Whamcloud - gitweb
e2155054e79a2baa4db8a1fb71ccd140f2f99824
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-9795 LU-9795 LU-9795 LU-9795
49         ALWAYS_EXCEPT+=" 17n     60a     133g    300f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64 fi
65
66 # skip nfs tests on kernels >= 4.12.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
68         # bug number:   LU-12661
69         ALWAYS_EXCEPT+=" 817"
70 fi
71 # skip cgroup tests on RHEL8.1 kernels until they are fixed
72 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
73       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
74         # bug number:   LU-13063
75         ALWAYS_EXCEPT+=" 411"
76 fi
77
78 #                                  5          12     8   12  (min)"
79 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
80
81 if [ "$mds1_FSTYPE" = "zfs" ]; then
82         # bug number for skipped test:
83         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
84         #                                               13    (min)"
85         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
86 fi
87
88 # Get the SLES distro version
89 #
90 # Returns a version string that should only be used in comparing
91 # strings returned by version_code()
92 sles_version_code()
93 {
94         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
95
96         # All SuSE Linux versions have one decimal. version_code expects two
97         local sles_version=$version.0
98         version_code $sles_version
99 }
100
101 # Check if we are running on Ubuntu or SLES so we can make decisions on
102 # what tests to run
103 if [ -r /etc/SuSE-release ]; then
104         sles_version=$(sles_version_code)
105         [ $sles_version -lt $(version_code 11.4.0) ] &&
106                 # bug number for skipped test: LU-4341
107                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
108         [ $sles_version -lt $(version_code 12.0.0) ] &&
109                 # bug number for skipped test: LU-3703
110                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
111 elif [ -r /etc/os-release ]; then
112         if grep -qi ubuntu /etc/os-release; then
113                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
114                                                 -e 's/^VERSION=//p' \
115                                                 /etc/os-release |
116                                                 awk '{ print $1 }'))
117
118                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
119                         # bug number for skipped test:
120                         #                LU-10334 LU-10366
121                         ALWAYS_EXCEPT+=" 103a     410"
122                 fi
123         fi
124 fi
125
126 build_test_filter
127 FAIL_ON_ERROR=false
128
129 cleanup() {
130         echo -n "cln.."
131         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
132         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
133 }
134 setup() {
135         echo -n "mnt.."
136         load_modules
137         setupall || exit 10
138         echo "done"
139 }
140
141 check_swap_layouts_support()
142 {
143         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
144                 skip "Does not support layout lock."
145 }
146
147 check_swap_layout_no_dom()
148 {
149         local FOLDER=$1
150         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
151         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
152 }
153
154 check_and_setup_lustre
155 DIR=${DIR:-$MOUNT}
156 assert_DIR
157
158 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
159
160 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
161 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
162 rm -rf $DIR/[Rdfs][0-9]*
163
164 # $RUNAS_ID may get set incorrectly somewhere else
165 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
166         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
167
168 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
169
170 if [ "${ONLY}" = "MOUNT" ] ; then
171         echo "Lustre is up, please go on"
172         exit
173 fi
174
175 echo "preparing for tests involving mounts"
176 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
177 touch $EXT2_DEV
178 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
179 echo # add a newline after mke2fs.
180
181 umask 077
182
183 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
184 lctl set_param debug=-1 2> /dev/null || true
185 test_0a() {
186         touch $DIR/$tfile
187         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
188         rm $DIR/$tfile
189         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
190 }
191 run_test 0a "touch; rm ====================="
192
193 test_0b() {
194         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
195         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
196 }
197 run_test 0b "chmod 0755 $DIR ============================="
198
199 test_0c() {
200         $LCTL get_param mdc.*.import | grep "state: FULL" ||
201                 error "import not FULL"
202         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
203                 error "bad target"
204 }
205 run_test 0c "check import proc"
206
207 test_0d() { # LU-3397
208         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
209                 skip "proc exports not supported before 2.10.57"
210
211         local mgs_exp="mgs.MGS.exports"
212         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
213         local exp_client_nid
214         local exp_client_version
215         local exp_val
216         local imp_val
217         local temp_imp=$DIR/$tfile.import
218         local temp_exp=$DIR/$tfile.export
219
220         # save mgc import file to $temp_imp
221         $LCTL get_param mgc.*.import | tee $temp_imp
222         # Check if client uuid is found in MGS export
223         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
224                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
225                         $client_uuid ] &&
226                         break;
227         done
228         # save mgs export file to $temp_exp
229         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
230
231         # Compare the value of field "connect_flags"
232         imp_val=$(grep "connect_flags" $temp_imp)
233         exp_val=$(grep "connect_flags" $temp_exp)
234         [ "$exp_val" == "$imp_val" ] ||
235                 error "export flags '$exp_val' != import flags '$imp_val'"
236
237         # Compare the value of client version
238         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
239         exp_val=$(version_code $exp_client_version)
240         imp_val=$CLIENT_VERSION
241         [ "$exp_val" == "$imp_val" ] ||
242                 error "export client version '$exp_val' != '$imp_val'"
243 }
244 run_test 0d "check export proc ============================="
245
246 test_1() {
247         test_mkdir $DIR/$tdir
248         test_mkdir $DIR/$tdir/d2
249         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
250         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
251         rmdir $DIR/$tdir/d2
252         rmdir $DIR/$tdir
253         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
254 }
255 run_test 1 "mkdir; remkdir; rmdir"
256
257 test_2() {
258         test_mkdir $DIR/$tdir
259         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
260         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
261         rm -r $DIR/$tdir
262         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
263 }
264 run_test 2 "mkdir; touch; rmdir; check file"
265
266 test_3() {
267         test_mkdir $DIR/$tdir
268         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
269         touch $DIR/$tdir/$tfile
270         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
271         rm -r $DIR/$tdir
272         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
273 }
274 run_test 3 "mkdir; touch; rmdir; check dir"
275
276 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
277 test_4() {
278         test_mkdir -i 1 $DIR/$tdir
279
280         touch $DIR/$tdir/$tfile ||
281                 error "Create file under remote directory failed"
282
283         rmdir $DIR/$tdir &&
284                 error "Expect error removing in-use dir $DIR/$tdir"
285
286         test -d $DIR/$tdir || error "Remote directory disappeared"
287
288         rm -rf $DIR/$tdir || error "remove remote dir error"
289 }
290 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
291
292 test_5() {
293         test_mkdir $DIR/$tdir
294         test_mkdir $DIR/$tdir/d2
295         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
296         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
297         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
298 }
299 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
300
301 test_6a() {
302         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
303         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
304         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
305                 error "$tfile does not have perm 0666 or UID $UID"
306         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
307         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
308                 error "$tfile should be 0666 and owned by UID $UID"
309 }
310 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
311
312 test_6c() {
313         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
314
315         touch $DIR/$tfile
316         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
317         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
318                 error "$tfile should be owned by UID $RUNAS_ID"
319         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
320         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
321                 error "$tfile should be owned by UID $RUNAS_ID"
322 }
323 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
324
325 test_6e() {
326         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
327
328         touch $DIR/$tfile
329         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
330         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
331                 error "$tfile should be owned by GID $UID"
332         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
333         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
334                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
335 }
336 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
337
338 test_6g() {
339         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
340
341         test_mkdir $DIR/$tdir
342         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
343         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
344         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
345         test_mkdir $DIR/$tdir/d/subdir
346         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
347                 error "$tdir/d/subdir should be GID $RUNAS_GID"
348         if [[ $MDSCOUNT -gt 1 ]]; then
349                 # check remote dir sgid inherite
350                 $LFS mkdir -i 0 $DIR/$tdir.local ||
351                         error "mkdir $tdir.local failed"
352                 chmod g+s $DIR/$tdir.local ||
353                         error "chmod $tdir.local failed"
354                 chgrp $RUNAS_GID $DIR/$tdir.local ||
355                         error "chgrp $tdir.local failed"
356                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
357                         error "mkdir $tdir.remote failed"
358                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
359                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
360                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
361                         error "$tdir.remote should be mode 02755"
362         fi
363 }
364 run_test 6g "verify new dir in sgid dir inherits group"
365
366 test_6h() { # bug 7331
367         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
368
369         touch $DIR/$tfile || error "touch failed"
370         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
371         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
372                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
373         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
374                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
375 }
376 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
377
378 test_7a() {
379         test_mkdir $DIR/$tdir
380         $MCREATE $DIR/$tdir/$tfile
381         chmod 0666 $DIR/$tdir/$tfile
382         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
383                 error "$tdir/$tfile should be mode 0666"
384 }
385 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
386
387 test_7b() {
388         if [ ! -d $DIR/$tdir ]; then
389                 test_mkdir $DIR/$tdir
390         fi
391         $MCREATE $DIR/$tdir/$tfile
392         echo -n foo > $DIR/$tdir/$tfile
393         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
394         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
395 }
396 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
397
398 test_8() {
399         test_mkdir $DIR/$tdir
400         touch $DIR/$tdir/$tfile
401         chmod 0666 $DIR/$tdir/$tfile
402         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
403                 error "$tfile mode not 0666"
404 }
405 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
406
407 test_9() {
408         test_mkdir $DIR/$tdir
409         test_mkdir $DIR/$tdir/d2
410         test_mkdir $DIR/$tdir/d2/d3
411         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
412 }
413 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
414
415 test_10() {
416         test_mkdir $DIR/$tdir
417         test_mkdir $DIR/$tdir/d2
418         touch $DIR/$tdir/d2/$tfile
419         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
420                 error "$tdir/d2/$tfile not a file"
421 }
422 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
423
424 test_11() {
425         test_mkdir $DIR/$tdir
426         test_mkdir $DIR/$tdir/d2
427         chmod 0666 $DIR/$tdir/d2
428         chmod 0705 $DIR/$tdir/d2
429         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
430                 error "$tdir/d2 mode not 0705"
431 }
432 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
433
434 test_12() {
435         test_mkdir $DIR/$tdir
436         touch $DIR/$tdir/$tfile
437         chmod 0666 $DIR/$tdir/$tfile
438         chmod 0654 $DIR/$tdir/$tfile
439         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
440                 error "$tdir/d2 mode not 0654"
441 }
442 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
443
444 test_13() {
445         test_mkdir $DIR/$tdir
446         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
447         >  $DIR/$tdir/$tfile
448         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
449                 error "$tdir/$tfile size not 0 after truncate"
450 }
451 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
452
453 test_14() {
454         test_mkdir $DIR/$tdir
455         touch $DIR/$tdir/$tfile
456         rm $DIR/$tdir/$tfile
457         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
458 }
459 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
460
461 test_15() {
462         test_mkdir $DIR/$tdir
463         touch $DIR/$tdir/$tfile
464         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
465         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
466                 error "$tdir/${tfile_2} not a file after rename"
467         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
468 }
469 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
470
471 test_16() {
472         test_mkdir $DIR/$tdir
473         touch $DIR/$tdir/$tfile
474         rm -rf $DIR/$tdir/$tfile
475         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
476 }
477 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
478
479 test_17a() {
480         test_mkdir $DIR/$tdir
481         touch $DIR/$tdir/$tfile
482         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
483         ls -l $DIR/$tdir
484         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
485                 error "$tdir/l-exist not a symlink"
486         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
487                 error "$tdir/l-exist not referencing a file"
488         rm -f $DIR/$tdir/l-exist
489         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
490 }
491 run_test 17a "symlinks: create, remove (real)"
492
493 test_17b() {
494         test_mkdir $DIR/$tdir
495         ln -s no-such-file $DIR/$tdir/l-dangle
496         ls -l $DIR/$tdir
497         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
498                 error "$tdir/l-dangle not referencing no-such-file"
499         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
500                 error "$tdir/l-dangle not referencing non-existent file"
501         rm -f $DIR/$tdir/l-dangle
502         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
503 }
504 run_test 17b "symlinks: create, remove (dangling)"
505
506 test_17c() { # bug 3440 - don't save failed open RPC for replay
507         test_mkdir $DIR/$tdir
508         ln -s foo $DIR/$tdir/$tfile
509         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
510 }
511 run_test 17c "symlinks: open dangling (should return error)"
512
513 test_17d() {
514         test_mkdir $DIR/$tdir
515         ln -s foo $DIR/$tdir/$tfile
516         touch $DIR/$tdir/$tfile || error "creating to new symlink"
517 }
518 run_test 17d "symlinks: create dangling"
519
520 test_17e() {
521         test_mkdir $DIR/$tdir
522         local foo=$DIR/$tdir/$tfile
523         ln -s $foo $foo || error "create symlink failed"
524         ls -l $foo || error "ls -l failed"
525         ls $foo && error "ls not failed" || true
526 }
527 run_test 17e "symlinks: create recursive symlink (should return error)"
528
529 test_17f() {
530         test_mkdir $DIR/$tdir
531         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
532         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
533         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
534         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
535         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
536         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
537         ls -l  $DIR/$tdir
538 }
539 run_test 17f "symlinks: long and very long symlink name"
540
541 # str_repeat(S, N) generate a string that is string S repeated N times
542 str_repeat() {
543         local s=$1
544         local n=$2
545         local ret=''
546         while [ $((n -= 1)) -ge 0 ]; do
547                 ret=$ret$s
548         done
549         echo $ret
550 }
551
552 # Long symlinks and LU-2241
553 test_17g() {
554         test_mkdir $DIR/$tdir
555         local TESTS="59 60 61 4094 4095"
556
557         # Fix for inode size boundary in 2.1.4
558         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
559                 TESTS="4094 4095"
560
561         # Patch not applied to 2.2 or 2.3 branches
562         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
563         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
564                 TESTS="4094 4095"
565
566         for i in $TESTS; do
567                 local SYMNAME=$(str_repeat 'x' $i)
568                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
569                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
570         done
571 }
572 run_test 17g "symlinks: really long symlink name and inode boundaries"
573
574 test_17h() { #bug 17378
575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
576         remote_mds_nodsh && skip "remote MDS with nodsh"
577
578         local mdt_idx
579
580         test_mkdir $DIR/$tdir
581         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
582         $LFS setstripe -c -1 $DIR/$tdir
583         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
584         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
585         touch $DIR/$tdir/$tfile || true
586 }
587 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
588
589 test_17i() { #bug 20018
590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
591         remote_mds_nodsh && skip "remote MDS with nodsh"
592
593         local foo=$DIR/$tdir/$tfile
594         local mdt_idx
595
596         test_mkdir -c1 $DIR/$tdir
597         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
598         ln -s $foo $foo || error "create symlink failed"
599 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
600         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
601         ls -l $foo && error "error not detected"
602         return 0
603 }
604 run_test 17i "don't panic on short symlink (should return error)"
605
606 test_17k() { #bug 22301
607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
608         [[ -z "$(which rsync 2>/dev/null)" ]] &&
609                 skip "no rsync command"
610         rsync --help | grep -q xattr ||
611                 skip_env "$(rsync --version | head -n1) does not support xattrs"
612         test_mkdir $DIR/$tdir
613         test_mkdir $DIR/$tdir.new
614         touch $DIR/$tdir/$tfile
615         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
616         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
617                 error "rsync failed with xattrs enabled"
618 }
619 run_test 17k "symlinks: rsync with xattrs enabled"
620
621 test_17l() { # LU-279
622         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
623                 skip "no getfattr command"
624
625         test_mkdir $DIR/$tdir
626         touch $DIR/$tdir/$tfile
627         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
628         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
629                 # -h to not follow symlinks. -m '' to list all the xattrs.
630                 # grep to remove first line: '# file: $path'.
631                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
632                 do
633                         lgetxattr_size_check $path $xattr ||
634                                 error "lgetxattr_size_check $path $xattr failed"
635                 done
636         done
637 }
638 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
639
640 # LU-1540
641 test_17m() {
642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
643         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
644         remote_mds_nodsh && skip "remote MDS with nodsh"
645         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
646         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
647                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
648
649         local short_sym="0123456789"
650         local wdir=$DIR/$tdir
651         local i
652
653         test_mkdir $wdir
654         long_sym=$short_sym
655         # create a long symlink file
656         for ((i = 0; i < 4; ++i)); do
657                 long_sym=${long_sym}${long_sym}
658         done
659
660         echo "create 512 short and long symlink files under $wdir"
661         for ((i = 0; i < 256; ++i)); do
662                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
663                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
664         done
665
666         echo "erase them"
667         rm -f $wdir/*
668         sync
669         wait_delete_completed
670
671         echo "recreate the 512 symlink files with a shorter string"
672         for ((i = 0; i < 512; ++i)); do
673                 # rewrite the symlink file with a shorter string
674                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
675                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
676         done
677
678         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
679         local devname=$(mdsdevname $mds_index)
680
681         echo "stop and checking mds${mds_index}:"
682         # e2fsck should not return error
683         stop mds${mds_index}
684         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
685         rc=$?
686
687         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
688                 error "start mds${mds_index} failed"
689         df $MOUNT > /dev/null 2>&1
690         [ $rc -eq 0 ] ||
691                 error "e2fsck detected error for short/long symlink: rc=$rc"
692         rm -f $wdir/*
693 }
694 run_test 17m "run e2fsck against MDT which contains short/long symlink"
695
696 check_fs_consistency_17n() {
697         local mdt_index
698         local rc=0
699
700         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
701         # so it only check MDT1/MDT2 instead of all of MDTs.
702         for mdt_index in 1 2; do
703                 local devname=$(mdsdevname $mdt_index)
704                 # e2fsck should not return error
705                 stop mds${mdt_index}
706                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
707                         rc=$((rc + $?))
708
709                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
710                         error "mount mds$mdt_index failed"
711                 df $MOUNT > /dev/null 2>&1
712         done
713         return $rc
714 }
715
716 test_17n() {
717         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
719         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
720         remote_mds_nodsh && skip "remote MDS with nodsh"
721         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
722         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
723                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
724
725         local i
726
727         test_mkdir $DIR/$tdir
728         for ((i=0; i<10; i++)); do
729                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
730                         error "create remote dir error $i"
731                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
732                         error "create files under remote dir failed $i"
733         done
734
735         check_fs_consistency_17n ||
736                 error "e2fsck report error after create files under remote dir"
737
738         for ((i = 0; i < 10; i++)); do
739                 rm -rf $DIR/$tdir/remote_dir_${i} ||
740                         error "destroy remote dir error $i"
741         done
742
743         check_fs_consistency_17n ||
744                 error "e2fsck report error after unlink files under remote dir"
745
746         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
747                 skip "lustre < 2.4.50 does not support migrate mv"
748
749         for ((i = 0; i < 10; i++)); do
750                 mkdir -p $DIR/$tdir/remote_dir_${i}
751                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
752                         error "create files under remote dir failed $i"
753                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
754                         error "migrate remote dir error $i"
755         done
756         check_fs_consistency_17n || error "e2fsck report error after migration"
757
758         for ((i = 0; i < 10; i++)); do
759                 rm -rf $DIR/$tdir/remote_dir_${i} ||
760                         error "destroy remote dir error $i"
761         done
762
763         check_fs_consistency_17n || error "e2fsck report error after unlink"
764 }
765 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
766
767 test_17o() {
768         remote_mds_nodsh && skip "remote MDS with nodsh"
769         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
770                 skip "Need MDS version at least 2.3.64"
771
772         local wdir=$DIR/${tdir}o
773         local mdt_index
774         local rc=0
775
776         test_mkdir $wdir
777         touch $wdir/$tfile
778         mdt_index=$($LFS getstripe -m $wdir/$tfile)
779         mdt_index=$((mdt_index + 1))
780
781         cancel_lru_locks mdc
782         #fail mds will wait the failover finish then set
783         #following fail_loc to avoid interfer the recovery process.
784         fail mds${mdt_index}
785
786         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
787         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
788         ls -l $wdir/$tfile && rc=1
789         do_facet mds${mdt_index} lctl set_param fail_loc=0
790         [[ $rc -eq 0 ]] || error "stat file should fail"
791 }
792 run_test 17o "stat file with incompat LMA feature"
793
794 test_18() {
795         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
796         ls $DIR || error "Failed to ls $DIR: $?"
797 }
798 run_test 18 "touch .../f ; ls ... =============================="
799
800 test_19a() {
801         touch $DIR/$tfile
802         ls -l $DIR
803         rm $DIR/$tfile
804         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
805 }
806 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
807
808 test_19b() {
809         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
810 }
811 run_test 19b "ls -l .../f19 (should return error) =============="
812
813 test_19c() {
814         [ $RUNAS_ID -eq $UID ] &&
815                 skip_env "RUNAS_ID = UID = $UID -- skipping"
816
817         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
818 }
819 run_test 19c "$RUNAS touch .../f19 (should return error) =="
820
821 test_19d() {
822         cat $DIR/f19 && error || true
823 }
824 run_test 19d "cat .../f19 (should return error) =============="
825
826 test_20() {
827         touch $DIR/$tfile
828         rm $DIR/$tfile
829         touch $DIR/$tfile
830         rm $DIR/$tfile
831         touch $DIR/$tfile
832         rm $DIR/$tfile
833         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
834 }
835 run_test 20 "touch .../f ; ls -l ..."
836
837 test_21() {
838         test_mkdir $DIR/$tdir
839         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
840         ln -s dangle $DIR/$tdir/link
841         echo foo >> $DIR/$tdir/link
842         cat $DIR/$tdir/dangle
843         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
844         $CHECKSTAT -f -t file $DIR/$tdir/link ||
845                 error "$tdir/link not linked to a file"
846 }
847 run_test 21 "write to dangling link"
848
849 test_22() {
850         local wdir=$DIR/$tdir
851         test_mkdir $wdir
852         chown $RUNAS_ID:$RUNAS_GID $wdir
853         (cd $wdir || error "cd $wdir failed";
854                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
855                 $RUNAS tar xf -)
856         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
857         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
858         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
859                 error "checkstat -u failed"
860 }
861 run_test 22 "unpack tar archive as non-root user"
862
863 # was test_23
864 test_23a() {
865         test_mkdir $DIR/$tdir
866         local file=$DIR/$tdir/$tfile
867
868         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
869         openfile -f O_CREAT:O_EXCL $file &&
870                 error "$file recreate succeeded" || true
871 }
872 run_test 23a "O_CREAT|O_EXCL in subdir"
873
874 test_23b() { # bug 18988
875         test_mkdir $DIR/$tdir
876         local file=$DIR/$tdir/$tfile
877
878         rm -f $file
879         echo foo > $file || error "write filed"
880         echo bar >> $file || error "append filed"
881         $CHECKSTAT -s 8 $file || error "wrong size"
882         rm $file
883 }
884 run_test 23b "O_APPEND check"
885
886 # LU-9409, size with O_APPEND and tiny writes
887 test_23c() {
888         local file=$DIR/$tfile
889
890         # single dd
891         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
892         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
893         rm -f $file
894
895         # racing tiny writes
896         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
897         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
898         wait
899         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
900         rm -f $file
901
902         #racing tiny & normal writes
903         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
905         wait
906         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
907         rm -f $file
908
909         #racing tiny & normal writes 2, ugly numbers
910         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
911         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
912         wait
913         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
914         rm -f $file
915 }
916 run_test 23c "O_APPEND size checks for tiny writes"
917
918 # LU-11069 file offset is correct after appending writes
919 test_23d() {
920         local file=$DIR/$tfile
921         local offset
922
923         echo CentaurHauls > $file
924         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
925         if ((offset != 26)); then
926                 error "wrong offset, expected 26, got '$offset'"
927         fi
928 }
929 run_test 23d "file offset is correct after appending writes"
930
931 # rename sanity
932 test_24a() {
933         echo '-- same directory rename'
934         test_mkdir $DIR/$tdir
935         touch $DIR/$tdir/$tfile.1
936         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
937         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
938 }
939 run_test 24a "rename file to non-existent target"
940
941 test_24b() {
942         test_mkdir $DIR/$tdir
943         touch $DIR/$tdir/$tfile.{1,2}
944         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
945         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
946         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
947 }
948 run_test 24b "rename file to existing target"
949
950 test_24c() {
951         test_mkdir $DIR/$tdir
952         test_mkdir $DIR/$tdir/d$testnum.1
953         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
954         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
955         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
956 }
957 run_test 24c "rename directory to non-existent target"
958
959 test_24d() {
960         test_mkdir -c1 $DIR/$tdir
961         test_mkdir -c1 $DIR/$tdir/d$testnum.1
962         test_mkdir -c1 $DIR/$tdir/d$testnum.2
963         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
964         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
965         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
966 }
967 run_test 24d "rename directory to existing target"
968
969 test_24e() {
970         echo '-- cross directory renames --'
971         test_mkdir $DIR/R5a
972         test_mkdir $DIR/R5b
973         touch $DIR/R5a/f
974         mv $DIR/R5a/f $DIR/R5b/g
975         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
976         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
977 }
978 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
979
980 test_24f() {
981         test_mkdir $DIR/R6a
982         test_mkdir $DIR/R6b
983         touch $DIR/R6a/f $DIR/R6b/g
984         mv $DIR/R6a/f $DIR/R6b/g
985         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
986         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
987 }
988 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
989
990 test_24g() {
991         test_mkdir $DIR/R7a
992         test_mkdir $DIR/R7b
993         test_mkdir $DIR/R7a/d
994         mv $DIR/R7a/d $DIR/R7b/e
995         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
996         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
997 }
998 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
999
1000 test_24h() {
1001         test_mkdir -c1 $DIR/R8a
1002         test_mkdir -c1 $DIR/R8b
1003         test_mkdir -c1 $DIR/R8a/d
1004         test_mkdir -c1 $DIR/R8b/e
1005         mrename $DIR/R8a/d $DIR/R8b/e
1006         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1007         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1008 }
1009 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1010
1011 test_24i() {
1012         echo "-- rename error cases"
1013         test_mkdir $DIR/R9
1014         test_mkdir $DIR/R9/a
1015         touch $DIR/R9/f
1016         mrename $DIR/R9/f $DIR/R9/a
1017         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1018         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1019         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1020 }
1021 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1022
1023 test_24j() {
1024         test_mkdir $DIR/R10
1025         mrename $DIR/R10/f $DIR/R10/g
1026         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1027         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1028         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1029 }
1030 run_test 24j "source does not exist ============================"
1031
1032 test_24k() {
1033         test_mkdir $DIR/R11a
1034         test_mkdir $DIR/R11a/d
1035         touch $DIR/R11a/f
1036         mv $DIR/R11a/f $DIR/R11a/d
1037         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1038         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1039 }
1040 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1041
1042 # bug 2429 - rename foo foo foo creates invalid file
1043 test_24l() {
1044         f="$DIR/f24l"
1045         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1046 }
1047 run_test 24l "Renaming a file to itself ========================"
1048
1049 test_24m() {
1050         f="$DIR/f24m"
1051         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1052         # on ext3 this does not remove either the source or target files
1053         # though the "expected" operation would be to remove the source
1054         $CHECKSTAT -t file ${f} || error "${f} missing"
1055         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1056 }
1057 run_test 24m "Renaming a file to a hard link to itself ========="
1058
1059 test_24n() {
1060     f="$DIR/f24n"
1061     # this stats the old file after it was renamed, so it should fail
1062     touch ${f}
1063     $CHECKSTAT ${f} || error "${f} missing"
1064     mv ${f} ${f}.rename
1065     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1066     $CHECKSTAT -a ${f} || error "${f} exists"
1067 }
1068 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1069
1070 test_24o() {
1071         test_mkdir $DIR/$tdir
1072         rename_many -s random -v -n 10 $DIR/$tdir
1073 }
1074 run_test 24o "rename of files during htree split"
1075
1076 test_24p() {
1077         test_mkdir $DIR/R12a
1078         test_mkdir $DIR/R12b
1079         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1080         mrename $DIR/R12a $DIR/R12b
1081         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1082         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1083         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1084         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1085 }
1086 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1087
1088 cleanup_multiop_pause() {
1089         trap 0
1090         kill -USR1 $MULTIPID
1091 }
1092
1093 test_24q() {
1094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1095
1096         test_mkdir $DIR/R13a
1097         test_mkdir $DIR/R13b
1098         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1099         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1100         MULTIPID=$!
1101
1102         trap cleanup_multiop_pause EXIT
1103         mrename $DIR/R13a $DIR/R13b
1104         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1105         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1106         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1107         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1108         cleanup_multiop_pause
1109         wait $MULTIPID || error "multiop close failed"
1110 }
1111 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1112
1113 test_24r() { #bug 3789
1114         test_mkdir $DIR/R14a
1115         test_mkdir $DIR/R14a/b
1116         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1117         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1118         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1119 }
1120 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1121
1122 test_24s() {
1123         test_mkdir $DIR/R15a
1124         test_mkdir $DIR/R15a/b
1125         test_mkdir $DIR/R15a/b/c
1126         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1127         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1128         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1129 }
1130 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1131 test_24t() {
1132         test_mkdir $DIR/R16a
1133         test_mkdir $DIR/R16a/b
1134         test_mkdir $DIR/R16a/b/c
1135         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1136         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1137         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1138 }
1139 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1140
1141 test_24u() { # bug12192
1142         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1143         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1144 }
1145 run_test 24u "create stripe file"
1146
1147 simple_cleanup_common() {
1148         local rc=0
1149         trap 0
1150         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1151
1152         local start=$SECONDS
1153         rm -rf $DIR/$tdir
1154         rc=$?
1155         wait_delete_completed
1156         echo "cleanup time $((SECONDS - start))"
1157         return $rc
1158 }
1159
1160 max_pages_per_rpc() {
1161         local mdtname="$(printf "MDT%04x" ${1:-0})"
1162         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1163 }
1164
1165 test_24v() {
1166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1167
1168         local nrfiles=${COUNT:-100000}
1169         local fname="$DIR/$tdir/$tfile"
1170
1171         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1172         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1173
1174         test_mkdir "$(dirname $fname)"
1175         # assume MDT0000 has the fewest inodes
1176         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1177         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1178         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1179
1180         trap simple_cleanup_common EXIT
1181
1182         createmany -m "$fname" $nrfiles
1183
1184         cancel_lru_locks mdc
1185         lctl set_param mdc.*.stats clear
1186
1187         # was previously test_24D: LU-6101
1188         # readdir() returns correct number of entries after cursor reload
1189         local num_ls=$(ls $DIR/$tdir | wc -l)
1190         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1191         local num_all=$(ls -a $DIR/$tdir | wc -l)
1192         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1193                 [ $num_all -ne $((nrfiles + 2)) ]; then
1194                         error "Expected $nrfiles files, got $num_ls " \
1195                                 "($num_uniq unique $num_all .&..)"
1196         fi
1197         # LU-5 large readdir
1198         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1199         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1200         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1201         # take into account of overhead in lu_dirpage header and end mark in
1202         # each page, plus one in rpc_num calculation.
1203         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1204         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1205         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1206         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1207         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1208         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1209         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1210         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1211                 error "large readdir doesn't take effect: " \
1212                       "$mds_readpage should be about $rpc_max"
1213
1214         simple_cleanup_common
1215 }
1216 run_test 24v "list large directory (test hash collision, b=17560)"
1217
1218 test_24w() { # bug21506
1219         SZ1=234852
1220         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1221         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1222         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1223         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1224         [[ "$SZ1" -eq "$SZ2" ]] ||
1225                 error "Error reading at the end of the file $tfile"
1226 }
1227 run_test 24w "Reading a file larger than 4Gb"
1228
1229 test_24x() {
1230         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1232         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1233                 skip "Need MDS version at least 2.7.56"
1234
1235         local MDTIDX=1
1236         local remote_dir=$DIR/$tdir/remote_dir
1237
1238         test_mkdir $DIR/$tdir
1239         $LFS mkdir -i $MDTIDX $remote_dir ||
1240                 error "create remote directory failed"
1241
1242         test_mkdir $DIR/$tdir/src_dir
1243         touch $DIR/$tdir/src_file
1244         test_mkdir $remote_dir/tgt_dir
1245         touch $remote_dir/tgt_file
1246
1247         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1248                 error "rename dir cross MDT failed!"
1249
1250         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1251                 error "rename file cross MDT failed!"
1252
1253         touch $DIR/$tdir/ln_file
1254         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1255                 error "ln file cross MDT failed"
1256
1257         rm -rf $DIR/$tdir || error "Can not delete directories"
1258 }
1259 run_test 24x "cross MDT rename/link"
1260
1261 test_24y() {
1262         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1264
1265         local remote_dir=$DIR/$tdir/remote_dir
1266         local mdtidx=1
1267
1268         test_mkdir $DIR/$tdir
1269         $LFS mkdir -i $mdtidx $remote_dir ||
1270                 error "create remote directory failed"
1271
1272         test_mkdir $remote_dir/src_dir
1273         touch $remote_dir/src_file
1274         test_mkdir $remote_dir/tgt_dir
1275         touch $remote_dir/tgt_file
1276
1277         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1278                 error "rename subdir in the same remote dir failed!"
1279
1280         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1281                 error "rename files in the same remote dir failed!"
1282
1283         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1284                 error "link files in the same remote dir failed!"
1285
1286         rm -rf $DIR/$tdir || error "Can not delete directories"
1287 }
1288 run_test 24y "rename/link on the same dir should succeed"
1289
1290 test_24z() {
1291         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1292         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1293                 skip "Need MDS version at least 2.12.51"
1294
1295         local index
1296
1297         for index in 0 1; do
1298                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1299                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1300         done
1301
1302         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1303
1304         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1305         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1306
1307         local mdts=$(comma_list $(mdts_nodes))
1308
1309         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1310         stack_trap "do_nodes $mdts $LCTL \
1311                 set_param mdt.*.enable_remote_rename=1" EXIT
1312
1313         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1314
1315         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1316         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1317 }
1318 run_test 24z "cross-MDT rename is done as cp"
1319
1320 test_24A() { # LU-3182
1321         local NFILES=5000
1322
1323         rm -rf $DIR/$tdir
1324         test_mkdir $DIR/$tdir
1325         trap simple_cleanup_common EXIT
1326         createmany -m $DIR/$tdir/$tfile $NFILES
1327         local t=$(ls $DIR/$tdir | wc -l)
1328         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1329         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1330         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1331            [ $v -ne $((NFILES + 2)) ] ; then
1332                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1333         fi
1334
1335         simple_cleanup_common || error "Can not delete directories"
1336 }
1337 run_test 24A "readdir() returns correct number of entries."
1338
1339 test_24B() { # LU-4805
1340         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1341
1342         local count
1343
1344         test_mkdir $DIR/$tdir
1345         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1346                 error "create striped dir failed"
1347
1348         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1349         [ $count -eq 2 ] || error "Expected 2, got $count"
1350
1351         touch $DIR/$tdir/striped_dir/a
1352
1353         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1354         [ $count -eq 3 ] || error "Expected 3, got $count"
1355
1356         touch $DIR/$tdir/striped_dir/.f
1357
1358         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1359         [ $count -eq 4 ] || error "Expected 4, got $count"
1360
1361         rm -rf $DIR/$tdir || error "Can not delete directories"
1362 }
1363 run_test 24B "readdir for striped dir return correct number of entries"
1364
1365 test_24C() {
1366         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1367
1368         mkdir $DIR/$tdir
1369         mkdir $DIR/$tdir/d0
1370         mkdir $DIR/$tdir/d1
1371
1372         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1373                 error "create striped dir failed"
1374
1375         cd $DIR/$tdir/d0/striped_dir
1376
1377         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1378         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1379         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1380
1381         [ "$d0_ino" = "$parent_ino" ] ||
1382                 error ".. wrong, expect $d0_ino, get $parent_ino"
1383
1384         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1385                 error "mv striped dir failed"
1386
1387         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1388
1389         [ "$d1_ino" = "$parent_ino" ] ||
1390                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1391 }
1392 run_test 24C "check .. in striped dir"
1393
1394 test_24E() {
1395         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1397
1398         mkdir -p $DIR/$tdir
1399         mkdir $DIR/$tdir/src_dir
1400         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1401                 error "create remote source failed"
1402
1403         touch $DIR/$tdir/src_dir/src_child/a
1404
1405         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1406                 error "create remote target dir failed"
1407
1408         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1409                 error "create remote target child failed"
1410
1411         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1412                 error "rename dir cross MDT failed!"
1413
1414         find $DIR/$tdir
1415
1416         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1417                 error "src_child still exists after rename"
1418
1419         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1420                 error "missing file(a) after rename"
1421
1422         rm -rf $DIR/$tdir || error "Can not delete directories"
1423 }
1424 run_test 24E "cross MDT rename/link"
1425
1426 test_24F () {
1427         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1428
1429         local repeats=1000
1430         [ "$SLOW" = "no" ] && repeats=100
1431
1432         mkdir -p $DIR/$tdir
1433
1434         echo "$repeats repeats"
1435         for ((i = 0; i < repeats; i++)); do
1436                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1437                 touch $DIR/$tdir/test/a || error "touch fails"
1438                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1439                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1440         done
1441
1442         true
1443 }
1444 run_test 24F "hash order vs readdir (LU-11330)"
1445
1446 test_25a() {
1447         echo '== symlink sanity ============================================='
1448
1449         test_mkdir $DIR/d25
1450         ln -s d25 $DIR/s25
1451         touch $DIR/s25/foo ||
1452                 error "File creation in symlinked directory failed"
1453 }
1454 run_test 25a "create file in symlinked directory ==============="
1455
1456 test_25b() {
1457         [ ! -d $DIR/d25 ] && test_25a
1458         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1459 }
1460 run_test 25b "lookup file in symlinked directory ==============="
1461
1462 test_26a() {
1463         test_mkdir $DIR/d26
1464         test_mkdir $DIR/d26/d26-2
1465         ln -s d26/d26-2 $DIR/s26
1466         touch $DIR/s26/foo || error "File creation failed"
1467 }
1468 run_test 26a "multiple component symlink ======================="
1469
1470 test_26b() {
1471         test_mkdir -p $DIR/$tdir/d26-2
1472         ln -s $tdir/d26-2/foo $DIR/s26-2
1473         touch $DIR/s26-2 || error "File creation failed"
1474 }
1475 run_test 26b "multiple component symlink at end of lookup ======"
1476
1477 test_26c() {
1478         test_mkdir $DIR/d26.2
1479         touch $DIR/d26.2/foo
1480         ln -s d26.2 $DIR/s26.2-1
1481         ln -s s26.2-1 $DIR/s26.2-2
1482         ln -s s26.2-2 $DIR/s26.2-3
1483         chmod 0666 $DIR/s26.2-3/foo
1484 }
1485 run_test 26c "chain of symlinks"
1486
1487 # recursive symlinks (bug 439)
1488 test_26d() {
1489         ln -s d26-3/foo $DIR/d26-3
1490 }
1491 run_test 26d "create multiple component recursive symlink"
1492
1493 test_26e() {
1494         [ ! -h $DIR/d26-3 ] && test_26d
1495         rm $DIR/d26-3
1496 }
1497 run_test 26e "unlink multiple component recursive symlink"
1498
1499 # recursive symlinks (bug 7022)
1500 test_26f() {
1501         test_mkdir $DIR/$tdir
1502         test_mkdir $DIR/$tdir/$tfile
1503         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1504         test_mkdir -p lndir/bar1
1505         test_mkdir $DIR/$tdir/$tfile/$tfile
1506         cd $tfile                || error "cd $tfile failed"
1507         ln -s .. dotdot          || error "ln dotdot failed"
1508         ln -s dotdot/lndir lndir || error "ln lndir failed"
1509         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1510         output=`ls $tfile/$tfile/lndir/bar1`
1511         [ "$output" = bar1 ] && error "unexpected output"
1512         rm -r $tfile             || error "rm $tfile failed"
1513         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1514 }
1515 run_test 26f "rm -r of a directory which has recursive symlink"
1516
1517 test_27a() {
1518         test_mkdir $DIR/$tdir
1519         $LFS getstripe $DIR/$tdir
1520         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1521         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1522         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1523 }
1524 run_test 27a "one stripe file"
1525
1526 test_27b() {
1527         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1528
1529         test_mkdir $DIR/$tdir
1530         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1531         $LFS getstripe -c $DIR/$tdir/$tfile
1532         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1533                 error "two-stripe file doesn't have two stripes"
1534
1535         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1536 }
1537 run_test 27b "create and write to two stripe file"
1538
1539 # 27c family tests specific striping, setstripe -o
1540 test_27ca() {
1541         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1542         test_mkdir -p $DIR/$tdir
1543         local osts="1"
1544
1545         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1546         $LFS getstripe -i $DIR/$tdir/$tfile
1547         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1548                 error "stripe not on specified OST"
1549
1550         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1551 }
1552 run_test 27ca "one stripe on specified OST"
1553
1554 test_27cb() {
1555         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1556         test_mkdir -p $DIR/$tdir
1557         local osts="1,0"
1558         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1559         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1560         echo "$getstripe"
1561
1562         # Strip getstripe output to a space separated list of OSTs
1563         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1564                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1565         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1566                 error "stripes not on specified OSTs"
1567
1568         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1569 }
1570 run_test 27cb "two stripes on specified OSTs"
1571
1572 test_27cc() {
1573         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1574         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1575                 skip "server does not support overstriping"
1576
1577         test_mkdir -p $DIR/$tdir
1578         local osts="0,0"
1579         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1580         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1581         echo "$getstripe"
1582
1583         # Strip getstripe output to a space separated list of OSTs
1584         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1585                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1586         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1587                 error "stripes not on specified OSTs"
1588
1589         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1590 }
1591 run_test 27cc "two stripes on the same OST"
1592
1593 test_27cd() {
1594         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1595         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1596                 skip "server does not support overstriping"
1597         test_mkdir -p $DIR/$tdir
1598         local osts="0,1,1,0"
1599         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1600         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1601         echo "$getstripe"
1602
1603         # Strip getstripe output to a space separated list of OSTs
1604         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1605                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1606         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1607                 error "stripes not on specified OSTs"
1608
1609         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1610 }
1611 run_test 27cd "four stripes on two OSTs"
1612
1613 test_27ce() {
1614         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1615                 skip_env "too many osts, skipping"
1616         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1617                 skip "server does not support overstriping"
1618         # We do one more stripe than we have OSTs
1619         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1620                 skip_env "ea_inode feature disabled"
1621
1622         test_mkdir -p $DIR/$tdir
1623         local osts=""
1624         for i in $(seq 0 $OSTCOUNT);
1625         do
1626                 osts=$osts"0"
1627                 if [ $i -ne $OSTCOUNT ]; then
1628                         osts=$osts","
1629                 fi
1630         done
1631         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1632         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1633         echo "$getstripe"
1634
1635         # Strip getstripe output to a space separated list of OSTs
1636         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1637                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1638         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1639                 error "stripes not on specified OSTs"
1640
1641         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1642 }
1643 run_test 27ce "more stripes than OSTs with -o"
1644
1645 test_27cf() {
1646         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1647         local pid=0
1648
1649         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1650         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1651         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1652         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1653                 error "failed to set $osp_proc=0"
1654
1655         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1656         pid=$!
1657         sleep 1
1658         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1659         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1660                 error "failed to set $osp_proc=1"
1661         wait $pid
1662         [[ $pid -ne 0 ]] ||
1663                 error "should return error due to $osp_proc=0"
1664 }
1665 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1666
1667 test_27d() {
1668         test_mkdir $DIR/$tdir
1669         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1670                 error "setstripe failed"
1671         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1672         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1673 }
1674 run_test 27d "create file with default settings"
1675
1676 test_27e() {
1677         # LU-5839 adds check for existed layout before setting it
1678         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1679                 skip "Need MDS version at least 2.7.56"
1680
1681         test_mkdir $DIR/$tdir
1682         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1683         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1684         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1685 }
1686 run_test 27e "setstripe existing file (should return error)"
1687
1688 test_27f() {
1689         test_mkdir $DIR/$tdir
1690         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1691                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1692         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1693                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1694         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1695         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1696 }
1697 run_test 27f "setstripe with bad stripe size (should return error)"
1698
1699 test_27g() {
1700         test_mkdir $DIR/$tdir
1701         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1702         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1703                 error "$DIR/$tdir/$tfile has object"
1704 }
1705 run_test 27g "$LFS getstripe with no objects"
1706
1707 test_27ga() {
1708         test_mkdir $DIR/$tdir
1709         touch $DIR/$tdir/$tfile || error "touch failed"
1710         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1711         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1712         local rc=$?
1713         (( rc == 2 )) || error "getstripe did not return ENOENT"
1714 }
1715 run_test 27ga "$LFS getstripe with missing file (should return error)"
1716
1717 test_27i() {
1718         test_mkdir $DIR/$tdir
1719         touch $DIR/$tdir/$tfile || error "touch failed"
1720         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1721                 error "missing objects"
1722 }
1723 run_test 27i "$LFS getstripe with some objects"
1724
1725 test_27j() {
1726         test_mkdir $DIR/$tdir
1727         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1728                 error "setstripe failed" || true
1729 }
1730 run_test 27j "setstripe with bad stripe offset (should return error)"
1731
1732 test_27k() { # bug 2844
1733         test_mkdir $DIR/$tdir
1734         local file=$DIR/$tdir/$tfile
1735         local ll_max_blksize=$((4 * 1024 * 1024))
1736         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1737         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1738         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1739         dd if=/dev/zero of=$file bs=4k count=1
1740         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1741         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1742 }
1743 run_test 27k "limit i_blksize for broken user apps"
1744
1745 test_27l() {
1746         mcreate $DIR/$tfile || error "creating file"
1747         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1748                 error "setstripe should have failed" || true
1749 }
1750 run_test 27l "check setstripe permissions (should return error)"
1751
1752 test_27m() {
1753         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1754
1755         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1756                 skip_env "multiple clients -- skipping"
1757
1758         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1759                    head -n1)
1760         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1761                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1762         fi
1763         trap simple_cleanup_common EXIT
1764         test_mkdir $DIR/$tdir
1765         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1766         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1767                 error "dd should fill OST0"
1768         i=2
1769         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1770                 i=$((i + 1))
1771                 [ $i -gt 256 ] && break
1772         done
1773         i=$((i + 1))
1774         touch $DIR/$tdir/$tfile.$i
1775         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1776             awk '{print $1}'| grep -w "0") ] &&
1777                 error "OST0 was full but new created file still use it"
1778         i=$((i + 1))
1779         touch $DIR/$tdir/$tfile.$i
1780         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1781             awk '{print $1}'| grep -w "0") ] &&
1782                 error "OST0 was full but new created file still use it"
1783         simple_cleanup_common
1784 }
1785 run_test 27m "create file while OST0 was full"
1786
1787 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1788 # if the OST isn't full anymore.
1789 reset_enospc() {
1790         local ostidx=${1:-""}
1791         local delay
1792         local ready
1793         local get_prealloc
1794
1795         local list=$(comma_list $(osts_nodes))
1796         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1797
1798         do_nodes $list lctl set_param fail_loc=0
1799         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1800         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1801                 awk '{print $1 * 2;exit;}')
1802         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1803                         grep -v \"^0$\""
1804         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1805 }
1806
1807 __exhaust_precreations() {
1808         local OSTIDX=$1
1809         local FAILLOC=$2
1810         local FAILIDX=${3:-$OSTIDX}
1811         local ofacet=ost$((OSTIDX + 1))
1812
1813         test_mkdir -p -c1 $DIR/$tdir
1814         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1815         local mfacet=mds$((mdtidx + 1))
1816         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1817
1818         local OST=$(ostname_from_index $OSTIDX)
1819
1820         # on the mdt's osc
1821         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1822         local last_id=$(do_facet $mfacet lctl get_param -n \
1823                         osp.$mdtosc_proc1.prealloc_last_id)
1824         local next_id=$(do_facet $mfacet lctl get_param -n \
1825                         osp.$mdtosc_proc1.prealloc_next_id)
1826
1827         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1828         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1829
1830         test_mkdir -p $DIR/$tdir/${OST}
1831         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1832 #define OBD_FAIL_OST_ENOSPC              0x215
1833         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1834         echo "Creating to objid $last_id on ost $OST..."
1835         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1836         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1837         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1838 }
1839
1840 exhaust_precreations() {
1841         __exhaust_precreations $1 $2 $3
1842         sleep_maxage
1843 }
1844
1845 exhaust_all_precreations() {
1846         local i
1847         for (( i=0; i < OSTCOUNT; i++ )) ; do
1848                 __exhaust_precreations $i $1 -1
1849         done
1850         sleep_maxage
1851 }
1852
1853 test_27n() {
1854         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1856         remote_mds_nodsh && skip "remote MDS with nodsh"
1857         remote_ost_nodsh && skip "remote OST with nodsh"
1858
1859         reset_enospc
1860         rm -f $DIR/$tdir/$tfile
1861         exhaust_precreations 0 0x80000215
1862         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1863         touch $DIR/$tdir/$tfile || error "touch failed"
1864         $LFS getstripe $DIR/$tdir/$tfile
1865         reset_enospc
1866 }
1867 run_test 27n "create file with some full OSTs"
1868
1869 test_27o() {
1870         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1872         remote_mds_nodsh && skip "remote MDS with nodsh"
1873         remote_ost_nodsh && skip "remote OST with nodsh"
1874
1875         reset_enospc
1876         rm -f $DIR/$tdir/$tfile
1877         exhaust_all_precreations 0x215
1878
1879         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1880
1881         reset_enospc
1882         rm -rf $DIR/$tdir/*
1883 }
1884 run_test 27o "create file with all full OSTs (should error)"
1885
1886 test_27p() {
1887         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1889         remote_mds_nodsh && skip "remote MDS with nodsh"
1890         remote_ost_nodsh && skip "remote OST with nodsh"
1891
1892         reset_enospc
1893         rm -f $DIR/$tdir/$tfile
1894         test_mkdir $DIR/$tdir
1895
1896         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1897         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1898         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1899
1900         exhaust_precreations 0 0x80000215
1901         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1902         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1903         $LFS getstripe $DIR/$tdir/$tfile
1904
1905         reset_enospc
1906 }
1907 run_test 27p "append to a truncated file with some full OSTs"
1908
1909 test_27q() {
1910         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1912         remote_mds_nodsh && skip "remote MDS with nodsh"
1913         remote_ost_nodsh && skip "remote OST with nodsh"
1914
1915         reset_enospc
1916         rm -f $DIR/$tdir/$tfile
1917
1918         test_mkdir $DIR/$tdir
1919         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1920         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1921                 error "truncate $DIR/$tdir/$tfile failed"
1922         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1923
1924         exhaust_all_precreations 0x215
1925
1926         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1927         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1928
1929         reset_enospc
1930 }
1931 run_test 27q "append to truncated file with all OSTs full (should error)"
1932
1933 test_27r() {
1934         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1936         remote_mds_nodsh && skip "remote MDS with nodsh"
1937         remote_ost_nodsh && skip "remote OST with nodsh"
1938
1939         reset_enospc
1940         rm -f $DIR/$tdir/$tfile
1941         exhaust_precreations 0 0x80000215
1942
1943         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1944
1945         reset_enospc
1946 }
1947 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1948
1949 test_27s() { # bug 10725
1950         test_mkdir $DIR/$tdir
1951         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1952         local stripe_count=0
1953         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1954         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1955                 error "stripe width >= 2^32 succeeded" || true
1956
1957 }
1958 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1959
1960 test_27t() { # bug 10864
1961         WDIR=$(pwd)
1962         WLFS=$(which lfs)
1963         cd $DIR
1964         touch $tfile
1965         $WLFS getstripe $tfile
1966         cd $WDIR
1967 }
1968 run_test 27t "check that utils parse path correctly"
1969
1970 test_27u() { # bug 4900
1971         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1972         remote_mds_nodsh && skip "remote MDS with nodsh"
1973
1974         local index
1975         local list=$(comma_list $(mdts_nodes))
1976
1977 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1978         do_nodes $list $LCTL set_param fail_loc=0x139
1979         test_mkdir -p $DIR/$tdir
1980         trap simple_cleanup_common EXIT
1981         createmany -o $DIR/$tdir/t- 1000
1982         do_nodes $list $LCTL set_param fail_loc=0
1983
1984         TLOG=$TMP/$tfile.getstripe
1985         $LFS getstripe $DIR/$tdir > $TLOG
1986         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1987         unlinkmany $DIR/$tdir/t- 1000
1988         trap 0
1989         [[ $OBJS -gt 0 ]] &&
1990                 error "$OBJS objects created on OST-0. See $TLOG" ||
1991                 rm -f $TLOG
1992 }
1993 run_test 27u "skip object creation on OSC w/o objects"
1994
1995 test_27v() { # bug 4900
1996         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1998         remote_mds_nodsh && skip "remote MDS with nodsh"
1999         remote_ost_nodsh && skip "remote OST with nodsh"
2000
2001         exhaust_all_precreations 0x215
2002         reset_enospc
2003
2004         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2005
2006         touch $DIR/$tdir/$tfile
2007         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2008         # all except ost1
2009         for (( i=1; i < OSTCOUNT; i++ )); do
2010                 do_facet ost$i lctl set_param fail_loc=0x705
2011         done
2012         local START=`date +%s`
2013         createmany -o $DIR/$tdir/$tfile 32
2014
2015         local FINISH=`date +%s`
2016         local TIMEOUT=`lctl get_param -n timeout`
2017         local PROCESS=$((FINISH - START))
2018         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2019                error "$FINISH - $START >= $TIMEOUT / 2"
2020         sleep $((TIMEOUT / 2 - PROCESS))
2021         reset_enospc
2022 }
2023 run_test 27v "skip object creation on slow OST"
2024
2025 test_27w() { # bug 10997
2026         test_mkdir $DIR/$tdir
2027         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2028         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2029                 error "stripe size $size != 65536" || true
2030         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2031                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2032 }
2033 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2034
2035 test_27wa() {
2036         [[ $OSTCOUNT -lt 2 ]] &&
2037                 skip_env "skipping multiple stripe count/offset test"
2038
2039         test_mkdir $DIR/$tdir
2040         for i in $(seq 1 $OSTCOUNT); do
2041                 offset=$((i - 1))
2042                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2043                         error "setstripe -c $i -i $offset failed"
2044                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2045                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2046                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2047                 [ $index -ne $offset ] &&
2048                         error "stripe offset $index != $offset" || true
2049         done
2050 }
2051 run_test 27wa "check $LFS setstripe -c -i options"
2052
2053 test_27x() {
2054         remote_ost_nodsh && skip "remote OST with nodsh"
2055         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2057
2058         OFFSET=$(($OSTCOUNT - 1))
2059         OSTIDX=0
2060         local OST=$(ostname_from_index $OSTIDX)
2061
2062         test_mkdir $DIR/$tdir
2063         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2064         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2065         sleep_maxage
2066         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2067         for i in $(seq 0 $OFFSET); do
2068                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2069                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2070                 error "OST0 was degraded but new created file still use it"
2071         done
2072         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2073 }
2074 run_test 27x "create files while OST0 is degraded"
2075
2076 test_27y() {
2077         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2078         remote_mds_nodsh && skip "remote MDS with nodsh"
2079         remote_ost_nodsh && skip "remote OST with nodsh"
2080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2081
2082         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2083         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2084                 osp.$mdtosc.prealloc_last_id)
2085         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2086                 osp.$mdtosc.prealloc_next_id)
2087         local fcount=$((last_id - next_id))
2088         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2089         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2090
2091         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2092                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2093         local OST_DEACTIVE_IDX=-1
2094         local OSC
2095         local OSTIDX
2096         local OST
2097
2098         for OSC in $MDS_OSCS; do
2099                 OST=$(osc_to_ost $OSC)
2100                 OSTIDX=$(index_from_ostuuid $OST)
2101                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2102                         OST_DEACTIVE_IDX=$OSTIDX
2103                 fi
2104                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2105                         echo $OSC "is Deactivated:"
2106                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2107                 fi
2108         done
2109
2110         OSTIDX=$(index_from_ostuuid $OST)
2111         test_mkdir $DIR/$tdir
2112         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2113
2114         for OSC in $MDS_OSCS; do
2115                 OST=$(osc_to_ost $OSC)
2116                 OSTIDX=$(index_from_ostuuid $OST)
2117                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2118                         echo $OST "is degraded:"
2119                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2120                                                 obdfilter.$OST.degraded=1
2121                 fi
2122         done
2123
2124         sleep_maxage
2125         createmany -o $DIR/$tdir/$tfile $fcount
2126
2127         for OSC in $MDS_OSCS; do
2128                 OST=$(osc_to_ost $OSC)
2129                 OSTIDX=$(index_from_ostuuid $OST)
2130                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2131                         echo $OST "is recovered from degraded:"
2132                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2133                                                 obdfilter.$OST.degraded=0
2134                 else
2135                         do_facet $SINGLEMDS lctl --device %$OSC activate
2136                 fi
2137         done
2138
2139         # all osp devices get activated, hence -1 stripe count restored
2140         local stripe_count=0
2141
2142         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2143         # devices get activated.
2144         sleep_maxage
2145         $LFS setstripe -c -1 $DIR/$tfile
2146         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2147         rm -f $DIR/$tfile
2148         [ $stripe_count -ne $OSTCOUNT ] &&
2149                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2150         return 0
2151 }
2152 run_test 27y "create files while OST0 is degraded and the rest inactive"
2153
2154 check_seq_oid()
2155 {
2156         log "check file $1"
2157
2158         lmm_count=$($LFS getstripe -c $1)
2159         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2160         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2161
2162         local old_ifs="$IFS"
2163         IFS=$'[:]'
2164         fid=($($LFS path2fid $1))
2165         IFS="$old_ifs"
2166
2167         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2168         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2169
2170         # compare lmm_seq and lu_fid->f_seq
2171         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2172         # compare lmm_object_id and lu_fid->oid
2173         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2174
2175         # check the trusted.fid attribute of the OST objects of the file
2176         local have_obdidx=false
2177         local stripe_nr=0
2178         $LFS getstripe $1 | while read obdidx oid hex seq; do
2179                 # skip lines up to and including "obdidx"
2180                 [ -z "$obdidx" ] && break
2181                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2182                 $have_obdidx || continue
2183
2184                 local ost=$((obdidx + 1))
2185                 local dev=$(ostdevname $ost)
2186                 local oid_hex
2187
2188                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2189
2190                 seq=$(echo $seq | sed -e "s/^0x//g")
2191                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2192                         oid_hex=$(echo $oid)
2193                 else
2194                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2195                 fi
2196                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2197
2198                 local ff=""
2199                 #
2200                 # Don't unmount/remount the OSTs if we don't need to do that.
2201                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2202                 # update too, until that use mount/ll_decode_filter_fid/mount.
2203                 # Re-enable when debugfs will understand new filter_fid.
2204                 #
2205                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2206                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2207                                 $dev 2>/dev/null" | grep "parent=")
2208                 fi
2209                 if [ -z "$ff" ]; then
2210                         stop ost$ost
2211                         mount_fstype ost$ost
2212                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2213                                 $(facet_mntpt ost$ost)/$obj_file)
2214                         unmount_fstype ost$ost
2215                         start ost$ost $dev $OST_MOUNT_OPTS
2216                         clients_up
2217                 fi
2218
2219                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2220
2221                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2222
2223                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2224                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2225                 #
2226                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2227                 #       stripe_size=1048576 component_id=1 component_start=0 \
2228                 #       component_end=33554432
2229                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2230                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2231                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2232                 local ff_pstripe
2233                 if grep -q 'stripe=' <<<$ff; then
2234                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2235                 else
2236                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2237                         # into f_ver in this case.  See comment on ff_parent.
2238                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2239                 fi
2240
2241                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2242                 [ $ff_pseq = $lmm_seq ] ||
2243                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2244                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2245                 [ $ff_poid = $lmm_oid ] ||
2246                         error "FF parent OID $ff_poid != $lmm_oid"
2247                 (($ff_pstripe == $stripe_nr)) ||
2248                         error "FF stripe $ff_pstripe != $stripe_nr"
2249
2250                 stripe_nr=$((stripe_nr + 1))
2251                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2252                         continue
2253                 if grep -q 'stripe_count=' <<<$ff; then
2254                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2255                                             -e 's/ .*//' <<<$ff)
2256                         [ $lmm_count = $ff_scnt ] ||
2257                                 error "FF stripe count $lmm_count != $ff_scnt"
2258                 fi
2259         done
2260 }
2261
2262 test_27z() {
2263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2264         remote_ost_nodsh && skip "remote OST with nodsh"
2265
2266         test_mkdir $DIR/$tdir
2267         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2268                 { error "setstripe -c -1 failed"; return 1; }
2269         # We need to send a write to every object to get parent FID info set.
2270         # This _should_ also work for setattr, but does not currently.
2271         # touch $DIR/$tdir/$tfile-1 ||
2272         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2273                 { error "dd $tfile-1 failed"; return 2; }
2274         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2275                 { error "setstripe -c -1 failed"; return 3; }
2276         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2277                 { error "dd $tfile-2 failed"; return 4; }
2278
2279         # make sure write RPCs have been sent to OSTs
2280         sync; sleep 5; sync
2281
2282         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2283         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2284 }
2285 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2286
2287 test_27A() { # b=19102
2288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2289
2290         save_layout_restore_at_exit $MOUNT
2291         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2292         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2293                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2294         local default_size=$($LFS getstripe -S $MOUNT)
2295         local default_offset=$($LFS getstripe -i $MOUNT)
2296         local dsize=$(do_facet $SINGLEMDS \
2297                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2298         [ $default_size -eq $dsize ] ||
2299                 error "stripe size $default_size != $dsize"
2300         [ $default_offset -eq -1 ] ||
2301                 error "stripe offset $default_offset != -1"
2302 }
2303 run_test 27A "check filesystem-wide default LOV EA values"
2304
2305 test_27B() { # LU-2523
2306         test_mkdir $DIR/$tdir
2307         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2308         touch $DIR/$tdir/f0
2309         # open f1 with O_LOV_DELAY_CREATE
2310         # rename f0 onto f1
2311         # call setstripe ioctl on open file descriptor for f1
2312         # close
2313         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2314                 $DIR/$tdir/f0
2315
2316         rm -f $DIR/$tdir/f1
2317         # open f1 with O_LOV_DELAY_CREATE
2318         # unlink f1
2319         # call setstripe ioctl on open file descriptor for f1
2320         # close
2321         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2322
2323         # Allow multiop to fail in imitation of NFS's busted semantics.
2324         true
2325 }
2326 run_test 27B "call setstripe on open unlinked file/rename victim"
2327
2328 # 27C family tests full striping and overstriping
2329 test_27Ca() { #LU-2871
2330         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2331
2332         declare -a ost_idx
2333         local index
2334         local found
2335         local i
2336         local j
2337
2338         test_mkdir $DIR/$tdir
2339         cd $DIR/$tdir
2340         for i in $(seq 0 $((OSTCOUNT - 1))); do
2341                 # set stripe across all OSTs starting from OST$i
2342                 $LFS setstripe -i $i -c -1 $tfile$i
2343                 # get striping information
2344                 ost_idx=($($LFS getstripe $tfile$i |
2345                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2346                 echo ${ost_idx[@]}
2347
2348                 # check the layout
2349                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2350                         error "${#ost_idx[@]} != $OSTCOUNT"
2351
2352                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2353                         found=0
2354                         for j in $(echo ${ost_idx[@]}); do
2355                                 if [ $index -eq $j ]; then
2356                                         found=1
2357                                         break
2358                                 fi
2359                         done
2360                         [ $found = 1 ] ||
2361                                 error "Can not find $index in ${ost_idx[@]}"
2362                 done
2363         done
2364 }
2365 run_test 27Ca "check full striping across all OSTs"
2366
2367 test_27Cb() {
2368         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2369                 skip "server does not support overstriping"
2370         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2371                 skip_env "too many osts, skipping"
2372
2373         test_mkdir -p $DIR/$tdir
2374         local setcount=$(($OSTCOUNT * 2))
2375         [ $setcount -ge 160 ] || large_xattr_enabled ||
2376                 skip_env "ea_inode feature disabled"
2377
2378         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2379                 error "setstripe failed"
2380
2381         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2382         [ $count -eq $setcount ] ||
2383                 error "stripe count $count, should be $setcount"
2384
2385         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2386                 error "overstriped should be set in pattern"
2387
2388         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2389                 error "dd failed"
2390 }
2391 run_test 27Cb "more stripes than OSTs with -C"
2392
2393 test_27Cc() {
2394         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2395                 skip "server does not support overstriping"
2396         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2397
2398         test_mkdir -p $DIR/$tdir
2399         local setcount=$(($OSTCOUNT - 1))
2400
2401         [ $setcount -ge 160 ] || large_xattr_enabled ||
2402                 skip_env "ea_inode feature disabled"
2403
2404         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2405                 error "setstripe failed"
2406
2407         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2408         [ $count -eq $setcount ] ||
2409                 error "stripe count $count, should be $setcount"
2410
2411         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2412                 error "overstriped should not be set in pattern"
2413
2414         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2415                 error "dd failed"
2416 }
2417 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2418
2419 test_27Cd() {
2420         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2421                 skip "server does not support overstriping"
2422         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2423         large_xattr_enabled || skip_env "ea_inode feature disabled"
2424
2425         test_mkdir -p $DIR/$tdir
2426         local setcount=$LOV_MAX_STRIPE_COUNT
2427
2428         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2429                 error "setstripe failed"
2430
2431         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2432         [ $count -eq $setcount ] ||
2433                 error "stripe count $count, should be $setcount"
2434
2435         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2436                 error "overstriped should be set in pattern"
2437
2438         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2439                 error "dd failed"
2440
2441         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2442 }
2443 run_test 27Cd "test maximum stripe count"
2444
2445 test_27Ce() {
2446         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2447                 skip "server does not support overstriping"
2448         test_mkdir -p $DIR/$tdir
2449
2450         pool_add $TESTNAME || error "Pool creation failed"
2451         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2452
2453         local setcount=8
2454
2455         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2456                 error "setstripe failed"
2457
2458         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2459         [ $count -eq $setcount ] ||
2460                 error "stripe count $count, should be $setcount"
2461
2462         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2463                 error "overstriped should be set in pattern"
2464
2465         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2466                 error "dd failed"
2467
2468         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2469 }
2470 run_test 27Ce "test pool with overstriping"
2471
2472 test_27Cf() {
2473         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2474                 skip "server does not support overstriping"
2475         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2476                 skip_env "too many osts, skipping"
2477
2478         test_mkdir -p $DIR/$tdir
2479
2480         local setcount=$(($OSTCOUNT * 2))
2481         [ $setcount -ge 160 ] || large_xattr_enabled ||
2482                 skip_env "ea_inode feature disabled"
2483
2484         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2485                 error "setstripe failed"
2486
2487         echo 1 > $DIR/$tdir/$tfile
2488
2489         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2490         [ $count -eq $setcount ] ||
2491                 error "stripe count $count, should be $setcount"
2492
2493         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2494                 error "overstriped should be set in pattern"
2495
2496         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2497                 error "dd failed"
2498
2499         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2500 }
2501 run_test 27Cf "test default inheritance with overstriping"
2502
2503 test_27D() {
2504         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2505         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2506         remote_mds_nodsh && skip "remote MDS with nodsh"
2507
2508         local POOL=${POOL:-testpool}
2509         local first_ost=0
2510         local last_ost=$(($OSTCOUNT - 1))
2511         local ost_step=1
2512         local ost_list=$(seq $first_ost $ost_step $last_ost)
2513         local ost_range="$first_ost $last_ost $ost_step"
2514
2515         test_mkdir $DIR/$tdir
2516         pool_add $POOL || error "pool_add failed"
2517         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2518
2519         local skip27D
2520         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2521                 skip27D+="-s 29"
2522         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2523                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2524                         skip27D+=" -s 30,31"
2525         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2526           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2527                 skip27D+=" -s 32,33"
2528         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2529                 skip27D+=" -s 34"
2530         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2531                 error "llapi_layout_test failed"
2532
2533         destroy_test_pools || error "destroy test pools failed"
2534 }
2535 run_test 27D "validate llapi_layout API"
2536
2537 # Verify that default_easize is increased from its initial value after
2538 # accessing a widely striped file.
2539 test_27E() {
2540         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2541         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2542                 skip "client does not have LU-3338 fix"
2543
2544         # 72 bytes is the minimum space required to store striping
2545         # information for a file striped across one OST:
2546         # (sizeof(struct lov_user_md_v3) +
2547         #  sizeof(struct lov_user_ost_data_v1))
2548         local min_easize=72
2549         $LCTL set_param -n llite.*.default_easize $min_easize ||
2550                 error "lctl set_param failed"
2551         local easize=$($LCTL get_param -n llite.*.default_easize)
2552
2553         [ $easize -eq $min_easize ] ||
2554                 error "failed to set default_easize"
2555
2556         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2557                 error "setstripe failed"
2558         # In order to ensure stat() call actually talks to MDS we need to
2559         # do something drastic to this file to shake off all lock, e.g.
2560         # rename it (kills lookup lock forcing cache cleaning)
2561         mv $DIR/$tfile $DIR/${tfile}-1
2562         ls -l $DIR/${tfile}-1
2563         rm $DIR/${tfile}-1
2564
2565         easize=$($LCTL get_param -n llite.*.default_easize)
2566
2567         [ $easize -gt $min_easize ] ||
2568                 error "default_easize not updated"
2569 }
2570 run_test 27E "check that default extended attribute size properly increases"
2571
2572 test_27F() { # LU-5346/LU-7975
2573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2574         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2575         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2576                 skip "Need MDS version at least 2.8.51"
2577         remote_ost_nodsh && skip "remote OST with nodsh"
2578
2579         test_mkdir $DIR/$tdir
2580         rm -f $DIR/$tdir/f0
2581         $LFS setstripe -c 2 $DIR/$tdir
2582
2583         # stop all OSTs to reproduce situation for LU-7975 ticket
2584         for num in $(seq $OSTCOUNT); do
2585                 stop ost$num
2586         done
2587
2588         # open/create f0 with O_LOV_DELAY_CREATE
2589         # truncate f0 to a non-0 size
2590         # close
2591         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2592
2593         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2594         # open/write it again to force delayed layout creation
2595         cat /etc/hosts > $DIR/$tdir/f0 &
2596         catpid=$!
2597
2598         # restart OSTs
2599         for num in $(seq $OSTCOUNT); do
2600                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2601                         error "ost$num failed to start"
2602         done
2603
2604         wait $catpid || error "cat failed"
2605
2606         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2607         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2608                 error "wrong stripecount"
2609
2610 }
2611 run_test 27F "Client resend delayed layout creation with non-zero size"
2612
2613 test_27G() { #LU-10629
2614         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2615                 skip "Need MDS version at least 2.11.51"
2616         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2617         remote_mds_nodsh && skip "remote MDS with nodsh"
2618         local POOL=${POOL:-testpool}
2619         local ostrange="0 0 1"
2620
2621         test_mkdir $DIR/$tdir
2622         touch $DIR/$tdir/$tfile.nopool
2623         pool_add $POOL || error "pool_add failed"
2624         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2625         $LFS setstripe -p $POOL $DIR/$tdir
2626
2627         local pool=$($LFS getstripe -p $DIR/$tdir)
2628
2629         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2630         touch $DIR/$tdir/$tfile.default
2631         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2632         $LFS find $DIR/$tdir -type f --pool $POOL
2633         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2634         [[ "$found" == "2" ]] ||
2635                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2636
2637         $LFS setstripe -d $DIR/$tdir
2638
2639         pool=$($LFS getstripe -p -d $DIR/$tdir)
2640
2641         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2642 }
2643 run_test 27G "Clear OST pool from stripe"
2644
2645 test_27H() {
2646         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2647                 skip "Need MDS version newer than 2.11.54"
2648         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2649         test_mkdir $DIR/$tdir
2650         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2651         touch $DIR/$tdir/$tfile
2652         $LFS getstripe -c $DIR/$tdir/$tfile
2653         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2654                 error "two-stripe file doesn't have two stripes"
2655
2656         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2657         $LFS getstripe -y $DIR/$tdir/$tfile
2658         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2659              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2660                 error "expected l_ost_idx: [02]$ not matched"
2661
2662         # make sure ost list has been cleared
2663         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2664         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2665                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2666         touch $DIR/$tdir/f3
2667         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2668 }
2669 run_test 27H "Set specific OSTs stripe"
2670
2671 test_27I() {
2672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2673         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2674         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2675                 skip "Need MDS version newer than 2.12.52"
2676         local pool=$TESTNAME
2677         local ostrange="1 1 1"
2678
2679         save_layout_restore_at_exit $MOUNT
2680         $LFS setstripe -c 2 -i 0 $MOUNT
2681         pool_add $pool || error "pool_add failed"
2682         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2683         test_mkdir $DIR/$tdir
2684         $LFS setstripe -p $pool $DIR/$tdir
2685         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2686         $LFS getstripe $DIR/$tdir/$tfile
2687 }
2688 run_test 27I "check that root dir striping does not break parent dir one"
2689
2690 test_27J() {
2691         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2692                 skip "Need MDS version newer than 2.12.51"
2693
2694         test_mkdir $DIR/$tdir
2695         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2696         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2697
2698         # create foreign file (raw way)
2699         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2700                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2701
2702         # verify foreign file (raw way)
2703         parse_foreign_file -f $DIR/$tdir/$tfile |
2704                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2705                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2706         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2707                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2708         parse_foreign_file -f $DIR/$tdir/$tfile |
2709                 grep "lov_foreign_size: 73" ||
2710                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2711         parse_foreign_file -f $DIR/$tdir/$tfile |
2712                 grep "lov_foreign_type: 1" ||
2713                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2714         parse_foreign_file -f $DIR/$tdir/$tfile |
2715                 grep "lov_foreign_flags: 0x0000DA08" ||
2716                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2717         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2718                 grep "lov_foreign_value: 0x" |
2719                 sed -e 's/lov_foreign_value: 0x//')
2720         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2721         [[ $lov = ${lov2// /} ]] ||
2722                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2723
2724         # create foreign file (lfs + API)
2725         $LFS setstripe --foreign=daos --flags 0xda08 \
2726                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2727                 error "$DIR/$tdir/${tfile}2: create failed"
2728
2729         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2730                 grep "lfm_magic:.*0x0BD70BD0" ||
2731                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2732         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2733         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2734                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2735         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2736                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2737         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2738                 grep "lfm_flags:.*0x0000DA08" ||
2739                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2740         $LFS getstripe $DIR/$tdir/${tfile}2 |
2741                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2742                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2743
2744         # modify striping should fail
2745         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2746                 error "$DIR/$tdir/$tfile: setstripe should fail"
2747         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2748                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2749
2750         # R/W should fail
2751         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2752         cat $DIR/$tdir/${tfile}2 &&
2753                 error "$DIR/$tdir/${tfile}2: read should fail"
2754         cat /etc/passwd > $DIR/$tdir/$tfile &&
2755                 error "$DIR/$tdir/$tfile: write should fail"
2756         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2757                 error "$DIR/$tdir/${tfile}2: write should fail"
2758
2759         # chmod should work
2760         chmod 222 $DIR/$tdir/$tfile ||
2761                 error "$DIR/$tdir/$tfile: chmod failed"
2762         chmod 222 $DIR/$tdir/${tfile}2 ||
2763                 error "$DIR/$tdir/${tfile}2: chmod failed"
2764
2765         # chown should work
2766         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2767                 error "$DIR/$tdir/$tfile: chown failed"
2768         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2769                 error "$DIR/$tdir/${tfile}2: chown failed"
2770
2771         # rename should work
2772         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2773                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2774         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2775                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2776
2777         #remove foreign file
2778         rm $DIR/$tdir/${tfile}.new ||
2779                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2780         rm $DIR/$tdir/${tfile}2.new ||
2781                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2782 }
2783 run_test 27J "basic ops on file with foreign LOV"
2784
2785 test_27K() {
2786         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2787                 skip "Need MDS version newer than 2.12.49"
2788
2789         test_mkdir $DIR/$tdir
2790         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2791         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2792
2793         # create foreign dir (raw way)
2794         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2795                 error "create_foreign_dir FAILED"
2796
2797         # verify foreign dir (raw way)
2798         parse_foreign_dir -d $DIR/$tdir/$tdir |
2799                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2800                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2801         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2802                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2803         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2804                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2805         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2806                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2807         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2808                 grep "lmv_foreign_value: 0x" |
2809                 sed 's/lmv_foreign_value: 0x//')
2810         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2811                 sed 's/ //g')
2812         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2813
2814         # create foreign dir (lfs + API)
2815         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2816                 $DIR/$tdir/${tdir}2 ||
2817                 error "$DIR/$tdir/${tdir}2: create failed"
2818
2819         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2820                 grep "lfm_magic:.*0x0CD50CD0" ||
2821                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2822         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2823         # - sizeof(lfm_type) - sizeof(lfm_flags)
2824         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2825                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2826         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2827                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2828         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2829                 grep "lfm_flags:.*0x0000DA05" ||
2830                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2831         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2832                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2833                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2834
2835         # file create in dir should fail
2836         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2837         touch $DIR/$tdir/${tdir}2/$tfile &&
2838                 "$DIR/${tdir}2: file create should fail"
2839
2840         # chmod should work
2841         chmod 777 $DIR/$tdir/$tdir ||
2842                 error "$DIR/$tdir: chmod failed"
2843         chmod 777 $DIR/$tdir/${tdir}2 ||
2844                 error "$DIR/${tdir}2: chmod failed"
2845
2846         # chown should work
2847         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2848                 error "$DIR/$tdir: chown failed"
2849         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2850                 error "$DIR/${tdir}2: chown failed"
2851
2852         # rename should work
2853         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2854                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2855         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2856                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2857
2858         #remove foreign dir
2859         rmdir $DIR/$tdir/${tdir}.new ||
2860                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2861         rmdir $DIR/$tdir/${tdir}2.new ||
2862                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2863 }
2864 run_test 27K "basic ops on dir with foreign LMV"
2865
2866 test_27L() {
2867         remote_mds_nodsh && skip "remote MDS with nodsh"
2868
2869         local POOL=${POOL:-$TESTNAME}
2870
2871         pool_add $POOL || error "pool_add failed"
2872
2873         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2874                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2875                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2876 }
2877 run_test 27L "lfs pool_list gives correct pool name"
2878
2879 test_27M() {
2880         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2881                 skip "Need MDS version >= than 2.12.57"
2882         remote_mds_nodsh && skip "remote MDS with nodsh"
2883         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2884
2885         test_mkdir $DIR/$tdir
2886
2887         # Set default striping on directory
2888         $LFS setstripe -C 4 $DIR/$tdir
2889
2890         echo 1 > $DIR/$tdir/${tfile}.1
2891         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2892         local setcount=4
2893         [ $count -eq $setcount ] ||
2894                 error "(1) stripe count $count, should be $setcount"
2895
2896         # Capture existing append_stripe_count setting for restore
2897         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2898         local mdts=$(comma_list $(mdts_nodes))
2899         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2900
2901         local appendcount=$orig_count
2902         echo 1 >> $DIR/$tdir/${tfile}.2_append
2903         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2904         [ $count -eq $appendcount ] ||
2905                 error "(2)stripe count $count, should be $appendcount for append"
2906
2907         # Disable O_APPEND striping, verify it works
2908         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2909
2910         # Should now get the default striping, which is 4
2911         setcount=4
2912         echo 1 >> $DIR/$tdir/${tfile}.3_append
2913         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2914         [ $count -eq $setcount ] ||
2915                 error "(3) stripe count $count, should be $setcount"
2916
2917         # Try changing the stripe count for append files
2918         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2919
2920         # Append striping is now 2 (directory default is still 4)
2921         appendcount=2
2922         echo 1 >> $DIR/$tdir/${tfile}.4_append
2923         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2924         [ $count -eq $appendcount ] ||
2925                 error "(4) stripe count $count, should be $appendcount for append"
2926
2927         # Test append stripe count of -1
2928         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2929         appendcount=$OSTCOUNT
2930         echo 1 >> $DIR/$tdir/${tfile}.5
2931         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2932         [ $count -eq $appendcount ] ||
2933                 error "(5) stripe count $count, should be $appendcount for append"
2934
2935         # Set append striping back to default of 1
2936         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2937
2938         # Try a new default striping, PFL + DOM
2939         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2940
2941         # Create normal DOM file, DOM returns stripe count == 0
2942         setcount=0
2943         touch $DIR/$tdir/${tfile}.6
2944         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2945         [ $count -eq $setcount ] ||
2946                 error "(6) stripe count $count, should be $setcount"
2947
2948         # Show
2949         appendcount=1
2950         echo 1 >> $DIR/$tdir/${tfile}.7_append
2951         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2952         [ $count -eq $appendcount ] ||
2953                 error "(7) stripe count $count, should be $appendcount for append"
2954
2955         # Clean up DOM layout
2956         $LFS setstripe -d $DIR/$tdir
2957
2958         # Now test that append striping works when layout is from root
2959         $LFS setstripe -c 2 $MOUNT
2960         # Make a special directory for this
2961         mkdir $DIR/${tdir}/${tdir}.2
2962         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2963
2964         # Verify for normal file
2965         setcount=2
2966         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2967         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2968         [ $count -eq $setcount ] ||
2969                 error "(8) stripe count $count, should be $setcount"
2970
2971         appendcount=1
2972         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2973         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2974         [ $count -eq $appendcount ] ||
2975                 error "(9) stripe count $count, should be $appendcount for append"
2976
2977         # Now test O_APPEND striping with pools
2978         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2979         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2980
2981         # Create the pool
2982         pool_add $TESTNAME || error "pool creation failed"
2983         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2984
2985         echo 1 >> $DIR/$tdir/${tfile}.10_append
2986
2987         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2988         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2989
2990         # Check that count is still correct
2991         appendcount=1
2992         echo 1 >> $DIR/$tdir/${tfile}.11_append
2993         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2994         [ $count -eq $appendcount ] ||
2995                 error "(11) stripe count $count, should be $appendcount for append"
2996
2997         # Disable O_APPEND stripe count, verify pool works separately
2998         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2999
3000         echo 1 >> $DIR/$tdir/${tfile}.12_append
3001
3002         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3003         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3004
3005         # Remove pool setting, verify it's not applied
3006         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3007
3008         echo 1 >> $DIR/$tdir/${tfile}.13_append
3009
3010         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3011         [ "$pool" = "" ] || error "(13) pool found: $pool"
3012 }
3013 run_test 27M "test O_APPEND striping"
3014
3015 test_27N() {
3016         combined_mgs_mds && skip "needs separate MGS/MDT"
3017
3018         pool_add $TESTNAME || error "pool_add failed"
3019         do_facet mgs "$LCTL pool_list $FSNAME" |
3020                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3021                 error "lctl pool_list on MGS failed"
3022 }
3023 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3024
3025 # createtest also checks that device nodes are created and
3026 # then visible correctly (#2091)
3027 test_28() { # bug 2091
3028         test_mkdir $DIR/d28
3029         $CREATETEST $DIR/d28/ct || error "createtest failed"
3030 }
3031 run_test 28 "create/mknod/mkdir with bad file types ============"
3032
3033 test_29() {
3034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3035
3036         sync; sleep 1; sync # flush out any dirty pages from previous tests
3037         cancel_lru_locks
3038         test_mkdir $DIR/d29
3039         touch $DIR/d29/foo
3040         log 'first d29'
3041         ls -l $DIR/d29
3042
3043         declare -i LOCKCOUNTORIG=0
3044         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3045                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3046         done
3047         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3048
3049         declare -i LOCKUNUSEDCOUNTORIG=0
3050         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3051                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3052         done
3053
3054         log 'second d29'
3055         ls -l $DIR/d29
3056         log 'done'
3057
3058         declare -i LOCKCOUNTCURRENT=0
3059         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3060                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3061         done
3062
3063         declare -i LOCKUNUSEDCOUNTCURRENT=0
3064         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3065                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3066         done
3067
3068         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3069                 $LCTL set_param -n ldlm.dump_namespaces ""
3070                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3071                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3072                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3073                 return 2
3074         fi
3075         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3076                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3077                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3078                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3079                 return 3
3080         fi
3081 }
3082 run_test 29 "IT_GETATTR regression  ============================"
3083
3084 test_30a() { # was test_30
3085         cp $(which ls) $DIR || cp /bin/ls $DIR
3086         $DIR/ls / || error "Can't execute binary from lustre"
3087         rm $DIR/ls
3088 }
3089 run_test 30a "execute binary from Lustre (execve) =============="
3090
3091 test_30b() {
3092         cp `which ls` $DIR || cp /bin/ls $DIR
3093         chmod go+rx $DIR/ls
3094         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3095         rm $DIR/ls
3096 }
3097 run_test 30b "execute binary from Lustre as non-root ==========="
3098
3099 test_30c() { # b=22376
3100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3101
3102         cp $(which ls) $DIR || cp /bin/ls $DIR
3103         chmod a-rw $DIR/ls
3104         cancel_lru_locks mdc
3105         cancel_lru_locks osc
3106         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3107         rm -f $DIR/ls
3108 }
3109 run_test 30c "execute binary from Lustre without read perms ===="
3110
3111 test_30d() {
3112         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3113
3114         for i in {1..10}; do
3115                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3116                 local PID=$!
3117                 sleep 1
3118                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3119                 wait $PID || error "executing dd from Lustre failed"
3120                 rm -f $DIR/$tfile
3121         done
3122
3123         rm -f $DIR/dd
3124 }
3125 run_test 30d "execute binary from Lustre while clear locks"
3126
3127 test_31a() {
3128         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3129         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3130 }
3131 run_test 31a "open-unlink file =================================="
3132
3133 test_31b() {
3134         touch $DIR/f31 || error "touch $DIR/f31 failed"
3135         ln $DIR/f31 $DIR/f31b || error "ln failed"
3136         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3137         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3138 }
3139 run_test 31b "unlink file with multiple links while open ======="
3140
3141 test_31c() {
3142         touch $DIR/f31 || error "touch $DIR/f31 failed"
3143         ln $DIR/f31 $DIR/f31c || error "ln failed"
3144         multiop_bg_pause $DIR/f31 O_uc ||
3145                 error "multiop_bg_pause for $DIR/f31 failed"
3146         MULTIPID=$!
3147         $MULTIOP $DIR/f31c Ouc
3148         kill -USR1 $MULTIPID
3149         wait $MULTIPID
3150 }
3151 run_test 31c "open-unlink file with multiple links ============="
3152
3153 test_31d() {
3154         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3155         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3156 }
3157 run_test 31d "remove of open directory ========================="
3158
3159 test_31e() { # bug 2904
3160         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3161 }
3162 run_test 31e "remove of open non-empty directory ==============="
3163
3164 test_31f() { # bug 4554
3165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3166
3167         set -vx
3168         test_mkdir $DIR/d31f
3169         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3170         cp /etc/hosts $DIR/d31f
3171         ls -l $DIR/d31f
3172         $LFS getstripe $DIR/d31f/hosts
3173         multiop_bg_pause $DIR/d31f D_c || return 1
3174         MULTIPID=$!
3175
3176         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3177         test_mkdir $DIR/d31f
3178         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3179         cp /etc/hosts $DIR/d31f
3180         ls -l $DIR/d31f
3181         $LFS getstripe $DIR/d31f/hosts
3182         multiop_bg_pause $DIR/d31f D_c || return 1
3183         MULTIPID2=$!
3184
3185         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3186         wait $MULTIPID || error "first opendir $MULTIPID failed"
3187
3188         sleep 6
3189
3190         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3191         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3192         set +vx
3193 }
3194 run_test 31f "remove of open directory with open-unlink file ==="
3195
3196 test_31g() {
3197         echo "-- cross directory link --"
3198         test_mkdir -c1 $DIR/${tdir}ga
3199         test_mkdir -c1 $DIR/${tdir}gb
3200         touch $DIR/${tdir}ga/f
3201         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3202         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3203         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3204         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3205         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3206 }
3207 run_test 31g "cross directory link==============="
3208
3209 test_31h() {
3210         echo "-- cross directory link --"
3211         test_mkdir -c1 $DIR/${tdir}
3212         test_mkdir -c1 $DIR/${tdir}/dir
3213         touch $DIR/${tdir}/f
3214         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3215         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3216         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3217         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3218         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3219 }
3220 run_test 31h "cross directory link under child==============="
3221
3222 test_31i() {
3223         echo "-- cross directory link --"
3224         test_mkdir -c1 $DIR/$tdir
3225         test_mkdir -c1 $DIR/$tdir/dir
3226         touch $DIR/$tdir/dir/f
3227         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3228         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3229         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3230         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3231         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3232 }
3233 run_test 31i "cross directory link under parent==============="
3234
3235 test_31j() {
3236         test_mkdir -c1 -p $DIR/$tdir
3237         test_mkdir -c1 -p $DIR/$tdir/dir1
3238         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3239         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3240         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3241         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3242         return 0
3243 }
3244 run_test 31j "link for directory==============="
3245
3246 test_31k() {
3247         test_mkdir -c1 -p $DIR/$tdir
3248         touch $DIR/$tdir/s
3249         touch $DIR/$tdir/exist
3250         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3251         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3252         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3253         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3254         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3255         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3256         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3257         return 0
3258 }
3259 run_test 31k "link to file: the same, non-existing, dir==============="
3260
3261 test_31m() {
3262         mkdir $DIR/d31m
3263         touch $DIR/d31m/s
3264         mkdir $DIR/d31m2
3265         touch $DIR/d31m2/exist
3266         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3267         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3268         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3269         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3270         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3271         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3272         return 0
3273 }
3274 run_test 31m "link to file: the same, non-existing, dir==============="
3275
3276 test_31n() {
3277         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3278         nlink=$(stat --format=%h $DIR/$tfile)
3279         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3280         local fd=$(free_fd)
3281         local cmd="exec $fd<$DIR/$tfile"
3282         eval $cmd
3283         cmd="exec $fd<&-"
3284         trap "eval $cmd" EXIT
3285         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3286         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3287         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3288         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3289         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3290         eval $cmd
3291 }
3292 run_test 31n "check link count of unlinked file"
3293
3294 link_one() {
3295         local tempfile=$(mktemp $1_XXXXXX)
3296         mlink $tempfile $1 2> /dev/null &&
3297                 echo "$BASHPID: link $tempfile to $1 succeeded"
3298         munlink $tempfile
3299 }
3300
3301 test_31o() { # LU-2901
3302         test_mkdir $DIR/$tdir
3303         for LOOP in $(seq 100); do
3304                 rm -f $DIR/$tdir/$tfile*
3305                 for THREAD in $(seq 8); do
3306                         link_one $DIR/$tdir/$tfile.$LOOP &
3307                 done
3308                 wait
3309                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3310                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3311                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3312                         break || true
3313         done
3314 }
3315 run_test 31o "duplicate hard links with same filename"
3316
3317 test_31p() {
3318         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3319
3320         test_mkdir $DIR/$tdir
3321         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3322         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3323
3324         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3325                 error "open unlink test1 failed"
3326         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3327                 error "open unlink test2 failed"
3328
3329         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3330                 error "test1 still exists"
3331         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3332                 error "test2 still exists"
3333 }
3334 run_test 31p "remove of open striped directory"
3335
3336 cleanup_test32_mount() {
3337         local rc=0
3338         trap 0
3339         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3340         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3341         losetup -d $loopdev || true
3342         rm -rf $DIR/$tdir
3343         return $rc
3344 }
3345
3346 test_32a() {
3347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3348
3349         echo "== more mountpoints and symlinks ================="
3350         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3351         trap cleanup_test32_mount EXIT
3352         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3353         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3354                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3355         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3356                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3357         cleanup_test32_mount
3358 }
3359 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3360
3361 test_32b() {
3362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3363
3364         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3365         trap cleanup_test32_mount EXIT
3366         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3367         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3368                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3369         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3370                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3371         cleanup_test32_mount
3372 }
3373 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3374
3375 test_32c() {
3376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3377
3378         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3379         trap cleanup_test32_mount EXIT
3380         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3381         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3382                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3383         test_mkdir -p $DIR/$tdir/d2/test_dir
3384         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3385                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3386         cleanup_test32_mount
3387 }
3388 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3389
3390 test_32d() {
3391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3392
3393         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3394         trap cleanup_test32_mount EXIT
3395         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3396         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3397                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3398         test_mkdir -p $DIR/$tdir/d2/test_dir
3399         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3400                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3401         cleanup_test32_mount
3402 }
3403 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3404
3405 test_32e() {
3406         rm -fr $DIR/$tdir
3407         test_mkdir -p $DIR/$tdir/tmp
3408         local tmp_dir=$DIR/$tdir/tmp
3409         ln -s $DIR/$tdir $tmp_dir/symlink11
3410         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3411         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3412         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3413 }
3414 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3415
3416 test_32f() {
3417         rm -fr $DIR/$tdir
3418         test_mkdir -p $DIR/$tdir/tmp
3419         local tmp_dir=$DIR/$tdir/tmp
3420         ln -s $DIR/$tdir $tmp_dir/symlink11
3421         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3422         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3423         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3424 }
3425 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3426
3427 test_32g() {
3428         local tmp_dir=$DIR/$tdir/tmp
3429         test_mkdir -p $tmp_dir
3430         test_mkdir $DIR/${tdir}2
3431         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3432         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3433         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3434         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3435         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3436         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3437 }
3438 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3439
3440 test_32h() {
3441         rm -fr $DIR/$tdir $DIR/${tdir}2
3442         tmp_dir=$DIR/$tdir/tmp
3443         test_mkdir -p $tmp_dir
3444         test_mkdir $DIR/${tdir}2
3445         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3446         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3447         ls $tmp_dir/symlink12 || error "listing symlink12"
3448         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3449 }
3450 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3451
3452 test_32i() {
3453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3454
3455         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3456         trap cleanup_test32_mount EXIT
3457         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3458         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3459                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3460         touch $DIR/$tdir/test_file
3461         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3462                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3463         cleanup_test32_mount
3464 }
3465 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3466
3467 test_32j() {
3468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3469
3470         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3471         trap cleanup_test32_mount EXIT
3472         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3473         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3474                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3475         touch $DIR/$tdir/test_file
3476         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3477                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3478         cleanup_test32_mount
3479 }
3480 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3481
3482 test_32k() {
3483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3484
3485         rm -fr $DIR/$tdir
3486         trap cleanup_test32_mount EXIT
3487         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3488         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3489                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3490         test_mkdir -p $DIR/$tdir/d2
3491         touch $DIR/$tdir/d2/test_file || error "touch failed"
3492         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3493                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3494         cleanup_test32_mount
3495 }
3496 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3497
3498 test_32l() {
3499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3500
3501         rm -fr $DIR/$tdir
3502         trap cleanup_test32_mount EXIT
3503         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3504         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3505                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3506         test_mkdir -p $DIR/$tdir/d2
3507         touch $DIR/$tdir/d2/test_file || error "touch failed"
3508         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3509                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3510         cleanup_test32_mount
3511 }
3512 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3513
3514 test_32m() {
3515         rm -fr $DIR/d32m
3516         test_mkdir -p $DIR/d32m/tmp
3517         TMP_DIR=$DIR/d32m/tmp
3518         ln -s $DIR $TMP_DIR/symlink11
3519         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3520         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3521                 error "symlink11 not a link"
3522         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3523                 error "symlink01 not a link"
3524 }
3525 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3526
3527 test_32n() {
3528         rm -fr $DIR/d32n
3529         test_mkdir -p $DIR/d32n/tmp
3530         TMP_DIR=$DIR/d32n/tmp
3531         ln -s $DIR $TMP_DIR/symlink11
3532         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3533         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3534         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3535 }
3536 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3537
3538 test_32o() {
3539         touch $DIR/$tfile
3540         test_mkdir -p $DIR/d32o/tmp
3541         TMP_DIR=$DIR/d32o/tmp
3542         ln -s $DIR/$tfile $TMP_DIR/symlink12
3543         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3544         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3545                 error "symlink12 not a link"
3546         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3547         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3548                 error "$DIR/d32o/tmp/symlink12 not file type"
3549         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3550                 error "$DIR/d32o/symlink02 not file type"
3551 }
3552 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3553
3554 test_32p() {
3555         log 32p_1
3556         rm -fr $DIR/d32p
3557         log 32p_2
3558         rm -f $DIR/$tfile
3559         log 32p_3
3560         touch $DIR/$tfile
3561         log 32p_4
3562         test_mkdir -p $DIR/d32p/tmp
3563         log 32p_5
3564         TMP_DIR=$DIR/d32p/tmp
3565         log 32p_6
3566         ln -s $DIR/$tfile $TMP_DIR/symlink12
3567         log 32p_7
3568         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3569         log 32p_8
3570         cat $DIR/d32p/tmp/symlink12 ||
3571                 error "Can't open $DIR/d32p/tmp/symlink12"
3572         log 32p_9
3573         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3574         log 32p_10
3575 }
3576 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3577
3578 test_32q() {
3579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3580
3581         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3582         trap cleanup_test32_mount EXIT
3583         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3584         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3585         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3586                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3587         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3588         cleanup_test32_mount
3589 }
3590 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3591
3592 test_32r() {
3593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3594
3595         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3596         trap cleanup_test32_mount EXIT
3597         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3598         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3599         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3600                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3601         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3602         cleanup_test32_mount
3603 }
3604 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3605
3606 test_33aa() {
3607         rm -f $DIR/$tfile
3608         touch $DIR/$tfile
3609         chmod 444 $DIR/$tfile
3610         chown $RUNAS_ID $DIR/$tfile
3611         log 33_1
3612         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3613         log 33_2
3614 }
3615 run_test 33aa "write file with mode 444 (should return error)"
3616
3617 test_33a() {
3618         rm -fr $DIR/$tdir
3619         test_mkdir $DIR/$tdir
3620         chown $RUNAS_ID $DIR/$tdir
3621         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3622                 error "$RUNAS create $tdir/$tfile failed"
3623         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3624                 error "open RDWR" || true
3625 }
3626 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3627
3628 test_33b() {
3629         rm -fr $DIR/$tdir
3630         test_mkdir $DIR/$tdir
3631         chown $RUNAS_ID $DIR/$tdir
3632         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3633 }
3634 run_test 33b "test open file with malformed flags (No panic)"
3635
3636 test_33c() {
3637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3638         remote_ost_nodsh && skip "remote OST with nodsh"
3639
3640         local ostnum
3641         local ostname
3642         local write_bytes
3643         local all_zeros
3644
3645         all_zeros=:
3646         rm -fr $DIR/$tdir
3647         test_mkdir $DIR/$tdir
3648         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3649
3650         sync
3651         for ostnum in $(seq $OSTCOUNT); do
3652                 # test-framework's OST numbering is one-based, while Lustre's
3653                 # is zero-based
3654                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3655                 # Parsing llobdstat's output sucks; we could grep the /proc
3656                 # path, but that's likely to not be as portable as using the
3657                 # llobdstat utility.  So we parse lctl output instead.
3658                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3659                         obdfilter/$ostname/stats |
3660                         awk '/^write_bytes/ {print $7}' )
3661                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3662                 if (( ${write_bytes:-0} > 0 ))
3663                 then
3664                         all_zeros=false
3665                         break;
3666                 fi
3667         done
3668
3669         $all_zeros || return 0
3670
3671         # Write four bytes
3672         echo foo > $DIR/$tdir/bar
3673         # Really write them
3674         sync
3675
3676         # Total up write_bytes after writing.  We'd better find non-zeros.
3677         for ostnum in $(seq $OSTCOUNT); do
3678                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3679                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3680                         obdfilter/$ostname/stats |
3681                         awk '/^write_bytes/ {print $7}' )
3682                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3683                 if (( ${write_bytes:-0} > 0 ))
3684                 then
3685                         all_zeros=false
3686                         break;
3687                 fi
3688         done
3689
3690         if $all_zeros
3691         then
3692                 for ostnum in $(seq $OSTCOUNT); do
3693                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3694                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3695                         do_facet ost$ostnum lctl get_param -n \
3696                                 obdfilter/$ostname/stats
3697                 done
3698                 error "OST not keeping write_bytes stats (b22312)"
3699         fi
3700 }
3701 run_test 33c "test llobdstat and write_bytes"
3702
3703 test_33d() {
3704         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3706
3707         local MDTIDX=1
3708         local remote_dir=$DIR/$tdir/remote_dir
3709
3710         test_mkdir $DIR/$tdir
3711         $LFS mkdir -i $MDTIDX $remote_dir ||
3712                 error "create remote directory failed"
3713
3714         touch $remote_dir/$tfile
3715         chmod 444 $remote_dir/$tfile
3716         chown $RUNAS_ID $remote_dir/$tfile
3717
3718         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3719
3720         chown $RUNAS_ID $remote_dir
3721         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3722                                         error "create" || true
3723         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3724                                     error "open RDWR" || true
3725         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3726 }
3727 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3728
3729 test_33e() {
3730         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3731
3732         mkdir $DIR/$tdir
3733
3734         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3735         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3736         mkdir $DIR/$tdir/local_dir
3737
3738         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3739         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3740         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3741
3742         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3743                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3744
3745         rmdir $DIR/$tdir/* || error "rmdir failed"
3746
3747         umask 777
3748         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3749         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3750         mkdir $DIR/$tdir/local_dir
3751
3752         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3753         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3754         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3755
3756         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3757                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3758
3759         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3760
3761         umask 000
3762         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3763         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3764         mkdir $DIR/$tdir/local_dir
3765
3766         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3767         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3768         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3769
3770         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3771                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3772 }
3773 run_test 33e "mkdir and striped directory should have same mode"
3774
3775 cleanup_33f() {
3776         trap 0
3777         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3778 }
3779
3780 test_33f() {
3781         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3782         remote_mds_nodsh && skip "remote MDS with nodsh"
3783
3784         mkdir $DIR/$tdir
3785         chmod go+rwx $DIR/$tdir
3786         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3787         trap cleanup_33f EXIT
3788
3789         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3790                 error "cannot create striped directory"
3791
3792         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3793                 error "cannot create files in striped directory"
3794
3795         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3796                 error "cannot remove files in striped directory"
3797
3798         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3799                 error "cannot remove striped directory"
3800
3801         cleanup_33f
3802 }
3803 run_test 33f "nonroot user can create, access, and remove a striped directory"
3804
3805 test_33g() {
3806         mkdir -p $DIR/$tdir/dir2
3807
3808         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3809         echo $err
3810         [[ $err =~ "exists" ]] || error "Not exists error"
3811 }
3812 run_test 33g "nonroot user create already existing root created file"
3813
3814 test_33h() {
3815         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3816         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3817                 skip "Need MDS version at least 2.13.50"
3818
3819         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3820                 error "mkdir $tdir failed"
3821         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3822
3823         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3824         local index2
3825
3826         for fname in $DIR/$tdir/$tfile.bak \
3827                      $DIR/$tdir/$tfile.SAV \
3828                      $DIR/$tdir/$tfile.orig \
3829                      $DIR/$tdir/$tfile~; do
3830                 touch $fname  || error "touch $fname failed"
3831                 index2=$($LFS getstripe -m $fname)
3832                 [ $index -eq $index2 ] ||
3833                         error "$fname MDT index mismatch $index != $index2"
3834         done
3835
3836         local failed=0
3837         for i in {1..250}; do
3838                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3839                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3840                         touch $fname  || error "touch $fname failed"
3841                         index2=$($LFS getstripe -m $fname)
3842                         if [[ $index != $index2 ]]; then
3843                                 failed=$((failed + 1))
3844                                 echo "$fname MDT index mismatch $index != $index2"
3845                         fi
3846                 done
3847         done
3848         echo "$failed MDT index mismatches"
3849         (( failed < 20 )) || error "MDT index mismatch $failed times"
3850
3851 }
3852 run_test 33h "temp file is located on the same MDT as target"
3853
3854 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3855 test_34a() {
3856         rm -f $DIR/f34
3857         $MCREATE $DIR/f34 || error "mcreate failed"
3858         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3859                 error "getstripe failed"
3860         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3861         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3862                 error "getstripe failed"
3863         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3864                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3865 }
3866 run_test 34a "truncate file that has not been opened ==========="
3867
3868 test_34b() {
3869         [ ! -f $DIR/f34 ] && test_34a
3870         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3871                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3872         $OPENFILE -f O_RDONLY $DIR/f34
3873         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3874                 error "getstripe failed"
3875         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3876                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3877 }
3878 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3879
3880 test_34c() {
3881         [ ! -f $DIR/f34 ] && test_34a
3882         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3883                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3884         $OPENFILE -f O_RDWR $DIR/f34
3885         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3886                 error "$LFS getstripe failed"
3887         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3888                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3889 }
3890 run_test 34c "O_RDWR opening file-with-size works =============="
3891
3892 test_34d() {
3893         [ ! -f $DIR/f34 ] && test_34a
3894         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3895                 error "dd failed"
3896         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3897                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3898         rm $DIR/f34
3899 }
3900 run_test 34d "write to sparse file ============================="
3901
3902 test_34e() {
3903         rm -f $DIR/f34e
3904         $MCREATE $DIR/f34e || error "mcreate failed"
3905         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3906         $CHECKSTAT -s 1000 $DIR/f34e ||
3907                 error "Size of $DIR/f34e not equal to 1000 bytes"
3908         $OPENFILE -f O_RDWR $DIR/f34e
3909         $CHECKSTAT -s 1000 $DIR/f34e ||
3910                 error "Size of $DIR/f34e not equal to 1000 bytes"
3911 }
3912 run_test 34e "create objects, some with size and some without =="
3913
3914 test_34f() { # bug 6242, 6243
3915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3916
3917         SIZE34F=48000
3918         rm -f $DIR/f34f
3919         $MCREATE $DIR/f34f || error "mcreate failed"
3920         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3921         dd if=$DIR/f34f of=$TMP/f34f
3922         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3923         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3924         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3925         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3926         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3927 }
3928 run_test 34f "read from a file with no objects until EOF ======="
3929
3930 test_34g() {
3931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3932
3933         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3934                 error "dd failed"
3935         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3936         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3937                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3938         cancel_lru_locks osc
3939         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3940                 error "wrong size after lock cancel"
3941
3942         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3943         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3944                 error "expanding truncate failed"
3945         cancel_lru_locks osc
3946         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3947                 error "wrong expanded size after lock cancel"
3948 }
3949 run_test 34g "truncate long file ==============================="
3950
3951 test_34h() {
3952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3953
3954         local gid=10
3955         local sz=1000
3956
3957         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3958         sync # Flush the cache so that multiop below does not block on cache
3959              # flush when getting the group lock
3960         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3961         MULTIPID=$!
3962
3963         # Since just timed wait is not good enough, let's do a sync write
3964         # that way we are sure enough time for a roundtrip + processing
3965         # passed + 2 seconds of extra margin.
3966         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3967         rm $DIR/${tfile}-1
3968         sleep 2
3969
3970         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3971                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3972                 kill -9 $MULTIPID
3973         fi
3974         wait $MULTIPID
3975         local nsz=`stat -c %s $DIR/$tfile`
3976         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3977 }
3978 run_test 34h "ftruncate file under grouplock should not block"
3979
3980 test_35a() {
3981         cp /bin/sh $DIR/f35a
3982         chmod 444 $DIR/f35a
3983         chown $RUNAS_ID $DIR/f35a
3984         $RUNAS $DIR/f35a && error || true
3985         rm $DIR/f35a
3986 }
3987 run_test 35a "exec file with mode 444 (should return and not leak)"
3988
3989 test_36a() {
3990         rm -f $DIR/f36
3991         utime $DIR/f36 || error "utime failed for MDS"
3992 }
3993 run_test 36a "MDS utime check (mknod, utime)"
3994
3995 test_36b() {
3996         echo "" > $DIR/f36
3997         utime $DIR/f36 || error "utime failed for OST"
3998 }
3999 run_test 36b "OST utime check (open, utime)"
4000
4001 test_36c() {
4002         rm -f $DIR/d36/f36
4003         test_mkdir $DIR/d36
4004         chown $RUNAS_ID $DIR/d36
4005         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4006 }
4007 run_test 36c "non-root MDS utime check (mknod, utime)"
4008
4009 test_36d() {
4010         [ ! -d $DIR/d36 ] && test_36c
4011         echo "" > $DIR/d36/f36
4012         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4013 }
4014 run_test 36d "non-root OST utime check (open, utime)"
4015
4016 test_36e() {
4017         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4018
4019         test_mkdir $DIR/$tdir
4020         touch $DIR/$tdir/$tfile
4021         $RUNAS utime $DIR/$tdir/$tfile &&
4022                 error "utime worked, expected failure" || true
4023 }
4024 run_test 36e "utime on non-owned file (should return error)"
4025
4026 subr_36fh() {
4027         local fl="$1"
4028         local LANG_SAVE=$LANG
4029         local LC_LANG_SAVE=$LC_LANG
4030         export LANG=C LC_LANG=C # for date language
4031
4032         DATESTR="Dec 20  2000"
4033         test_mkdir $DIR/$tdir
4034         lctl set_param fail_loc=$fl
4035         date; date +%s
4036         cp /etc/hosts $DIR/$tdir/$tfile
4037         sync & # write RPC generated with "current" inode timestamp, but delayed
4038         sleep 1
4039         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4040         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4041         cancel_lru_locks $OSC
4042         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4043         date; date +%s
4044         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4045                 echo "BEFORE: $LS_BEFORE" && \
4046                 echo "AFTER : $LS_AFTER" && \
4047                 echo "WANT  : $DATESTR" && \
4048                 error "$DIR/$tdir/$tfile timestamps changed" || true
4049
4050         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4051 }
4052
4053 test_36f() {
4054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4055
4056         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4057         subr_36fh "0x80000214"
4058 }
4059 run_test 36f "utime on file racing with OST BRW write =========="
4060
4061 test_36g() {
4062         remote_ost_nodsh && skip "remote OST with nodsh"
4063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4064         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4065                 skip "Need MDS version at least 2.12.51"
4066
4067         local fmd_max_age
4068         local fmd
4069         local facet="ost1"
4070         local tgt="obdfilter"
4071
4072         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4073
4074         test_mkdir $DIR/$tdir
4075         fmd_max_age=$(do_facet $facet \
4076                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4077                 head -n 1")
4078
4079         echo "FMD max age: ${fmd_max_age}s"
4080         touch $DIR/$tdir/$tfile
4081         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4082                 gawk '{cnt=cnt+$1}  END{print cnt}')
4083         echo "FMD before: $fmd"
4084         [[ $fmd == 0 ]] &&
4085                 error "FMD wasn't create by touch"
4086         sleep $((fmd_max_age + 12))
4087         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4088                 gawk '{cnt=cnt+$1}  END{print cnt}')
4089         echo "FMD after: $fmd"
4090         [[ $fmd == 0 ]] ||
4091                 error "FMD wasn't expired by ping"
4092 }
4093 run_test 36g "FMD cache expiry ====================="
4094
4095 test_36h() {
4096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4097
4098         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4099         subr_36fh "0x80000227"
4100 }
4101 run_test 36h "utime on file racing with OST BRW write =========="
4102
4103 test_36i() {
4104         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4105
4106         test_mkdir $DIR/$tdir
4107         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4108
4109         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4110         local new_mtime=$((mtime + 200))
4111
4112         #change Modify time of striped dir
4113         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4114                         error "change mtime failed"
4115
4116         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4117
4118         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4119 }
4120 run_test 36i "change mtime on striped directory"
4121
4122 # test_37 - duplicate with tests 32q 32r
4123
4124 test_38() {
4125         local file=$DIR/$tfile
4126         touch $file
4127         openfile -f O_DIRECTORY $file
4128         local RC=$?
4129         local ENOTDIR=20
4130         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4131         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4132 }
4133 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4134
4135 test_39a() { # was test_39
4136         touch $DIR/$tfile
4137         touch $DIR/${tfile}2
4138 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4139 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4140 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4141         sleep 2
4142         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4143         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4144                 echo "mtime"
4145                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4146                 echo "atime"
4147                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4148                 echo "ctime"
4149                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4150                 error "O_TRUNC didn't change timestamps"
4151         fi
4152 }
4153 run_test 39a "mtime changed on create"
4154
4155 test_39b() {
4156         test_mkdir -c1 $DIR/$tdir
4157         cp -p /etc/passwd $DIR/$tdir/fopen
4158         cp -p /etc/passwd $DIR/$tdir/flink
4159         cp -p /etc/passwd $DIR/$tdir/funlink
4160         cp -p /etc/passwd $DIR/$tdir/frename
4161         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4162
4163         sleep 1
4164         echo "aaaaaa" >> $DIR/$tdir/fopen
4165         echo "aaaaaa" >> $DIR/$tdir/flink
4166         echo "aaaaaa" >> $DIR/$tdir/funlink
4167         echo "aaaaaa" >> $DIR/$tdir/frename
4168
4169         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4170         local link_new=`stat -c %Y $DIR/$tdir/flink`
4171         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4172         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4173
4174         cat $DIR/$tdir/fopen > /dev/null
4175         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4176         rm -f $DIR/$tdir/funlink2
4177         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4178
4179         for (( i=0; i < 2; i++ )) ; do
4180                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4181                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4182                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4183                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4184
4185                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4186                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4187                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4188                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4189
4190                 cancel_lru_locks $OSC
4191                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4192         done
4193 }
4194 run_test 39b "mtime change on open, link, unlink, rename  ======"
4195
4196 # this should be set to past
4197 TEST_39_MTIME=`date -d "1 year ago" +%s`
4198
4199 # bug 11063
4200 test_39c() {
4201         touch $DIR1/$tfile
4202         sleep 2
4203         local mtime0=`stat -c %Y $DIR1/$tfile`
4204
4205         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4206         local mtime1=`stat -c %Y $DIR1/$tfile`
4207         [ "$mtime1" = $TEST_39_MTIME ] || \
4208                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4209
4210         local d1=`date +%s`
4211         echo hello >> $DIR1/$tfile
4212         local d2=`date +%s`
4213         local mtime2=`stat -c %Y $DIR1/$tfile`
4214         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4215                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4216
4217         mv $DIR1/$tfile $DIR1/$tfile-1
4218
4219         for (( i=0; i < 2; i++ )) ; do
4220                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4221                 [ "$mtime2" = "$mtime3" ] || \
4222                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4223
4224                 cancel_lru_locks $OSC
4225                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4226         done
4227 }
4228 run_test 39c "mtime change on rename ==========================="
4229
4230 # bug 21114
4231 test_39d() {
4232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4233
4234         touch $DIR1/$tfile
4235         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4236
4237         for (( i=0; i < 2; i++ )) ; do
4238                 local mtime=`stat -c %Y $DIR1/$tfile`
4239                 [ $mtime = $TEST_39_MTIME ] || \
4240                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4241
4242                 cancel_lru_locks $OSC
4243                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4244         done
4245 }
4246 run_test 39d "create, utime, stat =============================="
4247
4248 # bug 21114
4249 test_39e() {
4250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4251
4252         touch $DIR1/$tfile
4253         local mtime1=`stat -c %Y $DIR1/$tfile`
4254
4255         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4256
4257         for (( i=0; i < 2; i++ )) ; do
4258                 local mtime2=`stat -c %Y $DIR1/$tfile`
4259                 [ $mtime2 = $TEST_39_MTIME ] || \
4260                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4261
4262                 cancel_lru_locks $OSC
4263                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4264         done
4265 }
4266 run_test 39e "create, stat, utime, stat ========================"
4267
4268 # bug 21114
4269 test_39f() {
4270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4271
4272         touch $DIR1/$tfile
4273         mtime1=`stat -c %Y $DIR1/$tfile`
4274
4275         sleep 2
4276         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4277
4278         for (( i=0; i < 2; i++ )) ; do
4279                 local mtime2=`stat -c %Y $DIR1/$tfile`
4280                 [ $mtime2 = $TEST_39_MTIME ] || \
4281                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4282
4283                 cancel_lru_locks $OSC
4284                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4285         done
4286 }
4287 run_test 39f "create, stat, sleep, utime, stat ================="
4288
4289 # bug 11063
4290 test_39g() {
4291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4292
4293         echo hello >> $DIR1/$tfile
4294         local mtime1=`stat -c %Y $DIR1/$tfile`
4295
4296         sleep 2
4297         chmod o+r $DIR1/$tfile
4298
4299         for (( i=0; i < 2; i++ )) ; do
4300                 local mtime2=`stat -c %Y $DIR1/$tfile`
4301                 [ "$mtime1" = "$mtime2" ] || \
4302                         error "lost mtime: $mtime2, should be $mtime1"
4303
4304                 cancel_lru_locks $OSC
4305                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4306         done
4307 }
4308 run_test 39g "write, chmod, stat ==============================="
4309
4310 # bug 11063
4311 test_39h() {
4312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4313
4314         touch $DIR1/$tfile
4315         sleep 1
4316
4317         local d1=`date`
4318         echo hello >> $DIR1/$tfile
4319         local mtime1=`stat -c %Y $DIR1/$tfile`
4320
4321         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4322         local d2=`date`
4323         if [ "$d1" != "$d2" ]; then
4324                 echo "write and touch not within one second"
4325         else
4326                 for (( i=0; i < 2; i++ )) ; do
4327                         local mtime2=`stat -c %Y $DIR1/$tfile`
4328                         [ "$mtime2" = $TEST_39_MTIME ] || \
4329                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4330
4331                         cancel_lru_locks $OSC
4332                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4333                 done
4334         fi
4335 }
4336 run_test 39h "write, utime within one second, stat ============="
4337
4338 test_39i() {
4339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4340
4341         touch $DIR1/$tfile
4342         sleep 1
4343
4344         echo hello >> $DIR1/$tfile
4345         local mtime1=`stat -c %Y $DIR1/$tfile`
4346
4347         mv $DIR1/$tfile $DIR1/$tfile-1
4348
4349         for (( i=0; i < 2; i++ )) ; do
4350                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4351
4352                 [ "$mtime1" = "$mtime2" ] || \
4353                         error "lost mtime: $mtime2, should be $mtime1"
4354
4355                 cancel_lru_locks $OSC
4356                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4357         done
4358 }
4359 run_test 39i "write, rename, stat =============================="
4360
4361 test_39j() {
4362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4363
4364         start_full_debug_logging
4365         touch $DIR1/$tfile
4366         sleep 1
4367
4368         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4369         lctl set_param fail_loc=0x80000412
4370         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4371                 error "multiop failed"
4372         local multipid=$!
4373         local mtime1=`stat -c %Y $DIR1/$tfile`
4374
4375         mv $DIR1/$tfile $DIR1/$tfile-1
4376
4377         kill -USR1 $multipid
4378         wait $multipid || error "multiop close failed"
4379
4380         for (( i=0; i < 2; i++ )) ; do
4381                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4382                 [ "$mtime1" = "$mtime2" ] ||
4383                         error "mtime is lost on close: $mtime2, " \
4384                               "should be $mtime1"
4385
4386                 cancel_lru_locks
4387                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4388         done
4389         lctl set_param fail_loc=0
4390         stop_full_debug_logging
4391 }
4392 run_test 39j "write, rename, close, stat ======================="
4393
4394 test_39k() {
4395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4396
4397         touch $DIR1/$tfile
4398         sleep 1
4399
4400         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4401         local multipid=$!
4402         local mtime1=`stat -c %Y $DIR1/$tfile`
4403
4404         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4405
4406         kill -USR1 $multipid
4407         wait $multipid || error "multiop close failed"
4408
4409         for (( i=0; i < 2; i++ )) ; do
4410                 local mtime2=`stat -c %Y $DIR1/$tfile`
4411
4412                 [ "$mtime2" = $TEST_39_MTIME ] || \
4413                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4414
4415                 cancel_lru_locks
4416                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4417         done
4418 }
4419 run_test 39k "write, utime, close, stat ========================"
4420
4421 # this should be set to future
4422 TEST_39_ATIME=`date -d "1 year" +%s`
4423
4424 test_39l() {
4425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4426         remote_mds_nodsh && skip "remote MDS with nodsh"
4427
4428         local atime_diff=$(do_facet $SINGLEMDS \
4429                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4430         rm -rf $DIR/$tdir
4431         mkdir -p $DIR/$tdir
4432
4433         # test setting directory atime to future
4434         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4435         local atime=$(stat -c %X $DIR/$tdir)
4436         [ "$atime" = $TEST_39_ATIME ] ||
4437                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4438
4439         # test setting directory atime from future to now
4440         local now=$(date +%s)
4441         touch -a -d @$now $DIR/$tdir
4442
4443         atime=$(stat -c %X $DIR/$tdir)
4444         [ "$atime" -eq "$now"  ] ||
4445                 error "atime is not updated from future: $atime, $now"
4446
4447         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4448         sleep 3
4449
4450         # test setting directory atime when now > dir atime + atime_diff
4451         local d1=$(date +%s)
4452         ls $DIR/$tdir
4453         local d2=$(date +%s)
4454         cancel_lru_locks mdc
4455         atime=$(stat -c %X $DIR/$tdir)
4456         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4457                 error "atime is not updated  : $atime, should be $d2"
4458
4459         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4460         sleep 3
4461
4462         # test not setting directory atime when now < dir atime + atime_diff
4463         ls $DIR/$tdir
4464         cancel_lru_locks mdc
4465         atime=$(stat -c %X $DIR/$tdir)
4466         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4467                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4468
4469         do_facet $SINGLEMDS \
4470                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4471 }
4472 run_test 39l "directory atime update ==========================="
4473
4474 test_39m() {
4475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4476
4477         touch $DIR1/$tfile
4478         sleep 2
4479         local far_past_mtime=$(date -d "May 29 1953" +%s)
4480         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4481
4482         touch -m -d @$far_past_mtime $DIR1/$tfile
4483         touch -a -d @$far_past_atime $DIR1/$tfile
4484
4485         for (( i=0; i < 2; i++ )) ; do
4486                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4487                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4488                         error "atime or mtime set incorrectly"
4489
4490                 cancel_lru_locks $OSC
4491                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4492         done
4493 }
4494 run_test 39m "test atime and mtime before 1970"
4495
4496 test_39n() { # LU-3832
4497         remote_mds_nodsh && skip "remote MDS with nodsh"
4498
4499         local atime_diff=$(do_facet $SINGLEMDS \
4500                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4501         local atime0
4502         local atime1
4503         local atime2
4504
4505         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4506
4507         rm -rf $DIR/$tfile
4508         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4509         atime0=$(stat -c %X $DIR/$tfile)
4510
4511         sleep 5
4512         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4513         atime1=$(stat -c %X $DIR/$tfile)
4514
4515         sleep 5
4516         cancel_lru_locks mdc
4517         cancel_lru_locks osc
4518         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4519         atime2=$(stat -c %X $DIR/$tfile)
4520
4521         do_facet $SINGLEMDS \
4522                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4523
4524         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4525         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4526 }
4527 run_test 39n "check that O_NOATIME is honored"
4528
4529 test_39o() {
4530         TESTDIR=$DIR/$tdir/$tfile
4531         [ -e $TESTDIR ] && rm -rf $TESTDIR
4532         mkdir -p $TESTDIR
4533         cd $TESTDIR
4534         links1=2
4535         ls
4536         mkdir a b
4537         ls
4538         links2=$(stat -c %h .)
4539         [ $(($links1 + 2)) != $links2 ] &&
4540                 error "wrong links count $(($links1 + 2)) != $links2"
4541         rmdir b
4542         links3=$(stat -c %h .)
4543         [ $(($links1 + 1)) != $links3 ] &&
4544                 error "wrong links count $links1 != $links3"
4545         return 0
4546 }
4547 run_test 39o "directory cached attributes updated after create"
4548
4549 test_39p() {
4550         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4551
4552         local MDTIDX=1
4553         TESTDIR=$DIR/$tdir/$tdir
4554         [ -e $TESTDIR ] && rm -rf $TESTDIR
4555         test_mkdir -p $TESTDIR
4556         cd $TESTDIR
4557         links1=2
4558         ls
4559         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4560         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4561         ls
4562         links2=$(stat -c %h .)
4563         [ $(($links1 + 2)) != $links2 ] &&
4564                 error "wrong links count $(($links1 + 2)) != $links2"
4565         rmdir remote_dir2
4566         links3=$(stat -c %h .)
4567         [ $(($links1 + 1)) != $links3 ] &&
4568                 error "wrong links count $links1 != $links3"
4569         return 0
4570 }
4571 run_test 39p "remote directory cached attributes updated after create ========"
4572
4573 test_39r() {
4574         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4575                 skip "no atime update on old OST"
4576         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4577                 skip_env "ldiskfs only test"
4578         fi
4579
4580         local saved_adiff
4581         saved_adiff=$(do_facet ost1 \
4582                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4583         stack_trap "do_facet ost1 \
4584                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4585
4586         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4587
4588         $LFS setstripe -i 0 $DIR/$tfile
4589         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4590                 error "can't write initial file"
4591         cancel_lru_locks osc
4592
4593         # exceed atime_diff and access file
4594         sleep 6
4595         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4596
4597         local atime_cli=$(stat -c %X $DIR/$tfile)
4598         echo "client atime: $atime_cli"
4599         # allow atime update to be written to device
4600         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4601         sleep 5
4602
4603         local ostdev=$(ostdevname 1)
4604         local fid=($(lfs getstripe -y $DIR/$tfile |
4605                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4606         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4607         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4608
4609         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4610         local atime_ost=$(do_facet ost1 "$cmd" |&
4611                           awk -F'[: ]' '/atime:/ { print $4 }')
4612         (( atime_cli == atime_ost )) ||
4613                 error "atime on client $atime_cli != ost $atime_ost"
4614 }
4615 run_test 39r "lazy atime update on OST"
4616
4617 test_39q() { # LU-8041
4618         local testdir=$DIR/$tdir
4619         mkdir -p $testdir
4620         multiop_bg_pause $testdir D_c || error "multiop failed"
4621         local multipid=$!
4622         cancel_lru_locks mdc
4623         kill -USR1 $multipid
4624         local atime=$(stat -c %X $testdir)
4625         [ "$atime" -ne 0 ] || error "atime is zero"
4626 }
4627 run_test 39q "close won't zero out atime"
4628
4629 test_40() {
4630         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4631         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4632                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4633         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4634                 error "$tfile is not 4096 bytes in size"
4635 }
4636 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4637
4638 test_41() {
4639         # bug 1553
4640         small_write $DIR/f41 18
4641 }
4642 run_test 41 "test small file write + fstat ====================="
4643
4644 count_ost_writes() {
4645         lctl get_param -n ${OSC}.*.stats |
4646                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4647                         END { printf("%0.0f", writes) }'
4648 }
4649
4650 # decent default
4651 WRITEBACK_SAVE=500
4652 DIRTY_RATIO_SAVE=40
4653 MAX_DIRTY_RATIO=50
4654 BG_DIRTY_RATIO_SAVE=10
4655 MAX_BG_DIRTY_RATIO=25
4656
4657 start_writeback() {
4658         trap 0
4659         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4660         # dirty_ratio, dirty_background_ratio
4661         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4662                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4663                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4664                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4665         else
4666                 # if file not here, we are a 2.4 kernel
4667                 kill -CONT `pidof kupdated`
4668         fi
4669 }
4670
4671 stop_writeback() {
4672         # setup the trap first, so someone cannot exit the test at the
4673         # exact wrong time and mess up a machine
4674         trap start_writeback EXIT
4675         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4676         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4677                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4678                 sysctl -w vm.dirty_writeback_centisecs=0
4679                 sysctl -w vm.dirty_writeback_centisecs=0
4680                 # save and increase /proc/sys/vm/dirty_ratio
4681                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4682                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4683                 # save and increase /proc/sys/vm/dirty_background_ratio
4684                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4685                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4686         else
4687                 # if file not here, we are a 2.4 kernel
4688                 kill -STOP `pidof kupdated`
4689         fi
4690 }
4691
4692 # ensure that all stripes have some grant before we test client-side cache
4693 setup_test42() {
4694         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4695                 dd if=/dev/zero of=$i bs=4k count=1
4696                 rm $i
4697         done
4698 }
4699
4700 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4701 # file truncation, and file removal.
4702 test_42a() {
4703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4704
4705         setup_test42
4706         cancel_lru_locks $OSC
4707         stop_writeback
4708         sync; sleep 1; sync # just to be safe
4709         BEFOREWRITES=`count_ost_writes`
4710         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4711         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4712         AFTERWRITES=`count_ost_writes`
4713         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4714                 error "$BEFOREWRITES < $AFTERWRITES"
4715         start_writeback
4716 }
4717 run_test 42a "ensure that we don't flush on close"
4718
4719 test_42b() {
4720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4721
4722         setup_test42
4723         cancel_lru_locks $OSC
4724         stop_writeback
4725         sync
4726         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4727         BEFOREWRITES=$(count_ost_writes)
4728         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4729         AFTERWRITES=$(count_ost_writes)
4730         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4731                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4732         fi
4733         BEFOREWRITES=$(count_ost_writes)
4734         sync || error "sync: $?"
4735         AFTERWRITES=$(count_ost_writes)
4736         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4737                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4738         fi
4739         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4740         start_writeback
4741         return 0
4742 }
4743 run_test 42b "test destroy of file with cached dirty data ======"
4744
4745 # if these tests just want to test the effect of truncation,
4746 # they have to be very careful.  consider:
4747 # - the first open gets a {0,EOF}PR lock
4748 # - the first write conflicts and gets a {0, count-1}PW
4749 # - the rest of the writes are under {count,EOF}PW
4750 # - the open for truncate tries to match a {0,EOF}PR
4751 #   for the filesize and cancels the PWs.
4752 # any number of fixes (don't get {0,EOF} on open, match
4753 # composite locks, do smarter file size management) fix
4754 # this, but for now we want these tests to verify that
4755 # the cancellation with truncate intent works, so we
4756 # start the file with a full-file pw lock to match against
4757 # until the truncate.
4758 trunc_test() {
4759         test=$1
4760         file=$DIR/$test
4761         offset=$2
4762         cancel_lru_locks $OSC
4763         stop_writeback
4764         # prime the file with 0,EOF PW to match
4765         touch $file
4766         $TRUNCATE $file 0
4767         sync; sync
4768         # now the real test..
4769         dd if=/dev/zero of=$file bs=1024 count=100
4770         BEFOREWRITES=`count_ost_writes`
4771         $TRUNCATE $file $offset
4772         cancel_lru_locks $OSC
4773         AFTERWRITES=`count_ost_writes`
4774         start_writeback
4775 }
4776
4777 test_42c() {
4778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4779
4780         trunc_test 42c 1024
4781         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4782                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4783         rm $file
4784 }
4785 run_test 42c "test partial truncate of file with cached dirty data"
4786
4787 test_42d() {
4788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4789
4790         trunc_test 42d 0
4791         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4792                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4793         rm $file
4794 }
4795 run_test 42d "test complete truncate of file with cached dirty data"
4796
4797 test_42e() { # bug22074
4798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4799
4800         local TDIR=$DIR/${tdir}e
4801         local pages=16 # hardcoded 16 pages, don't change it.
4802         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4803         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4804         local max_dirty_mb
4805         local warmup_files
4806
4807         test_mkdir $DIR/${tdir}e
4808         $LFS setstripe -c 1 $TDIR
4809         createmany -o $TDIR/f $files
4810
4811         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4812
4813         # we assume that with $OSTCOUNT files, at least one of them will
4814         # be allocated on OST0.
4815         warmup_files=$((OSTCOUNT * max_dirty_mb))
4816         createmany -o $TDIR/w $warmup_files
4817
4818         # write a large amount of data into one file and sync, to get good
4819         # avail_grant number from OST.
4820         for ((i=0; i<$warmup_files; i++)); do
4821                 idx=$($LFS getstripe -i $TDIR/w$i)
4822                 [ $idx -ne 0 ] && continue
4823                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4824                 break
4825         done
4826         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4827         sync
4828         $LCTL get_param $proc_osc0/cur_dirty_bytes
4829         $LCTL get_param $proc_osc0/cur_grant_bytes
4830
4831         # create as much dirty pages as we can while not to trigger the actual
4832         # RPCs directly. but depends on the env, VFS may trigger flush during this
4833         # period, hopefully we are good.
4834         for ((i=0; i<$warmup_files; i++)); do
4835                 idx=$($LFS getstripe -i $TDIR/w$i)
4836                 [ $idx -ne 0 ] && continue
4837                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4838         done
4839         $LCTL get_param $proc_osc0/cur_dirty_bytes
4840         $LCTL get_param $proc_osc0/cur_grant_bytes
4841
4842         # perform the real test
4843         $LCTL set_param $proc_osc0/rpc_stats 0
4844         for ((;i<$files; i++)); do
4845                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4846                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4847         done
4848         sync
4849         $LCTL get_param $proc_osc0/rpc_stats
4850
4851         local percent=0
4852         local have_ppr=false
4853         $LCTL get_param $proc_osc0/rpc_stats |
4854                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4855                         # skip lines until we are at the RPC histogram data
4856                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4857                         $have_ppr || continue
4858
4859                         # we only want the percent stat for < 16 pages
4860                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4861
4862                         percent=$((percent + WPCT))
4863                         if [[ $percent -gt 15 ]]; then
4864                                 error "less than 16-pages write RPCs" \
4865                                       "$percent% > 15%"
4866                                 break
4867                         fi
4868                 done
4869         rm -rf $TDIR
4870 }
4871 run_test 42e "verify sub-RPC writes are not done synchronously"
4872
4873 test_43A() { # was test_43
4874         test_mkdir $DIR/$tdir
4875         cp -p /bin/ls $DIR/$tdir/$tfile
4876         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4877         pid=$!
4878         # give multiop a chance to open
4879         sleep 1
4880
4881         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4882         kill -USR1 $pid
4883         # Wait for multiop to exit
4884         wait $pid
4885 }
4886 run_test 43A "execution of file opened for write should return -ETXTBSY"
4887
4888 test_43a() {
4889         test_mkdir $DIR/$tdir
4890         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4891         $DIR/$tdir/sleep 60 &
4892         SLEEP_PID=$!
4893         # Make sure exec of $tdir/sleep wins race with truncate
4894         sleep 1
4895         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4896         kill $SLEEP_PID
4897 }
4898 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4899
4900 test_43b() {
4901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4902
4903         test_mkdir $DIR/$tdir
4904         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4905         $DIR/$tdir/sleep 60 &
4906         SLEEP_PID=$!
4907         # Make sure exec of $tdir/sleep wins race with truncate
4908         sleep 1
4909         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4910         kill $SLEEP_PID
4911 }
4912 run_test 43b "truncate of file being executed should return -ETXTBSY"
4913
4914 test_43c() {
4915         local testdir="$DIR/$tdir"
4916         test_mkdir $testdir
4917         cp $SHELL $testdir/
4918         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4919                 ( cd $testdir && md5sum -c )
4920 }
4921 run_test 43c "md5sum of copy into lustre"
4922
4923 test_44A() { # was test_44
4924         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4925
4926         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4927         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4928 }
4929 run_test 44A "zero length read from a sparse stripe"
4930
4931 test_44a() {
4932         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4933                 awk '{ print $2 }')
4934         [ -z "$nstripe" ] && skip "can't get stripe info"
4935         [[ $nstripe -gt $OSTCOUNT ]] &&
4936                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4937
4938         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4939                 awk '{ print $2 }')
4940         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4941                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4942                         awk '{ print $2 }')
4943         fi
4944
4945         OFFSETS="0 $((stride/2)) $((stride-1))"
4946         for offset in $OFFSETS; do
4947                 for i in $(seq 0 $((nstripe-1))); do
4948                         local GLOBALOFFSETS=""
4949                         # size in Bytes
4950                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4951                         local myfn=$DIR/d44a-$size
4952                         echo "--------writing $myfn at $size"
4953                         ll_sparseness_write $myfn $size ||
4954                                 error "ll_sparseness_write"
4955                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4956                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4957                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4958
4959                         for j in $(seq 0 $((nstripe-1))); do
4960                                 # size in Bytes
4961                                 size=$((((j + $nstripe )*$stride + $offset)))
4962                                 ll_sparseness_write $myfn $size ||
4963                                         error "ll_sparseness_write"
4964                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4965                         done
4966                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4967                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4968                         rm -f $myfn
4969                 done
4970         done
4971 }
4972 run_test 44a "test sparse pwrite ==============================="
4973
4974 dirty_osc_total() {
4975         tot=0
4976         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4977                 tot=$(($tot + $d))
4978         done
4979         echo $tot
4980 }
4981 do_dirty_record() {
4982         before=`dirty_osc_total`
4983         echo executing "\"$*\""
4984         eval $*
4985         after=`dirty_osc_total`
4986         echo before $before, after $after
4987 }
4988 test_45() {
4989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4990
4991         f="$DIR/f45"
4992         # Obtain grants from OST if it supports it
4993         echo blah > ${f}_grant
4994         stop_writeback
4995         sync
4996         do_dirty_record "echo blah > $f"
4997         [[ $before -eq $after ]] && error "write wasn't cached"
4998         do_dirty_record "> $f"
4999         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5000         do_dirty_record "echo blah > $f"
5001         [[ $before -eq $after ]] && error "write wasn't cached"
5002         do_dirty_record "sync"
5003         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5004         do_dirty_record "echo blah > $f"
5005         [[ $before -eq $after ]] && error "write wasn't cached"
5006         do_dirty_record "cancel_lru_locks osc"
5007         [[ $before -gt $after ]] ||
5008                 error "lock cancellation didn't lower dirty count"
5009         start_writeback
5010 }
5011 run_test 45 "osc io page accounting ============================"
5012
5013 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5014 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5015 # objects offset and an assert hit when an rpc was built with 1023's mapped
5016 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5017 test_46() {
5018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5019
5020         f="$DIR/f46"
5021         stop_writeback
5022         sync
5023         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5024         sync
5025         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5026         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5027         sync
5028         start_writeback
5029 }
5030 run_test 46 "dirtying a previously written page ================"
5031
5032 # test_47 is removed "Device nodes check" is moved to test_28
5033
5034 test_48a() { # bug 2399
5035         [ "$mds1_FSTYPE" = "zfs" ] &&
5036         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5037                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5038
5039         test_mkdir $DIR/$tdir
5040         cd $DIR/$tdir
5041         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5042         test_mkdir $DIR/$tdir
5043         touch foo || error "'touch foo' failed after recreating cwd"
5044         test_mkdir bar
5045         touch .foo || error "'touch .foo' failed after recreating cwd"
5046         test_mkdir .bar
5047         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5048         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5049         cd . || error "'cd .' failed after recreating cwd"
5050         mkdir . && error "'mkdir .' worked after recreating cwd"
5051         rmdir . && error "'rmdir .' worked after recreating cwd"
5052         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5053         cd .. || error "'cd ..' failed after recreating cwd"
5054 }
5055 run_test 48a "Access renamed working dir (should return errors)="
5056
5057 test_48b() { # bug 2399
5058         rm -rf $DIR/$tdir
5059         test_mkdir $DIR/$tdir
5060         cd $DIR/$tdir
5061         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5062         touch foo && error "'touch foo' worked after removing cwd"
5063         mkdir foo && error "'mkdir foo' worked after removing cwd"
5064         touch .foo && error "'touch .foo' worked after removing cwd"
5065         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5066         ls . > /dev/null && error "'ls .' worked after removing cwd"
5067         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5068         mkdir . && error "'mkdir .' worked after removing cwd"
5069         rmdir . && error "'rmdir .' worked after removing cwd"
5070         ln -s . foo && error "'ln -s .' worked after removing cwd"
5071         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5072 }
5073 run_test 48b "Access removed working dir (should return errors)="
5074
5075 test_48c() { # bug 2350
5076         #lctl set_param debug=-1
5077         #set -vx
5078         rm -rf $DIR/$tdir
5079         test_mkdir -p $DIR/$tdir/dir
5080         cd $DIR/$tdir/dir
5081         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5082         $TRACE touch foo && error "touch foo worked after removing cwd"
5083         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5084         touch .foo && error "touch .foo worked after removing cwd"
5085         mkdir .foo && error "mkdir .foo worked after removing cwd"
5086         $TRACE ls . && error "'ls .' worked after removing cwd"
5087         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5088         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5089         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5090         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5091         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5092 }
5093 run_test 48c "Access removed working subdir (should return errors)"
5094
5095 test_48d() { # bug 2350
5096         #lctl set_param debug=-1
5097         #set -vx
5098         rm -rf $DIR/$tdir
5099         test_mkdir -p $DIR/$tdir/dir
5100         cd $DIR/$tdir/dir
5101         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5102         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5103         $TRACE touch foo && error "'touch foo' worked after removing parent"
5104         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5105         touch .foo && error "'touch .foo' worked after removing parent"
5106         mkdir .foo && error "mkdir .foo worked after removing parent"
5107         $TRACE ls . && error "'ls .' worked after removing parent"
5108         $TRACE ls .. && error "'ls ..' worked after removing parent"
5109         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5110         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5111         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5112         true
5113 }
5114 run_test 48d "Access removed parent subdir (should return errors)"
5115
5116 test_48e() { # bug 4134
5117         #lctl set_param debug=-1
5118         #set -vx
5119         rm -rf $DIR/$tdir
5120         test_mkdir -p $DIR/$tdir/dir
5121         cd $DIR/$tdir/dir
5122         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5123         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5124         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5125         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5126         # On a buggy kernel addition of "touch foo" after cd .. will
5127         # produce kernel oops in lookup_hash_it
5128         touch ../foo && error "'cd ..' worked after recreate parent"
5129         cd $DIR
5130         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5131 }
5132 run_test 48e "Access to recreated parent subdir (should return errors)"
5133
5134 test_48f() {
5135         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5136                 skip "need MDS >= 2.13.55"
5137         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5138         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5139                 skip "needs different host for mdt1 mdt2"
5140         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5141
5142         $LFS mkdir -i0 $DIR/$tdir
5143         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5144
5145         for d in sub1 sub2 sub3; do
5146                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5147                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5148                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5149         done
5150
5151         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5152 }
5153 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5154
5155 test_49() { # LU-1030
5156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5157         remote_ost_nodsh && skip "remote OST with nodsh"
5158
5159         # get ost1 size - $FSNAME-OST0000
5160         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5161                 awk '{ print $4 }')
5162         # write 800M at maximum
5163         [[ $ost1_size -lt 2 ]] && ost1_size=2
5164         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5165
5166         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5167         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5168         local dd_pid=$!
5169
5170         # change max_pages_per_rpc while writing the file
5171         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5172         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5173         # loop until dd process exits
5174         while ps ax -opid | grep -wq $dd_pid; do
5175                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5176                 sleep $((RANDOM % 5 + 1))
5177         done
5178         # restore original max_pages_per_rpc
5179         $LCTL set_param $osc1_mppc=$orig_mppc
5180         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5181 }
5182 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5183
5184 test_50() {
5185         # bug 1485
5186         test_mkdir $DIR/$tdir
5187         cd $DIR/$tdir
5188         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5189 }
5190 run_test 50 "special situations: /proc symlinks  ==============="
5191
5192 test_51a() {    # was test_51
5193         # bug 1516 - create an empty entry right after ".." then split dir
5194         test_mkdir -c1 $DIR/$tdir
5195         touch $DIR/$tdir/foo
5196         $MCREATE $DIR/$tdir/bar
5197         rm $DIR/$tdir/foo
5198         createmany -m $DIR/$tdir/longfile 201
5199         FNUM=202
5200         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5201                 $MCREATE $DIR/$tdir/longfile$FNUM
5202                 FNUM=$(($FNUM + 1))
5203                 echo -n "+"
5204         done
5205         echo
5206         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5207 }
5208 run_test 51a "special situations: split htree with empty entry =="
5209
5210 cleanup_print_lfs_df () {
5211         trap 0
5212         $LFS df
5213         $LFS df -i
5214 }
5215
5216 test_51b() {
5217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5218
5219         local dir=$DIR/$tdir
5220         local nrdirs=$((65536 + 100))
5221
5222         # cleanup the directory
5223         rm -fr $dir
5224
5225         test_mkdir -c1 $dir
5226
5227         $LFS df
5228         $LFS df -i
5229         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5230         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5231         [[ $numfree -lt $nrdirs ]] &&
5232                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5233
5234         # need to check free space for the directories as well
5235         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5236         numfree=$(( blkfree / $(fs_inode_ksize) ))
5237         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5238
5239         trap cleanup_print_lfs_df EXIT
5240
5241         # create files
5242         createmany -d $dir/d $nrdirs || {
5243                 unlinkmany $dir/d $nrdirs
5244                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5245         }
5246
5247         # really created :
5248         nrdirs=$(ls -U $dir | wc -l)
5249
5250         # unlink all but 100 subdirectories, then check it still works
5251         local left=100
5252         local delete=$((nrdirs - left))
5253
5254         $LFS df
5255         $LFS df -i
5256
5257         # for ldiskfs the nlink count should be 1, but this is OSD specific
5258         # and so this is listed for informational purposes only
5259         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5260         unlinkmany -d $dir/d $delete ||
5261                 error "unlink of first $delete subdirs failed"
5262
5263         echo "nlink between: $(stat -c %h $dir)"
5264         local found=$(ls -U $dir | wc -l)
5265         [ $found -ne $left ] &&
5266                 error "can't find subdirs: found only $found, expected $left"
5267
5268         unlinkmany -d $dir/d $delete $left ||
5269                 error "unlink of second $left subdirs failed"
5270         # regardless of whether the backing filesystem tracks nlink accurately
5271         # or not, the nlink count shouldn't be more than "." and ".." here
5272         local after=$(stat -c %h $dir)
5273         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5274                 echo "nlink after: $after"
5275
5276         cleanup_print_lfs_df
5277 }
5278 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5279
5280 test_51d() {
5281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5282         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5283
5284         test_mkdir $DIR/$tdir
5285         createmany -o $DIR/$tdir/t- 1000
5286         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5287         for N in $(seq 0 $((OSTCOUNT - 1))); do
5288                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5289                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5290                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5291                         '($1 == '$N') { objs += 1 } \
5292                         END { printf("%0.0f", objs) }')
5293                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5294         done
5295         unlinkmany $DIR/$tdir/t- 1000
5296
5297         NLAST=0
5298         for N in $(seq 1 $((OSTCOUNT - 1))); do
5299                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5300                         error "OST $N has less objects vs OST $NLAST" \
5301                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5302                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5303                         error "OST $N has less objects vs OST $NLAST" \
5304                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5305
5306                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5307                         error "OST $N has less #0 objects vs OST $NLAST" \
5308                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5309                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5310                         error "OST $N has less #0 objects vs OST $NLAST" \
5311                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5312                 NLAST=$N
5313         done
5314         rm -f $TMP/$tfile
5315 }
5316 run_test 51d "check object distribution"
5317
5318 test_51e() {
5319         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5320                 skip_env "ldiskfs only test"
5321         fi
5322
5323         test_mkdir -c1 $DIR/$tdir
5324         test_mkdir -c1 $DIR/$tdir/d0
5325
5326         touch $DIR/$tdir/d0/foo
5327         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5328                 error "file exceed 65000 nlink limit!"
5329         unlinkmany $DIR/$tdir/d0/f- 65001
5330         return 0
5331 }
5332 run_test 51e "check file nlink limit"
5333
5334 test_51f() {
5335         test_mkdir $DIR/$tdir
5336
5337         local max=100000
5338         local ulimit_old=$(ulimit -n)
5339         local spare=20 # number of spare fd's for scripts/libraries, etc.
5340         local mdt=$($LFS getstripe -m $DIR/$tdir)
5341         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5342
5343         echo "MDT$mdt numfree=$numfree, max=$max"
5344         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5345         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5346                 while ! ulimit -n $((numfree + spare)); do
5347                         numfree=$((numfree * 3 / 4))
5348                 done
5349                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5350         else
5351                 echo "left ulimit at $ulimit_old"
5352         fi
5353
5354         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5355                 unlinkmany $DIR/$tdir/f $numfree
5356                 error "create+open $numfree files in $DIR/$tdir failed"
5357         }
5358         ulimit -n $ulimit_old
5359
5360         # if createmany exits at 120s there will be fewer than $numfree files
5361         unlinkmany $DIR/$tdir/f $numfree || true
5362 }
5363 run_test 51f "check many open files limit"
5364
5365 test_52a() {
5366         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5367         test_mkdir $DIR/$tdir
5368         touch $DIR/$tdir/foo
5369         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5370         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5371         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5372         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5373         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5374                                         error "link worked"
5375         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5376         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5377         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5378                                                      error "lsattr"
5379         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5380         cp -r $DIR/$tdir $TMP/
5381         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5382 }
5383 run_test 52a "append-only flag test (should return errors)"
5384
5385 test_52b() {
5386         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5387         test_mkdir $DIR/$tdir
5388         touch $DIR/$tdir/foo
5389         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5390         cat test > $DIR/$tdir/foo && error "cat test worked"
5391         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5392         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5393         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5394                                         error "link worked"
5395         echo foo >> $DIR/$tdir/foo && error "echo worked"
5396         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5397         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5398         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5399         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5400                                                         error "lsattr"
5401         chattr -i $DIR/$tdir/foo || error "chattr failed"
5402
5403         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5404 }
5405 run_test 52b "immutable flag test (should return errors) ======="
5406
5407 test_53() {
5408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5409         remote_mds_nodsh && skip "remote MDS with nodsh"
5410         remote_ost_nodsh && skip "remote OST with nodsh"
5411
5412         local param
5413         local param_seq
5414         local ostname
5415         local mds_last
5416         local mds_last_seq
5417         local ost_last
5418         local ost_last_seq
5419         local ost_last_id
5420         local ostnum
5421         local node
5422         local found=false
5423         local support_last_seq=true
5424
5425         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5426                 support_last_seq=false
5427
5428         # only test MDT0000
5429         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5430         local value
5431         for value in $(do_facet $SINGLEMDS \
5432                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5433                 param=$(echo ${value[0]} | cut -d "=" -f1)
5434                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5435
5436                 if $support_last_seq; then
5437                         param_seq=$(echo $param |
5438                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5439                         mds_last_seq=$(do_facet $SINGLEMDS \
5440                                        $LCTL get_param -n $param_seq)
5441                 fi
5442                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5443
5444                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5445                 node=$(facet_active_host ost$((ostnum+1)))
5446                 param="obdfilter.$ostname.last_id"
5447                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5448                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5449                         ost_last_id=$ost_last
5450
5451                         if $support_last_seq; then
5452                                 ost_last_id=$(echo $ost_last |
5453                                               awk -F':' '{print $2}' |
5454                                               sed -e "s/^0x//g")
5455                                 ost_last_seq=$(echo $ost_last |
5456                                                awk -F':' '{print $1}')
5457                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5458                         fi
5459
5460                         if [[ $ost_last_id != $mds_last ]]; then
5461                                 error "$ost_last_id != $mds_last"
5462                         else
5463                                 found=true
5464                                 break
5465                         fi
5466                 done
5467         done
5468         $found || error "can not match last_seq/last_id for $mdtosc"
5469         return 0
5470 }
5471 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5472
5473 test_54a() {
5474         perl -MSocket -e ';' || skip "no Socket perl module installed"
5475
5476         $SOCKETSERVER $DIR/socket ||
5477                 error "$SOCKETSERVER $DIR/socket failed: $?"
5478         $SOCKETCLIENT $DIR/socket ||
5479                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5480         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5481 }
5482 run_test 54a "unix domain socket test =========================="
5483
5484 test_54b() {
5485         f="$DIR/f54b"
5486         mknod $f c 1 3
5487         chmod 0666 $f
5488         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5489 }
5490 run_test 54b "char device works in lustre ======================"
5491
5492 find_loop_dev() {
5493         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5494         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5495         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5496
5497         for i in $(seq 3 7); do
5498                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5499                 LOOPDEV=$LOOPBASE$i
5500                 LOOPNUM=$i
5501                 break
5502         done
5503 }
5504
5505 cleanup_54c() {
5506         local rc=0
5507         loopdev="$DIR/loop54c"
5508
5509         trap 0
5510         $UMOUNT $DIR/$tdir || rc=$?
5511         losetup -d $loopdev || true
5512         losetup -d $LOOPDEV || true
5513         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5514         return $rc
5515 }
5516
5517 test_54c() {
5518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5519
5520         loopdev="$DIR/loop54c"
5521
5522         find_loop_dev
5523         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5524         trap cleanup_54c EXIT
5525         mknod $loopdev b 7 $LOOPNUM
5526         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5527         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5528         losetup $loopdev $DIR/$tfile ||
5529                 error "can't set up $loopdev for $DIR/$tfile"
5530         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5531         test_mkdir $DIR/$tdir
5532         mount -t ext2 $loopdev $DIR/$tdir ||
5533                 error "error mounting $loopdev on $DIR/$tdir"
5534         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5535                 error "dd write"
5536         df $DIR/$tdir
5537         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5538                 error "dd read"
5539         cleanup_54c
5540 }
5541 run_test 54c "block device works in lustre ====================="
5542
5543 test_54d() {
5544         f="$DIR/f54d"
5545         string="aaaaaa"
5546         mknod $f p
5547         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5548 }
5549 run_test 54d "fifo device works in lustre ======================"
5550
5551 test_54e() {
5552         f="$DIR/f54e"
5553         string="aaaaaa"
5554         cp -aL /dev/console $f
5555         echo $string > $f || error "echo $string to $f failed"
5556 }
5557 run_test 54e "console/tty device works in lustre ======================"
5558
5559 test_56a() {
5560         local numfiles=3
5561         local dir=$DIR/$tdir
5562
5563         rm -rf $dir
5564         test_mkdir -p $dir/dir
5565         for i in $(seq $numfiles); do
5566                 touch $dir/file$i
5567                 touch $dir/dir/file$i
5568         done
5569
5570         local numcomp=$($LFS getstripe --component-count $dir)
5571
5572         [[ $numcomp == 0 ]] && numcomp=1
5573
5574         # test lfs getstripe with --recursive
5575         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5576
5577         [[ $filenum -eq $((numfiles * 2)) ]] ||
5578                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5579         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5580         [[ $filenum -eq $numfiles ]] ||
5581                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5582         echo "$LFS getstripe showed obdidx or l_ost_idx"
5583
5584         # test lfs getstripe with file instead of dir
5585         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5586         [[ $filenum -eq 1 ]] ||
5587                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5588         echo "$LFS getstripe file1 passed"
5589
5590         #test lfs getstripe with --verbose
5591         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5592         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5593                 error "$LFS getstripe --verbose $dir: "\
5594                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5595         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5596                 error "$LFS getstripe $dir: showed lmm_magic"
5597
5598         #test lfs getstripe with -v prints lmm_fid
5599         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5600         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5601                 error "$LFS getstripe -v $dir: "\
5602                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5603         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5604                 error "$LFS getstripe $dir: showed lmm_fid by default"
5605         echo "$LFS getstripe --verbose passed"
5606
5607         #check for FID information
5608         local fid1=$($LFS getstripe --fid $dir/file1)
5609         local fid2=$($LFS getstripe --verbose $dir/file1 |
5610                      awk '/lmm_fid: / { print $2; exit; }')
5611         local fid3=$($LFS path2fid $dir/file1)
5612
5613         [ "$fid1" != "$fid2" ] &&
5614                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5615         [ "$fid1" != "$fid3" ] &&
5616                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5617         echo "$LFS getstripe --fid passed"
5618
5619         #test lfs getstripe with --obd
5620         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5621                 error "$LFS getstripe --obd wrong_uuid: should return error"
5622
5623         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5624
5625         local ostidx=1
5626         local obduuid=$(ostuuid_from_index $ostidx)
5627         local found=$($LFS getstripe -r --obd $obduuid $dir |
5628                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5629
5630         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5631         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5632                 ((filenum--))
5633         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5634                 ((filenum--))
5635
5636         [[ $found -eq $filenum ]] ||
5637                 error "$LFS getstripe --obd: found $found expect $filenum"
5638         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5639                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5640                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5641                 error "$LFS getstripe --obd: should not show file on other obd"
5642         echo "$LFS getstripe --obd passed"
5643 }
5644 run_test 56a "check $LFS getstripe"
5645
5646 test_56b() {
5647         local dir=$DIR/$tdir
5648         local numdirs=3
5649
5650         test_mkdir $dir
5651         for i in $(seq $numdirs); do
5652                 test_mkdir $dir/dir$i
5653         done
5654
5655         # test lfs getdirstripe default mode is non-recursion, which is
5656         # different from lfs getstripe
5657         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5658
5659         [[ $dircnt -eq 1 ]] ||
5660                 error "$LFS getdirstripe: found $dircnt, not 1"
5661         dircnt=$($LFS getdirstripe --recursive $dir |
5662                 grep -c lmv_stripe_count)
5663         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5664                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5665 }
5666 run_test 56b "check $LFS getdirstripe"
5667
5668 test_56c() {
5669         remote_ost_nodsh && skip "remote OST with nodsh"
5670
5671         local ost_idx=0
5672         local ost_name=$(ostname_from_index $ost_idx)
5673         local old_status=$(ost_dev_status $ost_idx)
5674         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5675
5676         [[ -z "$old_status" ]] ||
5677                 skip_env "OST $ost_name is in $old_status status"
5678
5679         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5680         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5681                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5682         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5683                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5684                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5685         fi
5686
5687         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5688                 error "$LFS df -v showing inactive devices"
5689         sleep_maxage
5690
5691         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5692
5693         [[ "$new_status" =~ "D" ]] ||
5694                 error "$ost_name status is '$new_status', missing 'D'"
5695         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5696                 [[ "$new_status" =~ "N" ]] ||
5697                         error "$ost_name status is '$new_status', missing 'N'"
5698         fi
5699         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5700                 [[ "$new_status" =~ "f" ]] ||
5701                         error "$ost_name status is '$new_status', missing 'f'"
5702         fi
5703
5704         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5705         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5706                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5707         [[ -z "$p" ]] && restore_lustre_params < $p || true
5708         sleep_maxage
5709
5710         new_status=$(ost_dev_status $ost_idx)
5711         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5712                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5713         # can't check 'f' as devices may actually be on flash
5714 }
5715 run_test 56c "check 'lfs df' showing device status"
5716
5717 test_56d() {
5718         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5719         local osts=$($LFS df -v $MOUNT | grep -c OST)
5720
5721         $LFS df $MOUNT
5722
5723         (( mdts == MDSCOUNT )) ||
5724                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5725         (( osts == OSTCOUNT )) ||
5726                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5727 }
5728 run_test 56d "'lfs df -v' prints only configured devices"
5729
5730 NUMFILES=3
5731 NUMDIRS=3
5732 setup_56() {
5733         local local_tdir="$1"
5734         local local_numfiles="$2"
5735         local local_numdirs="$3"
5736         local dir_params="$4"
5737         local dir_stripe_params="$5"
5738
5739         if [ ! -d "$local_tdir" ] ; then
5740                 test_mkdir -p $dir_stripe_params $local_tdir
5741                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5742                 for i in $(seq $local_numfiles) ; do
5743                         touch $local_tdir/file$i
5744                 done
5745                 for i in $(seq $local_numdirs) ; do
5746                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5747                         for j in $(seq $local_numfiles) ; do
5748                                 touch $local_tdir/dir$i/file$j
5749                         done
5750                 done
5751         fi
5752 }
5753
5754 setup_56_special() {
5755         local local_tdir=$1
5756         local local_numfiles=$2
5757         local local_numdirs=$3
5758
5759         setup_56 $local_tdir $local_numfiles $local_numdirs
5760
5761         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5762                 for i in $(seq $local_numfiles) ; do
5763                         mknod $local_tdir/loop${i}b b 7 $i
5764                         mknod $local_tdir/null${i}c c 1 3
5765                         ln -s $local_tdir/file1 $local_tdir/link${i}
5766                 done
5767                 for i in $(seq $local_numdirs) ; do
5768                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5769                         mknod $local_tdir/dir$i/null${i}c c 1 3
5770                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5771                 done
5772         fi
5773 }
5774
5775 test_56g() {
5776         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5777         local expected=$(($NUMDIRS + 2))
5778
5779         setup_56 $dir $NUMFILES $NUMDIRS
5780
5781         # test lfs find with -name
5782         for i in $(seq $NUMFILES) ; do
5783                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5784
5785                 [ $nums -eq $expected ] ||
5786                         error "lfs find -name '*$i' $dir wrong: "\
5787                               "found $nums, expected $expected"
5788         done
5789 }
5790 run_test 56g "check lfs find -name"
5791
5792 test_56h() {
5793         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5794         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5795
5796         setup_56 $dir $NUMFILES $NUMDIRS
5797
5798         # test lfs find with ! -name
5799         for i in $(seq $NUMFILES) ; do
5800                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5801
5802                 [ $nums -eq $expected ] ||
5803                         error "lfs find ! -name '*$i' $dir wrong: "\
5804                               "found $nums, expected $expected"
5805         done
5806 }
5807 run_test 56h "check lfs find ! -name"
5808
5809 test_56i() {
5810         local dir=$DIR/$tdir
5811
5812         test_mkdir $dir
5813
5814         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5815         local out=$($cmd)
5816
5817         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5818 }
5819 run_test 56i "check 'lfs find -ost UUID' skips directories"
5820
5821 test_56j() {
5822         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5823
5824         setup_56_special $dir $NUMFILES $NUMDIRS
5825
5826         local expected=$((NUMDIRS + 1))
5827         local cmd="$LFS find -type d $dir"
5828         local nums=$($cmd | wc -l)
5829
5830         [ $nums -eq $expected ] ||
5831                 error "'$cmd' wrong: found $nums, expected $expected"
5832 }
5833 run_test 56j "check lfs find -type d"
5834
5835 test_56k() {
5836         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5837
5838         setup_56_special $dir $NUMFILES $NUMDIRS
5839
5840         local expected=$(((NUMDIRS + 1) * NUMFILES))
5841         local cmd="$LFS find -type f $dir"
5842         local nums=$($cmd | wc -l)
5843
5844         [ $nums -eq $expected ] ||
5845                 error "'$cmd' wrong: found $nums, expected $expected"
5846 }
5847 run_test 56k "check lfs find -type f"
5848
5849 test_56l() {
5850         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5851
5852         setup_56_special $dir $NUMFILES $NUMDIRS
5853
5854         local expected=$((NUMDIRS + NUMFILES))
5855         local cmd="$LFS find -type b $dir"
5856         local nums=$($cmd | wc -l)
5857
5858         [ $nums -eq $expected ] ||
5859                 error "'$cmd' wrong: found $nums, expected $expected"
5860 }
5861 run_test 56l "check lfs find -type b"
5862
5863 test_56m() {
5864         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5865
5866         setup_56_special $dir $NUMFILES $NUMDIRS
5867
5868         local expected=$((NUMDIRS + NUMFILES))
5869         local cmd="$LFS find -type c $dir"
5870         local nums=$($cmd | wc -l)
5871         [ $nums -eq $expected ] ||
5872                 error "'$cmd' wrong: found $nums, expected $expected"
5873 }
5874 run_test 56m "check lfs find -type c"
5875
5876 test_56n() {
5877         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5878         setup_56_special $dir $NUMFILES $NUMDIRS
5879
5880         local expected=$((NUMDIRS + NUMFILES))
5881         local cmd="$LFS find -type l $dir"
5882         local nums=$($cmd | wc -l)
5883
5884         [ $nums -eq $expected ] ||
5885                 error "'$cmd' wrong: found $nums, expected $expected"
5886 }
5887 run_test 56n "check lfs find -type l"
5888
5889 test_56o() {
5890         local dir=$DIR/$tdir
5891
5892         setup_56 $dir $NUMFILES $NUMDIRS
5893         utime $dir/file1 > /dev/null || error "utime (1)"
5894         utime $dir/file2 > /dev/null || error "utime (2)"
5895         utime $dir/dir1 > /dev/null || error "utime (3)"
5896         utime $dir/dir2 > /dev/null || error "utime (4)"
5897         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5898         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5899
5900         local expected=4
5901         local nums=$($LFS find -mtime +0 $dir | wc -l)
5902
5903         [ $nums -eq $expected ] ||
5904                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5905
5906         expected=12
5907         cmd="$LFS find -mtime 0 $dir"
5908         nums=$($cmd | wc -l)
5909         [ $nums -eq $expected ] ||
5910                 error "'$cmd' wrong: found $nums, expected $expected"
5911 }
5912 run_test 56o "check lfs find -mtime for old files"
5913
5914 test_56ob() {
5915         local dir=$DIR/$tdir
5916         local expected=1
5917         local count=0
5918
5919         # just to make sure there is something that won't be found
5920         test_mkdir $dir
5921         touch $dir/$tfile.now
5922
5923         for age in year week day hour min; do
5924                 count=$((count + 1))
5925
5926                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5927                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5928                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5929
5930                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5931                 local nums=$($cmd | wc -l)
5932                 [ $nums -eq $expected ] ||
5933                         error "'$cmd' wrong: found $nums, expected $expected"
5934
5935                 cmd="$LFS find $dir -atime $count${age:0:1}"
5936                 nums=$($cmd | wc -l)
5937                 [ $nums -eq $expected ] ||
5938                         error "'$cmd' wrong: found $nums, expected $expected"
5939         done
5940
5941         sleep 2
5942         cmd="$LFS find $dir -ctime +1s -type f"
5943         nums=$($cmd | wc -l)
5944         (( $nums == $count * 2 + 1)) ||
5945                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
5946 }
5947 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5948
5949 test_newerXY_base() {
5950         local x=$1
5951         local y=$2
5952         local dir=$DIR/$tdir
5953         local ref
5954         local negref
5955
5956         if [ $y == "t" ]; then
5957                 if [ $x == "b" ]; then
5958                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5959                 else
5960                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5961                 fi
5962         else
5963                 ref=$DIR/$tfile.newer.$x$y
5964                 touch $ref || error "touch $ref failed"
5965         fi
5966         sleep 2
5967         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5968         sleep 2
5969         if [ $y == "t" ]; then
5970                 if [ $x == "b" ]; then
5971                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5972                 else
5973                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5974                 fi
5975         else
5976                 negref=$DIR/$tfile.negnewer.$x$y
5977                 touch $negref || error "touch $negref failed"
5978         fi
5979
5980         local cmd="$LFS find $dir -newer$x$y $ref"
5981         local nums=$(eval $cmd | wc -l)
5982         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5983
5984         [ $nums -eq $expected ] ||
5985                 error "'$cmd' wrong: found $nums, expected $expected"
5986
5987         cmd="$LFS find $dir ! -newer$x$y $negref"
5988         nums=$(eval $cmd | wc -l)
5989         [ $nums -eq $expected ] ||
5990                 error "'$cmd' wrong: found $nums, expected $expected"
5991
5992         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
5993         nums=$(eval $cmd | wc -l)
5994         [ $nums -eq $expected ] ||
5995                 error "'$cmd' wrong: found $nums, expected $expected"
5996
5997         rm -rf $DIR/*
5998 }
5999
6000 test_56oc() {
6001         test_newerXY_base "b" "t"
6002         test_newerXY_base "a" "a"
6003         test_newerXY_base "a" "m"
6004         test_newerXY_base "a" "c"
6005         test_newerXY_base "m" "a"
6006         test_newerXY_base "m" "m"
6007         test_newerXY_base "m" "c"
6008         test_newerXY_base "c" "a"
6009         test_newerXY_base "c" "m"
6010         test_newerXY_base "c" "c"
6011         test_newerXY_base "b" "b"
6012         test_newerXY_base "a" "t"
6013         test_newerXY_base "m" "t"
6014         test_newerXY_base "c" "t"
6015         test_newerXY_base "b" "t"
6016 }
6017 run_test 56oc "check lfs find -newerXY work"
6018
6019 btime_supported() {
6020         local dir=$DIR/$tdir
6021         local rc
6022
6023         mkdir -p $dir
6024         touch $dir/$tfile
6025         $LFS find $dir -btime -1d -type f
6026         rc=$?
6027         rm -rf $dir
6028         return $rc
6029 }
6030
6031 test_56od() {
6032         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6033                 ! btime_supported && skip "btime unsupported on MDS"
6034
6035         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6036                 ! btime_supported && skip "btime unsupported on clients"
6037
6038         local dir=$DIR/$tdir
6039         local ref=$DIR/$tfile.ref
6040         local negref=$DIR/$tfile.negref
6041
6042         mkdir $dir || error "mkdir $dir failed"
6043         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6044         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6045         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6046         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6047         touch $ref || error "touch $ref failed"
6048         # sleep 3 seconds at least
6049         sleep 3
6050
6051         local before=$(do_facet mds1 date +%s)
6052         local skew=$(($(date +%s) - before + 1))
6053
6054         if (( skew < 0 && skew > -5 )); then
6055                 sleep $((0 - skew + 1))
6056                 skew=0
6057         fi
6058
6059         # Set the dir stripe params to limit files all on MDT0,
6060         # otherwise we need to calc the max clock skew between
6061         # the client and MDTs.
6062         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6063         sleep 2
6064         touch $negref || error "touch $negref failed"
6065
6066         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6067         local nums=$($cmd | wc -l)
6068         local expected=$(((NUMFILES + 1) * NUMDIRS))
6069
6070         [ $nums -eq $expected ] ||
6071                 error "'$cmd' wrong: found $nums, expected $expected"
6072
6073         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6074         nums=$($cmd | wc -l)
6075         expected=$((NUMFILES + 1))
6076         [ $nums -eq $expected ] ||
6077                 error "'$cmd' wrong: found $nums, expected $expected"
6078
6079         [ $skew -lt 0 ] && return
6080
6081         local after=$(do_facet mds1 date +%s)
6082         local age=$((after - before + 1 + skew))
6083
6084         cmd="$LFS find $dir -btime -${age}s -type f"
6085         nums=$($cmd | wc -l)
6086         expected=$(((NUMFILES + 1) * NUMDIRS))
6087
6088         echo "Clock skew between client and server: $skew, age:$age"
6089         [ $nums -eq $expected ] ||
6090                 error "'$cmd' wrong: found $nums, expected $expected"
6091
6092         expected=$(($NUMDIRS + 1))
6093         cmd="$LFS find $dir -btime -${age}s -type d"
6094         nums=$($cmd | wc -l)
6095         [ $nums -eq $expected ] ||
6096                 error "'$cmd' wrong: found $nums, expected $expected"
6097         rm -f $ref $negref || error "Failed to remove $ref $negref"
6098 }
6099 run_test 56od "check lfs find -btime with units"
6100
6101 test_56p() {
6102         [ $RUNAS_ID -eq $UID ] &&
6103                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6104
6105         local dir=$DIR/$tdir
6106
6107         setup_56 $dir $NUMFILES $NUMDIRS
6108         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6109
6110         local expected=$NUMFILES
6111         local cmd="$LFS find -uid $RUNAS_ID $dir"
6112         local nums=$($cmd | wc -l)
6113
6114         [ $nums -eq $expected ] ||
6115                 error "'$cmd' wrong: found $nums, expected $expected"
6116
6117         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6118         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6119         nums=$($cmd | wc -l)
6120         [ $nums -eq $expected ] ||
6121                 error "'$cmd' wrong: found $nums, expected $expected"
6122 }
6123 run_test 56p "check lfs find -uid and ! -uid"
6124
6125 test_56q() {
6126         [ $RUNAS_ID -eq $UID ] &&
6127                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6128
6129         local dir=$DIR/$tdir
6130
6131         setup_56 $dir $NUMFILES $NUMDIRS
6132         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6133
6134         local expected=$NUMFILES
6135         local cmd="$LFS find -gid $RUNAS_GID $dir"
6136         local nums=$($cmd | wc -l)
6137
6138         [ $nums -eq $expected ] ||
6139                 error "'$cmd' wrong: found $nums, expected $expected"
6140
6141         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6142         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6143         nums=$($cmd | wc -l)
6144         [ $nums -eq $expected ] ||
6145                 error "'$cmd' wrong: found $nums, expected $expected"
6146 }
6147 run_test 56q "check lfs find -gid and ! -gid"
6148
6149 test_56r() {
6150         local dir=$DIR/$tdir
6151
6152         setup_56 $dir $NUMFILES $NUMDIRS
6153
6154         local expected=12
6155         local cmd="$LFS find -size 0 -type f -lazy $dir"
6156         local nums=$($cmd | wc -l)
6157
6158         [ $nums -eq $expected ] ||
6159                 error "'$cmd' wrong: found $nums, expected $expected"
6160         cmd="$LFS find -size 0 -type f $dir"
6161         nums=$($cmd | wc -l)
6162         [ $nums -eq $expected ] ||
6163                 error "'$cmd' wrong: found $nums, expected $expected"
6164
6165         expected=0
6166         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6167         nums=$($cmd | wc -l)
6168         [ $nums -eq $expected ] ||
6169                 error "'$cmd' wrong: found $nums, expected $expected"
6170         cmd="$LFS find ! -size 0 -type f $dir"
6171         nums=$($cmd | wc -l)
6172         [ $nums -eq $expected ] ||
6173                 error "'$cmd' wrong: found $nums, expected $expected"
6174
6175         echo "test" > $dir/$tfile
6176         echo "test2" > $dir/$tfile.2 && sync
6177         expected=1
6178         cmd="$LFS find -size 5 -type f -lazy $dir"
6179         nums=$($cmd | wc -l)
6180         [ $nums -eq $expected ] ||
6181                 error "'$cmd' wrong: found $nums, expected $expected"
6182         cmd="$LFS find -size 5 -type f $dir"
6183         nums=$($cmd | wc -l)
6184         [ $nums -eq $expected ] ||
6185                 error "'$cmd' wrong: found $nums, expected $expected"
6186
6187         expected=1
6188         cmd="$LFS find -size +5 -type f -lazy $dir"
6189         nums=$($cmd | wc -l)
6190         [ $nums -eq $expected ] ||
6191                 error "'$cmd' wrong: found $nums, expected $expected"
6192         cmd="$LFS find -size +5 -type f $dir"
6193         nums=$($cmd | wc -l)
6194         [ $nums -eq $expected ] ||
6195                 error "'$cmd' wrong: found $nums, expected $expected"
6196
6197         expected=2
6198         cmd="$LFS find -size +0 -type f -lazy $dir"
6199         nums=$($cmd | wc -l)
6200         [ $nums -eq $expected ] ||
6201                 error "'$cmd' wrong: found $nums, expected $expected"
6202         cmd="$LFS find -size +0 -type f $dir"
6203         nums=$($cmd | wc -l)
6204         [ $nums -eq $expected ] ||
6205                 error "'$cmd' wrong: found $nums, expected $expected"
6206
6207         expected=2
6208         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6209         nums=$($cmd | wc -l)
6210         [ $nums -eq $expected ] ||
6211                 error "'$cmd' wrong: found $nums, expected $expected"
6212         cmd="$LFS find ! -size -5 -type f $dir"
6213         nums=$($cmd | wc -l)
6214         [ $nums -eq $expected ] ||
6215                 error "'$cmd' wrong: found $nums, expected $expected"
6216
6217         expected=12
6218         cmd="$LFS find -size -5 -type f -lazy $dir"
6219         nums=$($cmd | wc -l)
6220         [ $nums -eq $expected ] ||
6221                 error "'$cmd' wrong: found $nums, expected $expected"
6222         cmd="$LFS find -size -5 -type f $dir"
6223         nums=$($cmd | wc -l)
6224         [ $nums -eq $expected ] ||
6225                 error "'$cmd' wrong: found $nums, expected $expected"
6226 }
6227 run_test 56r "check lfs find -size works"
6228
6229 test_56ra_sub() {
6230         local expected=$1
6231         local glimpses=$2
6232         local cmd="$3"
6233
6234         cancel_lru_locks $OSC
6235
6236         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6237         local nums=$($cmd | wc -l)
6238
6239         [ $nums -eq $expected ] ||
6240                 error "'$cmd' wrong: found $nums, expected $expected"
6241
6242         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6243
6244         if (( rpcs_before + glimpses != rpcs_after )); then
6245                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6246                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6247
6248                 if [[ $glimpses == 0 ]]; then
6249                         error "'$cmd' should not send glimpse RPCs to OST"
6250                 else
6251                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6252                 fi
6253         fi
6254 }
6255
6256 test_56ra() {
6257         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6258                 skip "MDS < 2.12.58 doesn't return LSOM data"
6259         local dir=$DIR/$tdir
6260
6261         [[ $OSC == "mdc" ]] && skip "DoM files" && return
6262
6263         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6264         # open and close all files to ensure LSOM is updated
6265         cancel_lru_locks $OSC
6266         find $dir -type f | xargs cat > /dev/null
6267
6268         #   expect_found  glimpse_rpcs  command_to_run
6269         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6270         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6271         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6272         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6273
6274         echo "test" > $dir/$tfile
6275         echo "test2" > $dir/$tfile.2 && sync
6276         cancel_lru_locks $OSC
6277         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6278
6279         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6280         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6281         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6282         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6283
6284         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6285         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6286         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6287         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6288         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6289         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6290 }
6291 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6292
6293 test_56rb() {
6294         local dir=$DIR/$tdir
6295         local tmp=$TMP/$tfile.log
6296         local mdt_idx;
6297
6298         test_mkdir -p $dir || error "failed to mkdir $dir"
6299         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6300                 error "failed to setstripe $dir/$tfile"
6301         mdt_idx=$($LFS getdirstripe -i $dir)
6302         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6303
6304         stack_trap "rm -f $tmp" EXIT
6305         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6306         ! grep -q obd_uuid $tmp ||
6307                 error "failed to find --size +100K --ost 0 $dir"
6308         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6309         ! grep -q obd_uuid $tmp ||
6310                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6311 }
6312 run_test 56rb "check lfs find --size --ost/--mdt works"
6313
6314 test_56s() { # LU-611 #LU-9369
6315         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6316
6317         local dir=$DIR/$tdir
6318         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6319
6320         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6321         for i in $(seq $NUMDIRS); do
6322                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6323         done
6324
6325         local expected=$NUMDIRS
6326         local cmd="$LFS find -c $OSTCOUNT $dir"
6327         local nums=$($cmd | wc -l)
6328
6329         [ $nums -eq $expected ] || {
6330                 $LFS getstripe -R $dir
6331                 error "'$cmd' wrong: found $nums, expected $expected"
6332         }
6333
6334         expected=$((NUMDIRS + onestripe))
6335         cmd="$LFS find -stripe-count +0 -type f $dir"
6336         nums=$($cmd | wc -l)
6337         [ $nums -eq $expected ] || {
6338                 $LFS getstripe -R $dir
6339                 error "'$cmd' wrong: found $nums, expected $expected"
6340         }
6341
6342         expected=$onestripe
6343         cmd="$LFS find -stripe-count 1 -type f $dir"
6344         nums=$($cmd | wc -l)
6345         [ $nums -eq $expected ] || {
6346                 $LFS getstripe -R $dir
6347                 error "'$cmd' wrong: found $nums, expected $expected"
6348         }
6349
6350         cmd="$LFS find -stripe-count -2 -type f $dir"
6351         nums=$($cmd | wc -l)
6352         [ $nums -eq $expected ] || {
6353                 $LFS getstripe -R $dir
6354                 error "'$cmd' wrong: found $nums, expected $expected"
6355         }
6356
6357         expected=0
6358         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6359         nums=$($cmd | wc -l)
6360         [ $nums -eq $expected ] || {
6361                 $LFS getstripe -R $dir
6362                 error "'$cmd' wrong: found $nums, expected $expected"
6363         }
6364 }
6365 run_test 56s "check lfs find -stripe-count works"
6366
6367 test_56t() { # LU-611 #LU-9369
6368         local dir=$DIR/$tdir
6369
6370         setup_56 $dir 0 $NUMDIRS
6371         for i in $(seq $NUMDIRS); do
6372                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6373         done
6374
6375         local expected=$NUMDIRS
6376         local cmd="$LFS find -S 8M $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         rm -rf $dir
6384
6385         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6386
6387         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6388
6389         expected=$(((NUMDIRS + 1) * NUMFILES))
6390         cmd="$LFS find -stripe-size 512k -type f $dir"
6391         nums=$($cmd | wc -l)
6392         [ $nums -eq $expected ] ||
6393                 error "'$cmd' wrong: found $nums, expected $expected"
6394
6395         cmd="$LFS find -stripe-size +320k -type f $dir"
6396         nums=$($cmd | wc -l)
6397         [ $nums -eq $expected ] ||
6398                 error "'$cmd' wrong: found $nums, expected $expected"
6399
6400         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6401         cmd="$LFS find -stripe-size +200k -type f $dir"
6402         nums=$($cmd | wc -l)
6403         [ $nums -eq $expected ] ||
6404                 error "'$cmd' wrong: found $nums, expected $expected"
6405
6406         cmd="$LFS find -stripe-size -640k -type f $dir"
6407         nums=$($cmd | wc -l)
6408         [ $nums -eq $expected ] ||
6409                 error "'$cmd' wrong: found $nums, expected $expected"
6410
6411         expected=4
6412         cmd="$LFS find -stripe-size 256k -type f $dir"
6413         nums=$($cmd | wc -l)
6414         [ $nums -eq $expected ] ||
6415                 error "'$cmd' wrong: found $nums, expected $expected"
6416
6417         cmd="$LFS find -stripe-size -320k -type f $dir"
6418         nums=$($cmd | wc -l)
6419         [ $nums -eq $expected ] ||
6420                 error "'$cmd' wrong: found $nums, expected $expected"
6421
6422         expected=0
6423         cmd="$LFS find -stripe-size 1024k -type f $dir"
6424         nums=$($cmd | wc -l)
6425         [ $nums -eq $expected ] ||
6426                 error "'$cmd' wrong: found $nums, expected $expected"
6427 }
6428 run_test 56t "check lfs find -stripe-size works"
6429
6430 test_56u() { # LU-611
6431         local dir=$DIR/$tdir
6432
6433         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6434
6435         if [[ $OSTCOUNT -gt 1 ]]; then
6436                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6437                 onestripe=4
6438         else
6439                 onestripe=0
6440         fi
6441
6442         local expected=$(((NUMDIRS + 1) * NUMFILES))
6443         local cmd="$LFS find -stripe-index 0 -type f $dir"
6444         local nums=$($cmd | wc -l)
6445
6446         [ $nums -eq $expected ] ||
6447                 error "'$cmd' wrong: found $nums, expected $expected"
6448
6449         expected=$onestripe
6450         cmd="$LFS find -stripe-index 1 -type f $dir"
6451         nums=$($cmd | wc -l)
6452         [ $nums -eq $expected ] ||
6453                 error "'$cmd' wrong: found $nums, expected $expected"
6454
6455         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6456         nums=$($cmd | wc -l)
6457         [ $nums -eq $expected ] ||
6458                 error "'$cmd' wrong: found $nums, expected $expected"
6459
6460         expected=0
6461         # This should produce an error and not return any files
6462         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6463         nums=$($cmd 2>/dev/null | wc -l)
6464         [ $nums -eq $expected ] ||
6465                 error "'$cmd' wrong: found $nums, expected $expected"
6466
6467         if [[ $OSTCOUNT -gt 1 ]]; then
6468                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6469                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6470                 nums=$($cmd | wc -l)
6471                 [ $nums -eq $expected ] ||
6472                         error "'$cmd' wrong: found $nums, expected $expected"
6473         fi
6474 }
6475 run_test 56u "check lfs find -stripe-index works"
6476
6477 test_56v() {
6478         local mdt_idx=0
6479         local dir=$DIR/$tdir
6480
6481         setup_56 $dir $NUMFILES $NUMDIRS
6482
6483         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6484         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6485
6486         for file in $($LFS find -m $UUID $dir); do
6487                 file_midx=$($LFS getstripe -m $file)
6488                 [ $file_midx -eq $mdt_idx ] ||
6489                         error "lfs find -m $UUID != getstripe -m $file_midx"
6490         done
6491 }
6492 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6493
6494 test_56w() {
6495         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6497
6498         local dir=$DIR/$tdir
6499
6500         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6501
6502         local stripe_size=$($LFS getstripe -S -d $dir) ||
6503                 error "$LFS getstripe -S -d $dir failed"
6504         stripe_size=${stripe_size%% *}
6505
6506         local file_size=$((stripe_size * OSTCOUNT))
6507         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6508         local required_space=$((file_num * file_size))
6509         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6510                            head -n1)
6511         [[ $free_space -le $((required_space / 1024)) ]] &&
6512                 skip_env "need $required_space, have $free_space kbytes"
6513
6514         local dd_bs=65536
6515         local dd_count=$((file_size / dd_bs))
6516
6517         # write data into the files
6518         local i
6519         local j
6520         local file
6521
6522         for i in $(seq $NUMFILES); do
6523                 file=$dir/file$i
6524                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6525                         error "write data into $file failed"
6526         done
6527         for i in $(seq $NUMDIRS); do
6528                 for j in $(seq $NUMFILES); do
6529                         file=$dir/dir$i/file$j
6530                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6531                                 error "write data into $file failed"
6532                 done
6533         done
6534
6535         # $LFS_MIGRATE will fail if hard link migration is unsupported
6536         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6537                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6538                         error "creating links to $dir/dir1/file1 failed"
6539         fi
6540
6541         local expected=-1
6542
6543         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6544
6545         # lfs_migrate file
6546         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6547
6548         echo "$cmd"
6549         eval $cmd || error "$cmd failed"
6550
6551         check_stripe_count $dir/file1 $expected
6552
6553         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6554         then
6555                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6556                 # OST 1 if it is on OST 0. This file is small enough to
6557                 # be on only one stripe.
6558                 file=$dir/migr_1_ost
6559                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6560                         error "write data into $file failed"
6561                 local obdidx=$($LFS getstripe -i $file)
6562                 local oldmd5=$(md5sum $file)
6563                 local newobdidx=0
6564
6565                 [[ $obdidx -eq 0 ]] && newobdidx=1
6566                 cmd="$LFS migrate -i $newobdidx $file"
6567                 echo $cmd
6568                 eval $cmd || error "$cmd failed"
6569
6570                 local realobdix=$($LFS getstripe -i $file)
6571                 local newmd5=$(md5sum $file)
6572
6573                 [[ $newobdidx -ne $realobdix ]] &&
6574                         error "new OST is different (was=$obdidx, "\
6575                               "wanted=$newobdidx, got=$realobdix)"
6576                 [[ "$oldmd5" != "$newmd5" ]] &&
6577                         error "md5sum differ: $oldmd5, $newmd5"
6578         fi
6579
6580         # lfs_migrate dir
6581         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6582         echo "$cmd"
6583         eval $cmd || error "$cmd failed"
6584
6585         for j in $(seq $NUMFILES); do
6586                 check_stripe_count $dir/dir1/file$j $expected
6587         done
6588
6589         # lfs_migrate works with lfs find
6590         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6591              $LFS_MIGRATE -y -c $expected"
6592         echo "$cmd"
6593         eval $cmd || error "$cmd failed"
6594
6595         for i in $(seq 2 $NUMFILES); do
6596                 check_stripe_count $dir/file$i $expected
6597         done
6598         for i in $(seq 2 $NUMDIRS); do
6599                 for j in $(seq $NUMFILES); do
6600                 check_stripe_count $dir/dir$i/file$j $expected
6601                 done
6602         done
6603 }
6604 run_test 56w "check lfs_migrate -c stripe_count works"
6605
6606 test_56wb() {
6607         local file1=$DIR/$tdir/file1
6608         local create_pool=false
6609         local initial_pool=$($LFS getstripe -p $DIR)
6610         local pool_list=()
6611         local pool=""
6612
6613         echo -n "Creating test dir..."
6614         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6615         echo "done."
6616
6617         echo -n "Creating test file..."
6618         touch $file1 || error "cannot create file"
6619         echo "done."
6620
6621         echo -n "Detecting existing pools..."
6622         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6623
6624         if [ ${#pool_list[@]} -gt 0 ]; then
6625                 echo "${pool_list[@]}"
6626                 for thispool in "${pool_list[@]}"; do
6627                         if [[ -z "$initial_pool" ||
6628                               "$initial_pool" != "$thispool" ]]; then
6629                                 pool="$thispool"
6630                                 echo "Using existing pool '$pool'"
6631                                 break
6632                         fi
6633                 done
6634         else
6635                 echo "none detected."
6636         fi
6637         if [ -z "$pool" ]; then
6638                 pool=${POOL:-testpool}
6639                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6640                 echo -n "Creating pool '$pool'..."
6641                 create_pool=true
6642                 pool_add $pool &> /dev/null ||
6643                         error "pool_add failed"
6644                 echo "done."
6645
6646                 echo -n "Adding target to pool..."
6647                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6648                         error "pool_add_targets failed"
6649                 echo "done."
6650         fi
6651
6652         echo -n "Setting pool using -p option..."
6653         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6654                 error "migrate failed rc = $?"
6655         echo "done."
6656
6657         echo -n "Verifying test file is in pool after migrating..."
6658         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6659                 error "file was not migrated to pool $pool"
6660         echo "done."
6661
6662         echo -n "Removing test file from pool '$pool'..."
6663         # "lfs migrate $file" won't remove the file from the pool
6664         # until some striping information is changed.
6665         $LFS migrate -c 1 $file1 &> /dev/null ||
6666                 error "cannot remove from pool"
6667         [ "$($LFS getstripe -p $file1)" ] &&
6668                 error "pool still set"
6669         echo "done."
6670
6671         echo -n "Setting pool using --pool option..."
6672         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6673                 error "migrate failed rc = $?"
6674         echo "done."
6675
6676         # Clean up
6677         rm -f $file1
6678         if $create_pool; then
6679                 destroy_test_pools 2> /dev/null ||
6680                         error "destroy test pools failed"
6681         fi
6682 }
6683 run_test 56wb "check lfs_migrate pool support"
6684
6685 test_56wc() {
6686         local file1="$DIR/$tdir/file1"
6687         local parent_ssize
6688         local parent_scount
6689         local cur_ssize
6690         local cur_scount
6691         local orig_ssize
6692
6693         echo -n "Creating test dir..."
6694         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6695         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6696                 error "cannot set stripe by '-S 1M -c 1'"
6697         echo "done"
6698
6699         echo -n "Setting initial stripe for test file..."
6700         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6701                 error "cannot set stripe"
6702         cur_ssize=$($LFS getstripe -S "$file1")
6703         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6704         echo "done."
6705
6706         # File currently set to -S 512K -c 1
6707
6708         # Ensure -c and -S options are rejected when -R is set
6709         echo -n "Verifying incompatible options are detected..."
6710         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6711                 error "incompatible -c and -R options not detected"
6712         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6713                 error "incompatible -S and -R options not detected"
6714         echo "done."
6715
6716         # Ensure unrecognized options are passed through to 'lfs migrate'
6717         echo -n "Verifying -S option is passed through to lfs migrate..."
6718         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6719                 error "migration failed"
6720         cur_ssize=$($LFS getstripe -S "$file1")
6721         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6722         echo "done."
6723
6724         # File currently set to -S 1M -c 1
6725
6726         # Ensure long options are supported
6727         echo -n "Verifying long options supported..."
6728         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6729                 error "long option without argument not supported"
6730         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6731                 error "long option with argument not supported"
6732         cur_ssize=$($LFS getstripe -S "$file1")
6733         [ $cur_ssize -eq 524288 ] ||
6734                 error "migrate --stripe-size $cur_ssize != 524288"
6735         echo "done."
6736
6737         # File currently set to -S 512K -c 1
6738
6739         if [ "$OSTCOUNT" -gt 1 ]; then
6740                 echo -n "Verifying explicit stripe count can be set..."
6741                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6742                         error "migrate failed"
6743                 cur_scount=$($LFS getstripe -c "$file1")
6744                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6745                 echo "done."
6746         fi
6747
6748         # File currently set to -S 512K -c 1 or -S 512K -c 2
6749
6750         # Ensure parent striping is used if -R is set, and no stripe
6751         # count or size is specified
6752         echo -n "Setting stripe for parent directory..."
6753         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6754                 error "cannot set stripe '-S 2M -c 1'"
6755         echo "done."
6756
6757         echo -n "Verifying restripe option uses parent stripe settings..."
6758         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6759         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6760         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6761                 error "migrate failed"
6762         cur_ssize=$($LFS getstripe -S "$file1")
6763         [ $cur_ssize -eq $parent_ssize ] ||
6764                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6765         cur_scount=$($LFS getstripe -c "$file1")
6766         [ $cur_scount -eq $parent_scount ] ||
6767                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6768         echo "done."
6769
6770         # File currently set to -S 1M -c 1
6771
6772         # Ensure striping is preserved if -R is not set, and no stripe
6773         # count or size is specified
6774         echo -n "Verifying striping size preserved when not specified..."
6775         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6776         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6777                 error "cannot set stripe on parent directory"
6778         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6779                 error "migrate failed"
6780         cur_ssize=$($LFS getstripe -S "$file1")
6781         [ $cur_ssize -eq $orig_ssize ] ||
6782                 error "migrate by default $cur_ssize != $orig_ssize"
6783         echo "done."
6784
6785         # Ensure file name properly detected when final option has no argument
6786         echo -n "Verifying file name properly detected..."
6787         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6788                 error "file name interpreted as option argument"
6789         echo "done."
6790
6791         # Clean up
6792         rm -f "$file1"
6793 }
6794 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6795
6796 test_56wd() {
6797         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6798
6799         local file1=$DIR/$tdir/file1
6800
6801         echo -n "Creating test dir..."
6802         test_mkdir $DIR/$tdir || error "cannot create dir"
6803         echo "done."
6804
6805         echo -n "Creating test file..."
6806         touch $file1
6807         echo "done."
6808
6809         # Ensure 'lfs migrate' will fail by using a non-existent option,
6810         # and make sure rsync is not called to recover
6811         echo -n "Make sure --no-rsync option works..."
6812         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6813                 grep -q 'refusing to fall back to rsync' ||
6814                 error "rsync was called with --no-rsync set"
6815         echo "done."
6816
6817         # Ensure rsync is called without trying 'lfs migrate' first
6818         echo -n "Make sure --rsync option works..."
6819         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6820                 grep -q 'falling back to rsync' &&
6821                 error "lfs migrate was called with --rsync set"
6822         echo "done."
6823
6824         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6825         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6826                 grep -q 'at the same time' ||
6827                 error "--rsync and --no-rsync accepted concurrently"
6828         echo "done."
6829
6830         # Clean up
6831         rm -f $file1
6832 }
6833 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6834
6835 test_56we() {
6836         local td=$DIR/$tdir
6837         local tf=$td/$tfile
6838
6839         test_mkdir $td || error "cannot create $td"
6840         touch $tf || error "cannot touch $tf"
6841
6842         echo -n "Make sure --non-direct|-D works..."
6843         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6844                 grep -q "lfs migrate --non-direct" ||
6845                 error "--non-direct option cannot work correctly"
6846         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6847                 grep -q "lfs migrate -D" ||
6848                 error "-D option cannot work correctly"
6849         echo "done."
6850 }
6851 run_test 56we "check lfs_migrate --non-direct|-D support"
6852
6853 test_56x() {
6854         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6855         check_swap_layouts_support
6856
6857         local dir=$DIR/$tdir
6858         local ref1=/etc/passwd
6859         local file1=$dir/file1
6860
6861         test_mkdir $dir || error "creating dir $dir"
6862         $LFS setstripe -c 2 $file1
6863         cp $ref1 $file1
6864         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6865         stripe=$($LFS getstripe -c $file1)
6866         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6867         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6868
6869         # clean up
6870         rm -f $file1
6871 }
6872 run_test 56x "lfs migration support"
6873
6874 test_56xa() {
6875         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6876         check_swap_layouts_support
6877
6878         local dir=$DIR/$tdir/$testnum
6879
6880         test_mkdir -p $dir
6881
6882         local ref1=/etc/passwd
6883         local file1=$dir/file1
6884
6885         $LFS setstripe -c 2 $file1
6886         cp $ref1 $file1
6887         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6888
6889         local stripe=$($LFS getstripe -c $file1)
6890
6891         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6892         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6893
6894         # clean up
6895         rm -f $file1
6896 }
6897 run_test 56xa "lfs migration --block support"
6898
6899 check_migrate_links() {
6900         local dir="$1"
6901         local file1="$dir/file1"
6902         local begin="$2"
6903         local count="$3"
6904         local runas="$4"
6905         local total_count=$(($begin + $count - 1))
6906         local symlink_count=10
6907         local uniq_count=10
6908
6909         if [ ! -f "$file1" ]; then
6910                 echo -n "creating initial file..."
6911                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6912                         error "cannot setstripe initial file"
6913                 echo "done"
6914
6915                 echo -n "creating symlinks..."
6916                 for s in $(seq 1 $symlink_count); do
6917                         ln -s "$file1" "$dir/slink$s" ||
6918                                 error "cannot create symlinks"
6919                 done
6920                 echo "done"
6921
6922                 echo -n "creating nonlinked files..."
6923                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6924                         error "cannot create nonlinked files"
6925                 echo "done"
6926         fi
6927
6928         # create hard links
6929         if [ ! -f "$dir/file$total_count" ]; then
6930                 echo -n "creating hard links $begin:$total_count..."
6931                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6932                         /dev/null || error "cannot create hard links"
6933                 echo "done"
6934         fi
6935
6936         echo -n "checking number of hard links listed in xattrs..."
6937         local fid=$($LFS getstripe -F "$file1")
6938         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6939
6940         echo "${#paths[*]}"
6941         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6942                         skip "hard link list has unexpected size, skipping test"
6943         fi
6944         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6945                         error "link names should exceed xattrs size"
6946         fi
6947
6948         echo -n "migrating files..."
6949         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6950         local rc=$?
6951         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6952         echo "done"
6953
6954         # make sure all links have been properly migrated
6955         echo -n "verifying files..."
6956         fid=$($LFS getstripe -F "$file1") ||
6957                 error "cannot get fid for file $file1"
6958         for i in $(seq 2 $total_count); do
6959                 local fid2=$($LFS getstripe -F $dir/file$i)
6960
6961                 [ "$fid2" == "$fid" ] ||
6962                         error "migrated hard link has mismatched FID"
6963         done
6964
6965         # make sure hard links were properly detected, and migration was
6966         # performed only once for the entire link set; nonlinked files should
6967         # also be migrated
6968         local actual=$(grep -c 'done' <<< "$migrate_out")
6969         local expected=$(($uniq_count + 1))
6970
6971         [ "$actual" -eq  "$expected" ] ||
6972                 error "hard links individually migrated ($actual != $expected)"
6973
6974         # make sure the correct number of hard links are present
6975         local hardlinks=$(stat -c '%h' "$file1")
6976
6977         [ $hardlinks -eq $total_count ] ||
6978                 error "num hard links $hardlinks != $total_count"
6979         echo "done"
6980
6981         return 0
6982 }
6983
6984 test_56xb() {
6985         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6986                 skip "Need MDS version at least 2.10.55"
6987
6988         local dir="$DIR/$tdir"
6989
6990         test_mkdir "$dir" || error "cannot create dir $dir"
6991
6992         echo "testing lfs migrate mode when all links fit within xattrs"
6993         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6994
6995         echo "testing rsync mode when all links fit within xattrs"
6996         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6997
6998         echo "testing lfs migrate mode when all links do not fit within xattrs"
6999         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7000
7001         echo "testing rsync mode when all links do not fit within xattrs"
7002         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7003
7004         chown -R $RUNAS_ID $dir
7005         echo "testing non-root lfs migrate mode when not all links are in xattr"
7006         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7007
7008         # clean up
7009         rm -rf $dir
7010 }
7011 run_test 56xb "lfs migration hard link support"
7012
7013 test_56xc() {
7014         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7015
7016         local dir="$DIR/$tdir"
7017
7018         test_mkdir "$dir" || error "cannot create dir $dir"
7019
7020         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7021         echo -n "Setting initial stripe for 20MB test file..."
7022         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7023                 error "cannot setstripe 20MB file"
7024         echo "done"
7025         echo -n "Sizing 20MB test file..."
7026         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7027         echo "done"
7028         echo -n "Verifying small file autostripe count is 1..."
7029         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7030                 error "cannot migrate 20MB file"
7031         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7032                 error "cannot get stripe for $dir/20mb"
7033         [ $stripe_count -eq 1 ] ||
7034                 error "unexpected stripe count $stripe_count for 20MB file"
7035         rm -f "$dir/20mb"
7036         echo "done"
7037
7038         # Test 2: File is small enough to fit within the available space on
7039         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7040         # have at least an additional 1KB for each desired stripe for test 3
7041         echo -n "Setting stripe for 1GB test file..."
7042         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7043         echo "done"
7044         echo -n "Sizing 1GB test file..."
7045         # File size is 1GB + 3KB
7046         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7047         echo "done"
7048
7049         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7050         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7051         if (( avail > 524288 * OSTCOUNT )); then
7052                 echo -n "Migrating 1GB file..."
7053                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7054                         error "cannot migrate 1GB file"
7055                 echo "done"
7056                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7057                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7058                         error "cannot getstripe for 1GB file"
7059                 [ $stripe_count -eq 2 ] ||
7060                         error "unexpected stripe count $stripe_count != 2"
7061                 echo "done"
7062         fi
7063
7064         # Test 3: File is too large to fit within the available space on
7065         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7066         if [ $OSTCOUNT -ge 3 ]; then
7067                 # The required available space is calculated as
7068                 # file size (1GB + 3KB) / OST count (3).
7069                 local kb_per_ost=349526
7070
7071                 echo -n "Migrating 1GB file with limit..."
7072                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7073                         error "cannot migrate 1GB file with limit"
7074                 echo "done"
7075
7076                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7077                 echo -n "Verifying 1GB autostripe count with limited space..."
7078                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7079                         error "unexpected stripe count $stripe_count (min 3)"
7080                 echo "done"
7081         fi
7082
7083         # clean up
7084         rm -rf $dir
7085 }
7086 run_test 56xc "lfs migration autostripe"
7087
7088 test_56xd() {
7089         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7090
7091         local dir=$DIR/$tdir
7092         local f_mgrt=$dir/$tfile.mgrt
7093         local f_yaml=$dir/$tfile.yaml
7094         local f_copy=$dir/$tfile.copy
7095         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7096         local layout_copy="-c 2 -S 2M -i 1"
7097         local yamlfile=$dir/yamlfile
7098         local layout_before;
7099         local layout_after;
7100
7101         test_mkdir "$dir" || error "cannot create dir $dir"
7102         $LFS setstripe $layout_yaml $f_yaml ||
7103                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7104         $LFS getstripe --yaml $f_yaml > $yamlfile
7105         $LFS setstripe $layout_copy $f_copy ||
7106                 error "cannot setstripe $f_copy with layout $layout_copy"
7107         touch $f_mgrt
7108         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7109
7110         # 1. test option --yaml
7111         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7112                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7113         layout_before=$(get_layout_param $f_yaml)
7114         layout_after=$(get_layout_param $f_mgrt)
7115         [ "$layout_after" == "$layout_before" ] ||
7116                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7117
7118         # 2. test option --copy
7119         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7120                 error "cannot migrate $f_mgrt with --copy $f_copy"
7121         layout_before=$(get_layout_param $f_copy)
7122         layout_after=$(get_layout_param $f_mgrt)
7123         [ "$layout_after" == "$layout_before" ] ||
7124                 error "lfs_migrate --copy: $layout_after != $layout_before"
7125 }
7126 run_test 56xd "check lfs_migrate --yaml and --copy support"
7127
7128 test_56xe() {
7129         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7130
7131         local dir=$DIR/$tdir
7132         local f_comp=$dir/$tfile
7133         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7134         local layout_before=""
7135         local layout_after=""
7136
7137         test_mkdir "$dir" || error "cannot create dir $dir"
7138         $LFS setstripe $layout $f_comp ||
7139                 error "cannot setstripe $f_comp with layout $layout"
7140         layout_before=$(get_layout_param $f_comp)
7141         dd if=/dev/zero of=$f_comp bs=1M count=4
7142
7143         # 1. migrate a comp layout file by lfs_migrate
7144         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7145         layout_after=$(get_layout_param $f_comp)
7146         [ "$layout_before" == "$layout_after" ] ||
7147                 error "lfs_migrate: $layout_before != $layout_after"
7148
7149         # 2. migrate a comp layout file by lfs migrate
7150         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7151         layout_after=$(get_layout_param $f_comp)
7152         [ "$layout_before" == "$layout_after" ] ||
7153                 error "lfs migrate: $layout_before != $layout_after"
7154 }
7155 run_test 56xe "migrate a composite layout file"
7156
7157 test_56xf() {
7158         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7159
7160         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7161                 skip "Need server version at least 2.13.53"
7162
7163         local dir=$DIR/$tdir
7164         local f_comp=$dir/$tfile
7165         local layout="-E 1M -c1 -E -1 -c2"
7166         local fid_before=""
7167         local fid_after=""
7168
7169         test_mkdir "$dir" || error "cannot create dir $dir"
7170         $LFS setstripe $layout $f_comp ||
7171                 error "cannot setstripe $f_comp with layout $layout"
7172         fid_before=$($LFS getstripe --fid $f_comp)
7173         dd if=/dev/zero of=$f_comp bs=1M count=4
7174
7175         # 1. migrate a comp layout file to a comp layout
7176         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7177         fid_after=$($LFS getstripe --fid $f_comp)
7178         [ "$fid_before" == "$fid_after" ] ||
7179                 error "comp-to-comp migrate: $fid_before != $fid_after"
7180
7181         # 2. migrate a comp layout file to a plain layout
7182         $LFS migrate -c2 $f_comp ||
7183                 error "cannot migrate $f_comp by lfs migrate"
7184         fid_after=$($LFS getstripe --fid $f_comp)
7185         [ "$fid_before" == "$fid_after" ] ||
7186                 error "comp-to-plain migrate: $fid_before != $fid_after"
7187
7188         # 3. migrate a plain layout file to a comp layout
7189         $LFS migrate $layout $f_comp ||
7190                 error "cannot migrate $f_comp by lfs migrate"
7191         fid_after=$($LFS getstripe --fid $f_comp)
7192         [ "$fid_before" == "$fid_after" ] ||
7193                 error "plain-to-comp migrate: $fid_before != $fid_after"
7194 }
7195 run_test 56xf "FID is not lost during migration of a composite layout file"
7196
7197 test_56y() {
7198         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7199                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7200
7201         local res=""
7202         local dir=$DIR/$tdir
7203         local f1=$dir/file1
7204         local f2=$dir/file2
7205
7206         test_mkdir -p $dir || error "creating dir $dir"
7207         touch $f1 || error "creating std file $f1"
7208         $MULTIOP $f2 H2c || error "creating released file $f2"
7209
7210         # a directory can be raid0, so ask only for files
7211         res=$($LFS find $dir -L raid0 -type f | wc -l)
7212         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7213
7214         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7215         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7216
7217         # only files can be released, so no need to force file search
7218         res=$($LFS find $dir -L released)
7219         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7220
7221         res=$($LFS find $dir -type f \! -L released)
7222         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7223 }
7224 run_test 56y "lfs find -L raid0|released"
7225
7226 test_56z() { # LU-4824
7227         # This checks to make sure 'lfs find' continues after errors
7228         # There are two classes of errors that should be caught:
7229         # - If multiple paths are provided, all should be searched even if one
7230         #   errors out
7231         # - If errors are encountered during the search, it should not terminate
7232         #   early
7233         local dir=$DIR/$tdir
7234         local i
7235
7236         test_mkdir $dir
7237         for i in d{0..9}; do
7238                 test_mkdir $dir/$i
7239                 touch $dir/$i/$tfile
7240         done
7241         $LFS find $DIR/non_existent_dir $dir &&
7242                 error "$LFS find did not return an error"
7243         # Make a directory unsearchable. This should NOT be the last entry in
7244         # directory order.  Arbitrarily pick the 6th entry
7245         chmod 700 $($LFS find $dir -type d | sed '6!d')
7246
7247         $RUNAS $LFS find $DIR/non_existent $dir
7248         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7249
7250         # The user should be able to see 10 directories and 9 files
7251         (( count == 19 )) ||
7252                 error "$LFS find found $count != 19 entries after error"
7253 }
7254 run_test 56z "lfs find should continue after an error"
7255
7256 test_56aa() { # LU-5937
7257         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7258
7259         local dir=$DIR/$tdir
7260
7261         mkdir $dir
7262         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7263
7264         createmany -o $dir/striped_dir/${tfile}- 1024
7265         local dirs=$($LFS find --size +8k $dir/)
7266
7267         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7268 }
7269 run_test 56aa "lfs find --size under striped dir"
7270
7271 test_56ab() { # LU-10705
7272         test_mkdir $DIR/$tdir
7273         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7274         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7275         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7276         # Flush writes to ensure valid blocks.  Need to be more thorough for
7277         # ZFS, since blocks are not allocated/returned to client immediately.
7278         sync_all_data
7279         wait_zfs_commit ost1 2
7280         cancel_lru_locks osc
7281         ls -ls $DIR/$tdir
7282
7283         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7284
7285         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7286
7287         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7288         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7289
7290         rm -f $DIR/$tdir/$tfile.[123]
7291 }
7292 run_test 56ab "lfs find --blocks"
7293
7294 test_56ba() {
7295         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7296                 skip "Need MDS version at least 2.10.50"
7297
7298         # Create composite files with one component
7299         local dir=$DIR/$tdir
7300
7301         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7302         # Create composite files with three components
7303         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7304         # Create non-composite files
7305         createmany -o $dir/${tfile}- 10
7306
7307         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7308
7309         [[ $nfiles == 10 ]] ||
7310                 error "lfs find -E 1M found $nfiles != 10 files"
7311
7312         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7313         [[ $nfiles == 25 ]] ||
7314                 error "lfs find ! -E 1M found $nfiles != 25 files"
7315
7316         # All files have a component that starts at 0
7317         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7318         [[ $nfiles == 35 ]] ||
7319                 error "lfs find --component-start 0 - $nfiles != 35 files"
7320
7321         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7322         [[ $nfiles == 15 ]] ||
7323                 error "lfs find --component-start 2M - $nfiles != 15 files"
7324
7325         # All files created here have a componenet that does not starts at 2M
7326         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7327         [[ $nfiles == 35 ]] ||
7328                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7329
7330         # Find files with a specified number of components
7331         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7332         [[ $nfiles == 15 ]] ||
7333                 error "lfs find --component-count 3 - $nfiles != 15 files"
7334
7335         # Remember non-composite files have a component count of zero
7336         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7337         [[ $nfiles == 10 ]] ||
7338                 error "lfs find --component-count 0 - $nfiles != 10 files"
7339
7340         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7341         [[ $nfiles == 20 ]] ||
7342                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7343
7344         # All files have a flag called "init"
7345         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7346         [[ $nfiles == 35 ]] ||
7347                 error "lfs find --component-flags init - $nfiles != 35 files"
7348
7349         # Multi-component files will have a component not initialized
7350         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7351         [[ $nfiles == 15 ]] ||
7352                 error "lfs find !--component-flags init - $nfiles != 15 files"
7353
7354         rm -rf $dir
7355
7356 }
7357 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7358
7359 test_56ca() {
7360         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7361                 skip "Need MDS version at least 2.10.57"
7362
7363         local td=$DIR/$tdir
7364         local tf=$td/$tfile
7365         local dir
7366         local nfiles
7367         local cmd
7368         local i
7369         local j
7370
7371         # create mirrored directories and mirrored files
7372         mkdir $td || error "mkdir $td failed"
7373         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7374         createmany -o $tf- 10 || error "create $tf- failed"
7375
7376         for i in $(seq 2); do
7377                 dir=$td/dir$i
7378                 mkdir $dir || error "mkdir $dir failed"
7379                 $LFS mirror create -N$((3 + i)) $dir ||
7380                         error "create mirrored dir $dir failed"
7381                 createmany -o $dir/$tfile- 10 ||
7382                         error "create $dir/$tfile- failed"
7383         done
7384
7385         # change the states of some mirrored files
7386         echo foo > $tf-6
7387         for i in $(seq 2); do
7388                 dir=$td/dir$i
7389                 for j in $(seq 4 9); do
7390                         echo foo > $dir/$tfile-$j
7391                 done
7392         done
7393
7394         # find mirrored files with specific mirror count
7395         cmd="$LFS find --mirror-count 3 --type f $td"
7396         nfiles=$($cmd | wc -l)
7397         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7398
7399         cmd="$LFS find ! --mirror-count 3 --type f $td"
7400         nfiles=$($cmd | wc -l)
7401         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7402
7403         cmd="$LFS find --mirror-count +2 --type f $td"
7404         nfiles=$($cmd | wc -l)
7405         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7406
7407         cmd="$LFS find --mirror-count -6 --type f $td"
7408         nfiles=$($cmd | wc -l)
7409         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7410
7411         # find mirrored files with specific file state
7412         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7413         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7414
7415         cmd="$LFS find --mirror-state=ro --type f $td"
7416         nfiles=$($cmd | wc -l)
7417         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7418
7419         cmd="$LFS find ! --mirror-state=ro --type f $td"
7420         nfiles=$($cmd | wc -l)
7421         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7422
7423         cmd="$LFS find --mirror-state=wp --type f $td"
7424         nfiles=$($cmd | wc -l)
7425         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7426
7427         cmd="$LFS find ! --mirror-state=sp --type f $td"
7428         nfiles=$($cmd | wc -l)
7429         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7430 }
7431 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7432
7433 test_57a() {
7434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7435         # note test will not do anything if MDS is not local
7436         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7437                 skip_env "ldiskfs only test"
7438         fi
7439         remote_mds_nodsh && skip "remote MDS with nodsh"
7440
7441         local MNTDEV="osd*.*MDT*.mntdev"
7442         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7443         [ -z "$DEV" ] && error "can't access $MNTDEV"
7444         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7445                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7446                         error "can't access $DEV"
7447                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7448                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7449                 rm $TMP/t57a.dump
7450         done
7451 }
7452 run_test 57a "verify MDS filesystem created with large inodes =="
7453
7454 test_57b() {
7455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7456         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7457                 skip_env "ldiskfs only test"
7458         fi
7459         remote_mds_nodsh && skip "remote MDS with nodsh"
7460
7461         local dir=$DIR/$tdir
7462         local filecount=100
7463         local file1=$dir/f1
7464         local fileN=$dir/f$filecount
7465
7466         rm -rf $dir || error "removing $dir"
7467         test_mkdir -c1 $dir
7468         local mdtidx=$($LFS getstripe -m $dir)
7469         local mdtname=MDT$(printf %04x $mdtidx)
7470         local facet=mds$((mdtidx + 1))
7471
7472         echo "mcreating $filecount files"
7473         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7474
7475         # verify that files do not have EAs yet
7476         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7477                 error "$file1 has an EA"
7478         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7479                 error "$fileN has an EA"
7480
7481         sync
7482         sleep 1
7483         df $dir  #make sure we get new statfs data
7484         local mdsfree=$(do_facet $facet \
7485                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7486         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7487         local file
7488
7489         echo "opening files to create objects/EAs"
7490         for file in $(seq -f $dir/f%g 1 $filecount); do
7491                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7492                         error "opening $file"
7493         done
7494
7495         # verify that files have EAs now
7496         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7497         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7498
7499         sleep 1  #make sure we get new statfs data
7500         df $dir
7501         local mdsfree2=$(do_facet $facet \
7502                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7503         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7504
7505         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7506                 if [ "$mdsfree" != "$mdsfree2" ]; then
7507                         error "MDC before $mdcfree != after $mdcfree2"
7508                 else
7509                         echo "MDC before $mdcfree != after $mdcfree2"
7510                         echo "unable to confirm if MDS has large inodes"
7511                 fi
7512         fi
7513         rm -rf $dir
7514 }
7515 run_test 57b "default LOV EAs are stored inside large inodes ==="
7516
7517 test_58() {
7518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7519         [ -z "$(which wiretest 2>/dev/null)" ] &&
7520                         skip_env "could not find wiretest"
7521
7522         wiretest
7523 }
7524 run_test 58 "verify cross-platform wire constants =============="
7525
7526 test_59() {
7527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7528
7529         echo "touch 130 files"
7530         createmany -o $DIR/f59- 130
7531         echo "rm 130 files"
7532         unlinkmany $DIR/f59- 130
7533         sync
7534         # wait for commitment of removal
7535         wait_delete_completed
7536 }
7537 run_test 59 "verify cancellation of llog records async ========="
7538
7539 TEST60_HEAD="test_60 run $RANDOM"
7540 test_60a() {
7541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7542         remote_mgs_nodsh && skip "remote MGS with nodsh"
7543         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7544                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7545                         skip_env "missing subtest run-llog.sh"
7546
7547         log "$TEST60_HEAD - from kernel mode"
7548         do_facet mgs "$LCTL dk > /dev/null"
7549         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7550         do_facet mgs $LCTL dk > $TMP/$tfile
7551
7552         # LU-6388: test llog_reader
7553         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7554         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7555         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7556                         skip_env "missing llog_reader"
7557         local fstype=$(facet_fstype mgs)
7558         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7559                 skip_env "Only for ldiskfs or zfs type mgs"
7560
7561         local mntpt=$(facet_mntpt mgs)
7562         local mgsdev=$(mgsdevname 1)
7563         local fid_list
7564         local fid
7565         local rec_list
7566         local rec
7567         local rec_type
7568         local obj_file
7569         local path
7570         local seq
7571         local oid
7572         local pass=true
7573
7574         #get fid and record list
7575         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7576                 tail -n 4))
7577         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7578                 tail -n 4))
7579         #remount mgs as ldiskfs or zfs type
7580         stop mgs || error "stop mgs failed"
7581         mount_fstype mgs || error "remount mgs failed"
7582         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7583                 fid=${fid_list[i]}
7584                 rec=${rec_list[i]}
7585                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7586                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7587                 oid=$((16#$oid))
7588
7589                 case $fstype in
7590                         ldiskfs )
7591                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7592                         zfs )
7593                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7594                 esac
7595                 echo "obj_file is $obj_file"
7596                 do_facet mgs $llog_reader $obj_file
7597
7598                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7599                         awk '{ print $3 }' | sed -e "s/^type=//g")
7600                 if [ $rec_type != $rec ]; then
7601                         echo "FAILED test_60a wrong record type $rec_type," \
7602                               "should be $rec"
7603                         pass=false
7604                         break
7605                 fi
7606
7607                 #check obj path if record type is LLOG_LOGID_MAGIC
7608                 if [ "$rec" == "1064553b" ]; then
7609                         path=$(do_facet mgs $llog_reader $obj_file |
7610                                 grep "path=" | awk '{ print $NF }' |
7611                                 sed -e "s/^path=//g")
7612                         if [ $obj_file != $mntpt/$path ]; then
7613                                 echo "FAILED test_60a wrong obj path" \
7614                                       "$montpt/$path, should be $obj_file"
7615                                 pass=false
7616                                 break
7617                         fi
7618                 fi
7619         done
7620         rm -f $TMP/$tfile
7621         #restart mgs before "error", otherwise it will block the next test
7622         stop mgs || error "stop mgs failed"
7623         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7624         $pass || error "test failed, see FAILED test_60a messages for specifics"
7625 }
7626 run_test 60a "llog_test run from kernel module and test llog_reader"
7627
7628 test_60b() { # bug 6411
7629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7630
7631         dmesg > $DIR/$tfile
7632         LLOG_COUNT=$(do_facet mgs dmesg |
7633                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7634                           /llog_[a-z]*.c:[0-9]/ {
7635                                 if (marker)
7636                                         from_marker++
7637                                 from_begin++
7638                           }
7639                           END {
7640                                 if (marker)
7641                                         print from_marker
7642                                 else
7643                                         print from_begin
7644                           }")
7645
7646         [[ $LLOG_COUNT -gt 120 ]] &&
7647                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7648 }
7649 run_test 60b "limit repeated messages from CERROR/CWARN"
7650
7651 test_60c() {
7652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7653
7654         echo "create 5000 files"
7655         createmany -o $DIR/f60c- 5000
7656 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7657         lctl set_param fail_loc=0x80000137
7658         unlinkmany $DIR/f60c- 5000
7659         lctl set_param fail_loc=0
7660 }
7661 run_test 60c "unlink file when mds full"
7662
7663 test_60d() {
7664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7665
7666         SAVEPRINTK=$(lctl get_param -n printk)
7667         # verify "lctl mark" is even working"
7668         MESSAGE="test message ID $RANDOM $$"
7669         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7670         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7671
7672         lctl set_param printk=0 || error "set lnet.printk failed"
7673         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7674         MESSAGE="new test message ID $RANDOM $$"
7675         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7676         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7677         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7678
7679         lctl set_param -n printk="$SAVEPRINTK"
7680 }
7681 run_test 60d "test printk console message masking"
7682
7683 test_60e() {
7684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7685         remote_mds_nodsh && skip "remote MDS with nodsh"
7686
7687         touch $DIR/$tfile
7688 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7689         do_facet mds1 lctl set_param fail_loc=0x15b
7690         rm $DIR/$tfile
7691 }
7692 run_test 60e "no space while new llog is being created"
7693
7694 test_60g() {
7695         local pid
7696         local i
7697
7698         test_mkdir -c $MDSCOUNT $DIR/$tdir
7699
7700         (
7701                 local index=0
7702                 while true; do
7703                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7704                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7705                                 2>/dev/null
7706                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7707                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7708                         index=$((index + 1))
7709                 done
7710         ) &
7711
7712         pid=$!
7713
7714         for i in {0..100}; do
7715                 # define OBD_FAIL_OSD_TXN_START    0x19a
7716                 local index=$((i % MDSCOUNT + 1))
7717
7718                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7719                         > /dev/null
7720                 sleep 0.01
7721         done
7722
7723         kill -9 $pid
7724
7725         for i in $(seq $MDSCOUNT); do
7726                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7727         done
7728
7729         mkdir $DIR/$tdir/new || error "mkdir failed"
7730         rmdir $DIR/$tdir/new || error "rmdir failed"
7731
7732         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7733                 -t namespace
7734         for i in $(seq $MDSCOUNT); do
7735                 wait_update_facet mds$i "$LCTL get_param -n \
7736                         mdd.$(facet_svc mds$i).lfsck_namespace |
7737                         awk '/^status/ { print \\\$2 }'" "completed"
7738         done
7739
7740         ls -R $DIR/$tdir || error "ls failed"
7741         rm -rf $DIR/$tdir || error "rmdir failed"
7742 }
7743 run_test 60g "transaction abort won't cause MDT hung"
7744
7745 test_60h() {
7746         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7747                 skip "Need MDS version at least 2.12.52"
7748         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7749
7750         local f
7751
7752         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7753         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7754         for fail_loc in 0x80000188 0x80000189; do
7755                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7756                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7757                         error "mkdir $dir-$fail_loc failed"
7758                 for i in {0..10}; do
7759                         # create may fail on missing stripe
7760                         echo $i > $DIR/$tdir-$fail_loc/$i
7761                 done
7762                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7763                         error "getdirstripe $tdir-$fail_loc failed"
7764                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7765                         error "migrate $tdir-$fail_loc failed"
7766                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7767                         error "getdirstripe $tdir-$fail_loc failed"
7768                 pushd $DIR/$tdir-$fail_loc
7769                 for f in *; do
7770                         echo $f | cmp $f - || error "$f data mismatch"
7771                 done
7772                 popd
7773                 rm -rf $DIR/$tdir-$fail_loc
7774         done
7775 }
7776 run_test 60h "striped directory with missing stripes can be accessed"
7777
7778 test_61a() {
7779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7780
7781         f="$DIR/f61"
7782         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7783         cancel_lru_locks osc
7784         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7785         sync
7786 }
7787 run_test 61a "mmap() writes don't make sync hang ================"
7788
7789 test_61b() {
7790         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7791 }
7792 run_test 61b "mmap() of unstriped file is successful"
7793
7794 # bug 2330 - insufficient obd_match error checking causes LBUG
7795 test_62() {
7796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7797
7798         f="$DIR/f62"
7799         echo foo > $f
7800         cancel_lru_locks osc
7801         lctl set_param fail_loc=0x405
7802         cat $f && error "cat succeeded, expect -EIO"
7803         lctl set_param fail_loc=0
7804 }
7805 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7806 # match every page all of the time.
7807 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7808
7809 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7810 # Though this test is irrelevant anymore, it helped to reveal some
7811 # other grant bugs (LU-4482), let's keep it.
7812 test_63a() {   # was test_63
7813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7814
7815         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7816
7817         for i in `seq 10` ; do
7818                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7819                 sleep 5
7820                 kill $!
7821                 sleep 1
7822         done
7823
7824         rm -f $DIR/f63 || true
7825 }
7826 run_test 63a "Verify oig_wait interruption does not crash ======="
7827
7828 # bug 2248 - async write errors didn't return to application on sync
7829 # bug 3677 - async write errors left page locked
7830 test_63b() {
7831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7832
7833         debugsave
7834         lctl set_param debug=-1
7835
7836         # ensure we have a grant to do async writes
7837         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7838         rm $DIR/$tfile
7839
7840         sync    # sync lest earlier test intercept the fail_loc
7841
7842         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7843         lctl set_param fail_loc=0x80000406
7844         $MULTIOP $DIR/$tfile Owy && \
7845                 error "sync didn't return ENOMEM"
7846         sync; sleep 2; sync     # do a real sync this time to flush page
7847         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7848                 error "locked page left in cache after async error" || true
7849         debugrestore
7850 }
7851 run_test 63b "async write errors should be returned to fsync ==="
7852
7853 test_64a () {
7854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7855
7856         lfs df $DIR
7857         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7858 }
7859 run_test 64a "verify filter grant calculations (in kernel) ====="
7860
7861 test_64b () {
7862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7863
7864         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7865 }
7866 run_test 64b "check out-of-space detection on client"
7867
7868 test_64c() {
7869         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7870 }
7871 run_test 64c "verify grant shrink"
7872
7873 import_param() {
7874         local tgt=$1
7875         local param=$2
7876
7877         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7878 }
7879
7880 # this does exactly what osc_request.c:osc_announce_cached() does in
7881 # order to calculate max amount of grants to ask from server
7882 want_grant() {
7883         local tgt=$1
7884
7885         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7886         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7887
7888         ((rpc_in_flight++));
7889         nrpages=$((nrpages * rpc_in_flight))
7890
7891         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7892
7893         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7894
7895         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7896         local undirty=$((nrpages * PAGE_SIZE))
7897
7898         local max_extent_pages
7899         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7900         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7901         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7902         local grant_extent_tax
7903         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7904
7905         undirty=$((undirty + nrextents * grant_extent_tax))
7906
7907         echo $undirty
7908 }
7909
7910 # this is size of unit for grant allocation. It should be equal to
7911 # what tgt_grant.c:tgt_grant_chunk() calculates
7912 grant_chunk() {
7913         local tgt=$1
7914         local max_brw_size
7915         local grant_extent_tax
7916
7917         max_brw_size=$(import_param $tgt max_brw_size)
7918
7919         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7920
7921         echo $(((max_brw_size + grant_extent_tax) * 2))
7922 }
7923
7924 test_64d() {
7925         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7926                 skip "OST < 2.10.55 doesn't limit grants enough"
7927
7928         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7929
7930         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7931                 skip "no grant_param connect flag"
7932
7933         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7934
7935         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7936         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7937
7938
7939         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7940         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7941
7942         $LFS setstripe $DIR/$tfile -i 0 -c 1
7943         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7944         ddpid=$!
7945
7946         while kill -0 $ddpid; do
7947                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7948
7949                 if [[ $cur_grant -gt $max_cur_granted ]]; then
7950                         kill $ddpid
7951                         error "cur_grant $cur_grant > $max_cur_granted"
7952                 fi
7953
7954                 sleep 1
7955         done
7956 }
7957 run_test 64d "check grant limit exceed"
7958
7959 check_grants() {
7960         local tgt=$1
7961         local expected=$2
7962         local msg=$3
7963         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7964
7965         ((cur_grants == expected)) ||
7966                 error "$msg: grants mismatch: $cur_grants, expected $expected"
7967 }
7968
7969 round_up_p2() {
7970         echo $((($1 + $2 - 1) & ~($2 - 1)))
7971 }
7972
7973 test_64e() {
7974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7975         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
7976                 skip "Need OSS version at least 2.11.56"
7977
7978         # Remount client to reset grant
7979         remount_client $MOUNT || error "failed to remount client"
7980         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
7981
7982         local init_grants=$(import_param $osc_tgt initial_grant)
7983
7984         check_grants $osc_tgt $init_grants "init grants"
7985
7986         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
7987         local max_brw_size=$(import_param $osc_tgt max_brw_size)
7988         local gbs=$(import_param $osc_tgt grant_block_size)
7989
7990         # write random number of bytes from max_brw_size / 4 to max_brw_size
7991         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
7992         # align for direct io
7993         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
7994         # round to grant consumption unit
7995         local wb_round_up=$(round_up_p2 $write_bytes gbs)
7996
7997         local grants=$((wb_round_up + extent_tax))
7998
7999         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8000
8001         # define OBD_FAIL_TGT_NO_GRANT 0x725
8002         # make the server not grant more back
8003         do_facet ost1 $LCTL set_param fail_loc=0x725
8004         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8005
8006         do_facet ost1 $LCTL set_param fail_loc=0
8007
8008         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8009
8010         rm -f $DIR/$tfile || error "rm failed"
8011
8012         # Remount client to reset grant
8013         remount_client $MOUNT || error "failed to remount client"
8014         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8015
8016         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8017
8018         # define OBD_FAIL_TGT_NO_GRANT 0x725
8019         # make the server not grant more back
8020         do_facet ost1 $LCTL set_param fail_loc=0x725
8021         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8022         do_facet ost1 $LCTL set_param fail_loc=0
8023
8024         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8025 }
8026 run_test 64e "check grant consumption (no grant allocation)"
8027
8028 test_64f() {
8029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8030
8031         # Remount client to reset grant
8032         remount_client $MOUNT || error "failed to remount client"
8033         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8034
8035         local init_grants=$(import_param $osc_tgt initial_grant)
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         local chunk=$(grant_chunk $osc_tgt)
8040
8041         # write random number of bytes from max_brw_size / 4 to max_brw_size
8042         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8043         # align for direct io
8044         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8045         # round to grant consumption unit
8046         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8047
8048         local grants=$((wb_round_up + extent_tax))
8049
8050         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8051         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8052                 error "error writing to $DIR/$tfile"
8053
8054         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8055                 "direct io with grant allocation"
8056
8057         rm -f $DIR/$tfile || error "rm failed"
8058
8059         # Remount client to reset grant
8060         remount_client $MOUNT || error "failed to remount client"
8061         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8062
8063         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8064
8065         local cmd="oO_WRONLY:w${write_bytes}_yc"
8066
8067         $MULTIOP $DIR/$tfile $cmd &
8068         MULTIPID=$!
8069         sleep 1
8070
8071         check_grants $osc_tgt $((init_grants - grants)) \
8072                 "buffered io, not write rpc"
8073
8074         kill -USR1 $MULTIPID
8075         wait
8076
8077         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8078                 "buffered io, one RPC"
8079 }
8080 run_test 64f "check grant consumption (with grant allocation)"
8081
8082 # bug 1414 - set/get directories' stripe info
8083 test_65a() {
8084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8085
8086         test_mkdir $DIR/$tdir
8087         touch $DIR/$tdir/f1
8088         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8089 }
8090 run_test 65a "directory with no stripe info"
8091
8092 test_65b() {
8093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8094
8095         test_mkdir $DIR/$tdir
8096         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8097
8098         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8099                                                 error "setstripe"
8100         touch $DIR/$tdir/f2
8101         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8102 }
8103 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8104
8105 test_65c() {
8106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8107         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8108
8109         test_mkdir $DIR/$tdir
8110         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8111
8112         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8113                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8114         touch $DIR/$tdir/f3
8115         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8116 }
8117 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8118
8119 test_65d() {
8120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8121
8122         test_mkdir $DIR/$tdir
8123         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8124         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8125
8126         if [[ $STRIPECOUNT -le 0 ]]; then
8127                 sc=1
8128         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8129                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8130                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8131         else
8132                 sc=$(($STRIPECOUNT - 1))
8133         fi
8134         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8135         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8136         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8137                 error "lverify failed"
8138 }
8139 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8140
8141 test_65e() {
8142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8143
8144         test_mkdir $DIR/$tdir
8145
8146         $LFS setstripe $DIR/$tdir || error "setstripe"
8147         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8148                                         error "no stripe info failed"
8149         touch $DIR/$tdir/f6
8150         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8151 }
8152 run_test 65e "directory setstripe defaults"
8153
8154 test_65f() {
8155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8156
8157         test_mkdir $DIR/${tdir}f
8158         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8159                 error "setstripe succeeded" || true
8160 }
8161 run_test 65f "dir setstripe permission (should return error) ==="
8162
8163 test_65g() {
8164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8165
8166         test_mkdir $DIR/$tdir
8167         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8168
8169         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8170                 error "setstripe -S failed"
8171         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8172         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8173                 error "delete default stripe failed"
8174 }
8175 run_test 65g "directory setstripe -d"
8176
8177 test_65h() {
8178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8179
8180         test_mkdir $DIR/$tdir
8181         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8182
8183         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8184                 error "setstripe -S failed"
8185         test_mkdir $DIR/$tdir/dd1
8186         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8187                 error "stripe info inherit failed"
8188 }
8189 run_test 65h "directory stripe info inherit ===================="
8190
8191 test_65i() {
8192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8193
8194         save_layout_restore_at_exit $MOUNT
8195
8196         # bug6367: set non-default striping on root directory
8197         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8198
8199         # bug12836: getstripe on -1 default directory striping
8200         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8201
8202         # bug12836: getstripe -v on -1 default directory striping
8203         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8204
8205         # bug12836: new find on -1 default directory striping
8206         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8207 }
8208 run_test 65i "various tests to set root directory striping"
8209
8210 test_65j() { # bug6367
8211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8212
8213         sync; sleep 1
8214
8215         # if we aren't already remounting for each test, do so for this test
8216         if [ "$I_MOUNTED" = "yes" ]; then
8217                 cleanup || error "failed to unmount"
8218                 setup
8219         fi
8220
8221         save_layout_restore_at_exit $MOUNT
8222
8223         $LFS setstripe -d $MOUNT || error "setstripe failed"
8224 }
8225 run_test 65j "set default striping on root directory (bug 6367)="
8226
8227 cleanup_65k() {
8228         rm -rf $DIR/$tdir
8229         wait_delete_completed
8230         do_facet $SINGLEMDS "lctl set_param -n \
8231                 osp.$ost*MDT0000.max_create_count=$max_count"
8232         do_facet $SINGLEMDS "lctl set_param -n \
8233                 osp.$ost*MDT0000.create_count=$count"
8234         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8235         echo $INACTIVE_OSC "is Activate"
8236
8237         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8238 }
8239
8240 test_65k() { # bug11679
8241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8242         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8243         remote_mds_nodsh && skip "remote MDS with nodsh"
8244
8245         local disable_precreate=true
8246         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8247                 disable_precreate=false
8248
8249         echo "Check OST status: "
8250         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8251                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8252
8253         for OSC in $MDS_OSCS; do
8254                 echo $OSC "is active"
8255                 do_facet $SINGLEMDS lctl --device %$OSC activate
8256         done
8257
8258         for INACTIVE_OSC in $MDS_OSCS; do
8259                 local ost=$(osc_to_ost $INACTIVE_OSC)
8260                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8261                                lov.*md*.target_obd |
8262                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8263
8264                 mkdir -p $DIR/$tdir
8265                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8266                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8267
8268                 echo "Deactivate: " $INACTIVE_OSC
8269                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8270
8271                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8272                               osp.$ost*MDT0000.create_count")
8273                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8274                                   osp.$ost*MDT0000.max_create_count")
8275                 $disable_precreate &&
8276                         do_facet $SINGLEMDS "lctl set_param -n \
8277                                 osp.$ost*MDT0000.max_create_count=0"
8278
8279                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8280                         [ -f $DIR/$tdir/$idx ] && continue
8281                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8282                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8283                                 { cleanup_65k;
8284                                   error "setstripe $idx should succeed"; }
8285                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8286                 done
8287                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8288                 rmdir $DIR/$tdir
8289
8290                 do_facet $SINGLEMDS "lctl set_param -n \
8291                         osp.$ost*MDT0000.max_create_count=$max_count"
8292                 do_facet $SINGLEMDS "lctl set_param -n \
8293                         osp.$ost*MDT0000.create_count=$count"
8294                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8295                 echo $INACTIVE_OSC "is Activate"
8296
8297                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8298         done
8299 }
8300 run_test 65k "validate manual striping works properly with deactivated OSCs"
8301
8302 test_65l() { # bug 12836
8303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8304
8305         test_mkdir -p $DIR/$tdir/test_dir
8306         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8307         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8308 }
8309 run_test 65l "lfs find on -1 stripe dir ========================"
8310
8311 test_65m() {
8312         local layout=$(save_layout $MOUNT)
8313         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8314                 restore_layout $MOUNT $layout
8315                 error "setstripe should fail by non-root users"
8316         }
8317         true
8318 }
8319 run_test 65m "normal user can't set filesystem default stripe"
8320
8321 test_65n() {
8322         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8323         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8324                 skip "Need MDS version at least 2.12.50"
8325         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8326
8327         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8328         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8329         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8330
8331         local root_layout=$(save_layout $MOUNT)
8332         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8333
8334         # new subdirectory under root directory should not inherit
8335         # the default layout from root
8336         local dir1=$MOUNT/$tdir-1
8337         mkdir $dir1 || error "mkdir $dir1 failed"
8338         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8339                 error "$dir1 shouldn't have LOV EA"
8340
8341         # delete the default layout on root directory
8342         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8343
8344         local dir2=$MOUNT/$tdir-2
8345         mkdir $dir2 || error "mkdir $dir2 failed"
8346         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8347                 error "$dir2 shouldn't have LOV EA"
8348
8349         # set a new striping pattern on root directory
8350         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8351         local new_def_stripe_size=$((def_stripe_size * 2))
8352         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8353                 error "set stripe size on $MOUNT failed"
8354
8355         # new file created in $dir2 should inherit the new stripe size from
8356         # the filesystem default
8357         local file2=$dir2/$tfile-2
8358         touch $file2 || error "touch $file2 failed"
8359
8360         local file2_stripe_size=$($LFS getstripe -S $file2)
8361         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8362                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8363
8364         local dir3=$MOUNT/$tdir-3
8365         mkdir $dir3 || error "mkdir $dir3 failed"
8366         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8367         # the root layout, which is the actual default layout that will be used
8368         # when new files are created in $dir3.
8369         local dir3_layout=$(get_layout_param $dir3)
8370         local root_dir_layout=$(get_layout_param $MOUNT)
8371         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8372                 error "$dir3 should show the default layout from $MOUNT"
8373
8374         # set OST pool on root directory
8375         local pool=$TESTNAME
8376         pool_add $pool || error "add $pool failed"
8377         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8378                 error "add targets to $pool failed"
8379
8380         $LFS setstripe -p $pool $MOUNT ||
8381                 error "set OST pool on $MOUNT failed"
8382
8383         # new file created in $dir3 should inherit the pool from
8384         # the filesystem default
8385         local file3=$dir3/$tfile-3
8386         touch $file3 || error "touch $file3 failed"
8387
8388         local file3_pool=$($LFS getstripe -p $file3)
8389         [[ "$file3_pool" = "$pool" ]] ||
8390                 error "$file3 didn't inherit OST pool $pool"
8391
8392         local dir4=$MOUNT/$tdir-4
8393         mkdir $dir4 || error "mkdir $dir4 failed"
8394         local dir4_layout=$(get_layout_param $dir4)
8395         root_dir_layout=$(get_layout_param $MOUNT)
8396         echo "$LFS getstripe -d $dir4"
8397         $LFS getstripe -d $dir4
8398         echo "$LFS getstripe -d $MOUNT"
8399         $LFS getstripe -d $MOUNT
8400         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8401                 error "$dir4 should show the default layout from $MOUNT"
8402
8403         # new file created in $dir4 should inherit the pool from
8404         # the filesystem default
8405         local file4=$dir4/$tfile-4
8406         touch $file4 || error "touch $file4 failed"
8407
8408         local file4_pool=$($LFS getstripe -p $file4)
8409         [[ "$file4_pool" = "$pool" ]] ||
8410                 error "$file4 didn't inherit OST pool $pool"
8411
8412         # new subdirectory under non-root directory should inherit
8413         # the default layout from its parent directory
8414         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8415                 error "set directory layout on $dir4 failed"
8416
8417         local dir5=$dir4/$tdir-5
8418         mkdir $dir5 || error "mkdir $dir5 failed"
8419
8420         dir4_layout=$(get_layout_param $dir4)
8421         local dir5_layout=$(get_layout_param $dir5)
8422         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8423                 error "$dir5 should inherit the default layout from $dir4"
8424
8425         # though subdir under ROOT doesn't inherit default layout, but
8426         # its sub dir/file should be created with default layout.
8427         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8428         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8429                 skip "Need MDS version at least 2.12.59"
8430
8431         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8432         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8433         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8434
8435         if [ $default_lmv_hash == "none" ]; then
8436                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8437         else
8438                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8439                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8440         fi
8441
8442         $LFS setdirstripe -D -c 2 $MOUNT ||
8443                 error "setdirstripe -D -c 2 failed"
8444         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8445         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8446         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8447 }
8448 run_test 65n "don't inherit default layout from root for new subdirectories"
8449
8450 # bug 2543 - update blocks count on client
8451 test_66() {
8452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8453
8454         COUNT=${COUNT:-8}
8455         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8456         sync; sync_all_data; sync; sync_all_data
8457         cancel_lru_locks osc
8458         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8459         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8460 }
8461 run_test 66 "update inode blocks count on client ==============="
8462
8463 meminfo() {
8464         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8465 }
8466
8467 swap_used() {
8468         swapon -s | awk '($1 == "'$1'") { print $4 }'
8469 }
8470
8471 # bug5265, obdfilter oa2dentry return -ENOENT
8472 # #define OBD_FAIL_SRV_ENOENT 0x217
8473 test_69() {
8474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8475         remote_ost_nodsh && skip "remote OST with nodsh"
8476
8477         f="$DIR/$tfile"
8478         $LFS setstripe -c 1 -i 0 $f
8479
8480         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8481
8482         do_facet ost1 lctl set_param fail_loc=0x217
8483         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8484         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8485
8486         do_facet ost1 lctl set_param fail_loc=0
8487         $DIRECTIO write $f 0 2 || error "write error"
8488
8489         cancel_lru_locks osc
8490         $DIRECTIO read $f 0 1 || error "read error"
8491
8492         do_facet ost1 lctl set_param fail_loc=0x217
8493         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8494
8495         do_facet ost1 lctl set_param fail_loc=0
8496         rm -f $f
8497 }
8498 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8499
8500 test_71() {
8501         test_mkdir $DIR/$tdir
8502         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8503         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8504 }
8505 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8506
8507 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8509         [ "$RUNAS_ID" = "$UID" ] &&
8510                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8511         # Check that testing environment is properly set up. Skip if not
8512         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8513                 skip_env "User $RUNAS_ID does not exist - skipping"
8514
8515         touch $DIR/$tfile
8516         chmod 777 $DIR/$tfile
8517         chmod ug+s $DIR/$tfile
8518         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8519                 error "$RUNAS dd $DIR/$tfile failed"
8520         # See if we are still setuid/sgid
8521         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8522                 error "S/gid is not dropped on write"
8523         # Now test that MDS is updated too
8524         cancel_lru_locks mdc
8525         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8526                 error "S/gid is not dropped on MDS"
8527         rm -f $DIR/$tfile
8528 }
8529 run_test 72a "Test that remove suid works properly (bug5695) ===="
8530
8531 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8532         local perm
8533
8534         [ "$RUNAS_ID" = "$UID" ] &&
8535                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8536         [ "$RUNAS_ID" -eq 0 ] &&
8537                 skip_env "RUNAS_ID = 0 -- skipping"
8538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8539         # Check that testing environment is properly set up. Skip if not
8540         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8541                 skip_env "User $RUNAS_ID does not exist - skipping"
8542
8543         touch $DIR/${tfile}-f{g,u}
8544         test_mkdir $DIR/${tfile}-dg
8545         test_mkdir $DIR/${tfile}-du
8546         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8547         chmod g+s $DIR/${tfile}-{f,d}g
8548         chmod u+s $DIR/${tfile}-{f,d}u
8549         for perm in 777 2777 4777; do
8550                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8551                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8552                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8553                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8554         done
8555         true
8556 }
8557 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8558
8559 # bug 3462 - multiple simultaneous MDC requests
8560 test_73() {
8561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8562
8563         test_mkdir $DIR/d73-1
8564         test_mkdir $DIR/d73-2
8565         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8566         pid1=$!
8567
8568         lctl set_param fail_loc=0x80000129
8569         $MULTIOP $DIR/d73-1/f73-2 Oc &
8570         sleep 1
8571         lctl set_param fail_loc=0
8572
8573         $MULTIOP $DIR/d73-2/f73-3 Oc &
8574         pid3=$!
8575
8576         kill -USR1 $pid1
8577         wait $pid1 || return 1
8578
8579         sleep 25
8580
8581         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8582         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8583         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8584
8585         rm -rf $DIR/d73-*
8586 }
8587 run_test 73 "multiple MDC requests (should not deadlock)"
8588
8589 test_74a() { # bug 6149, 6184
8590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8591
8592         touch $DIR/f74a
8593         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8594         #
8595         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8596         # will spin in a tight reconnection loop
8597         $LCTL set_param fail_loc=0x8000030e
8598         # get any lock that won't be difficult - lookup works.
8599         ls $DIR/f74a
8600         $LCTL set_param fail_loc=0
8601         rm -f $DIR/f74a
8602         true
8603 }
8604 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8605
8606 test_74b() { # bug 13310
8607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8608
8609         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8610         #
8611         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8612         # will spin in a tight reconnection loop
8613         $LCTL set_param fail_loc=0x8000030e
8614         # get a "difficult" lock
8615         touch $DIR/f74b
8616         $LCTL set_param fail_loc=0
8617         rm -f $DIR/f74b
8618         true
8619 }
8620 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8621
8622 test_74c() {
8623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8624
8625         #define OBD_FAIL_LDLM_NEW_LOCK
8626         $LCTL set_param fail_loc=0x319
8627         touch $DIR/$tfile && error "touch successful"
8628         $LCTL set_param fail_loc=0
8629         true
8630 }
8631 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8632
8633 slab_lic=/sys/kernel/slab/lustre_inode_cache
8634 num_objects() {
8635         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8636         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8637                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8638 }
8639
8640 test_76() { # Now for b=20433, added originally in b=1443
8641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8642
8643         cancel_lru_locks osc
8644         # there may be some slab objects cached per core
8645         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8646         local before=$(num_objects)
8647         local count=$((512 * cpus))
8648         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8649         local margin=$((count / 10))
8650         if [[ -f $slab_lic/aliases ]]; then
8651                 local aliases=$(cat $slab_lic/aliases)
8652                 (( aliases > 0 )) && margin=$((margin * aliases))
8653         fi
8654
8655         echo "before slab objects: $before"
8656         for i in $(seq $count); do
8657                 touch $DIR/$tfile
8658                 rm -f $DIR/$tfile
8659         done
8660         cancel_lru_locks osc
8661         local after=$(num_objects)
8662         echo "created: $count, after slab objects: $after"
8663         # shared slab counts are not very accurate, allow significant margin
8664         # the main goal is that the cache growth is not permanently > $count
8665         while (( after > before + margin )); do
8666                 sleep 1
8667                 after=$(num_objects)
8668                 wait=$((wait + 1))
8669                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8670                 if (( wait > 60 )); then
8671                         error "inode slab grew from $before+$margin to $after"
8672                 fi
8673         done
8674 }
8675 run_test 76 "confirm clients recycle inodes properly ===="
8676
8677
8678 export ORIG_CSUM=""
8679 set_checksums()
8680 {
8681         # Note: in sptlrpc modes which enable its own bulk checksum, the
8682         # original crc32_le bulk checksum will be automatically disabled,
8683         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8684         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8685         # In this case set_checksums() will not be no-op, because sptlrpc
8686         # bulk checksum will be enabled all through the test.
8687
8688         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8689         lctl set_param -n osc.*.checksums $1
8690         return 0
8691 }
8692
8693 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8694                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8695 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8696                              tr -d [] | head -n1)}
8697 set_checksum_type()
8698 {
8699         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8700         rc=$?
8701         log "set checksum type to $1, rc = $rc"
8702         return $rc
8703 }
8704
8705 get_osc_checksum_type()
8706 {
8707         # arugment 1: OST name, like OST0000
8708         ost=$1
8709         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8710                         sed 's/.*\[\(.*\)\].*/\1/g')
8711         rc=$?
8712         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8713         echo $checksum_type
8714 }
8715
8716 F77_TMP=$TMP/f77-temp
8717 F77SZ=8
8718 setup_f77() {
8719         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8720                 error "error writing to $F77_TMP"
8721 }
8722
8723 test_77a() { # bug 10889
8724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8725         $GSS && skip_env "could not run with gss"
8726
8727         [ ! -f $F77_TMP ] && setup_f77
8728         set_checksums 1
8729         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8730         set_checksums 0
8731         rm -f $DIR/$tfile
8732 }
8733 run_test 77a "normal checksum read/write operation"
8734
8735 test_77b() { # bug 10889
8736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8737         $GSS && skip_env "could not run with gss"
8738
8739         [ ! -f $F77_TMP ] && setup_f77
8740         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8741         $LCTL set_param fail_loc=0x80000409
8742         set_checksums 1
8743
8744         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8745                 error "dd error: $?"
8746         $LCTL set_param fail_loc=0
8747
8748         for algo in $CKSUM_TYPES; do
8749                 cancel_lru_locks osc
8750                 set_checksum_type $algo
8751                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8752                 $LCTL set_param fail_loc=0x80000408
8753                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8754                 $LCTL set_param fail_loc=0
8755         done
8756         set_checksums 0
8757         set_checksum_type $ORIG_CSUM_TYPE
8758         rm -f $DIR/$tfile
8759 }
8760 run_test 77b "checksum error on client write, read"
8761
8762 cleanup_77c() {
8763         trap 0
8764         set_checksums 0
8765         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8766         $check_ost &&
8767                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8768         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8769         $check_ost && [ -n "$ost_file_prefix" ] &&
8770                 do_facet ost1 rm -f ${ost_file_prefix}\*
8771 }
8772
8773 test_77c() {
8774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8775         $GSS && skip_env "could not run with gss"
8776         remote_ost_nodsh && skip "remote OST with nodsh"
8777
8778         local bad1
8779         local osc_file_prefix
8780         local osc_file
8781         local check_ost=false
8782         local ost_file_prefix
8783         local ost_file
8784         local orig_cksum
8785         local dump_cksum
8786         local fid
8787
8788         # ensure corruption will occur on first OSS/OST
8789         $LFS setstripe -i 0 $DIR/$tfile
8790
8791         [ ! -f $F77_TMP ] && setup_f77
8792         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8793                 error "dd write error: $?"
8794         fid=$($LFS path2fid $DIR/$tfile)
8795
8796         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8797         then
8798                 check_ost=true
8799                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8800                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8801         else
8802                 echo "OSS do not support bulk pages dump upon error"
8803         fi
8804
8805         osc_file_prefix=$($LCTL get_param -n debug_path)
8806         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8807
8808         trap cleanup_77c EXIT
8809
8810         set_checksums 1
8811         # enable bulk pages dump upon error on Client
8812         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8813         # enable bulk pages dump upon error on OSS
8814         $check_ost &&
8815                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8816
8817         # flush Client cache to allow next read to reach OSS
8818         cancel_lru_locks osc
8819
8820         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8821         $LCTL set_param fail_loc=0x80000408
8822         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8823         $LCTL set_param fail_loc=0
8824
8825         rm -f $DIR/$tfile
8826
8827         # check cksum dump on Client
8828         osc_file=$(ls ${osc_file_prefix}*)
8829         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8830         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8831         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8832         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8833         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8834                      cksum)
8835         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8836         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8837                 error "dump content does not match on Client"
8838
8839         $check_ost || skip "No need to check cksum dump on OSS"
8840
8841         # check cksum dump on OSS
8842         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8843         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8844         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8845         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8846         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8847                 error "dump content does not match on OSS"
8848
8849         cleanup_77c
8850 }
8851 run_test 77c "checksum error on client read with debug"
8852
8853 test_77d() { # bug 10889
8854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8855         $GSS && skip_env "could not run with gss"
8856
8857         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8858         $LCTL set_param fail_loc=0x80000409
8859         set_checksums 1
8860         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8861                 error "direct write: rc=$?"
8862         $LCTL set_param fail_loc=0
8863         set_checksums 0
8864
8865         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8866         $LCTL set_param fail_loc=0x80000408
8867         set_checksums 1
8868         cancel_lru_locks osc
8869         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8870                 error "direct read: rc=$?"
8871         $LCTL set_param fail_loc=0
8872         set_checksums 0
8873 }
8874 run_test 77d "checksum error on OST direct write, read"
8875
8876 test_77f() { # bug 10889
8877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8878         $GSS && skip_env "could not run with gss"
8879
8880         set_checksums 1
8881         for algo in $CKSUM_TYPES; do
8882                 cancel_lru_locks osc
8883                 set_checksum_type $algo
8884                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8885                 $LCTL set_param fail_loc=0x409
8886                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8887                         error "direct write succeeded"
8888                 $LCTL set_param fail_loc=0
8889         done
8890         set_checksum_type $ORIG_CSUM_TYPE
8891         set_checksums 0
8892 }
8893 run_test 77f "repeat checksum error on write (expect error)"
8894
8895 test_77g() { # bug 10889
8896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8897         $GSS && skip_env "could not run with gss"
8898         remote_ost_nodsh && skip "remote OST with nodsh"
8899
8900         [ ! -f $F77_TMP ] && setup_f77
8901
8902         local file=$DIR/$tfile
8903         stack_trap "rm -f $file" EXIT
8904
8905         $LFS setstripe -c 1 -i 0 $file
8906         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8907         do_facet ost1 lctl set_param fail_loc=0x8000021a
8908         set_checksums 1
8909         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8910                 error "write error: rc=$?"
8911         do_facet ost1 lctl set_param fail_loc=0
8912         set_checksums 0
8913
8914         cancel_lru_locks osc
8915         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8916         do_facet ost1 lctl set_param fail_loc=0x8000021b
8917         set_checksums 1
8918         cmp $F77_TMP $file || error "file compare failed"
8919         do_facet ost1 lctl set_param fail_loc=0
8920         set_checksums 0
8921 }
8922 run_test 77g "checksum error on OST write, read"
8923
8924 test_77k() { # LU-10906
8925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8926         $GSS && skip_env "could not run with gss"
8927
8928         local cksum_param="osc.$FSNAME*.checksums"
8929         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8930         local checksum
8931         local i
8932
8933         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8934         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
8935         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
8936
8937         for i in 0 1; do
8938                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8939                         error "failed to set checksum=$i on MGS"
8940                 wait_update $HOSTNAME "$get_checksum" $i
8941                 #remount
8942                 echo "remount client, checksum should be $i"
8943                 remount_client $MOUNT || error "failed to remount client"
8944                 checksum=$(eval $get_checksum)
8945                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8946         done
8947         # remove persistent param to avoid races with checksum mountopt below
8948         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8949                 error "failed to delete checksum on MGS"
8950
8951         for opt in "checksum" "nochecksum"; do
8952                 #remount with mount option
8953                 echo "remount client with option $opt, checksum should be $i"
8954                 umount_client $MOUNT || error "failed to umount client"
8955                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8956                         error "failed to mount client with option '$opt'"
8957                 checksum=$(eval $get_checksum)
8958                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8959                 i=$((i - 1))
8960         done
8961
8962         remount_client $MOUNT || error "failed to remount client"
8963 }
8964 run_test 77k "enable/disable checksum correctly"
8965
8966 test_77l() {
8967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8968         $GSS && skip_env "could not run with gss"
8969
8970         set_checksums 1
8971         stack_trap "set_checksums $ORIG_CSUM" EXIT
8972         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8973
8974         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8975
8976         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8977         for algo in $CKSUM_TYPES; do
8978                 set_checksum_type $algo || error "fail to set checksum type $algo"
8979                 osc_algo=$(get_osc_checksum_type OST0000)
8980                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8981
8982                 # no locks, no reqs to let the connection idle
8983                 cancel_lru_locks osc
8984                 lru_resize_disable osc
8985                 wait_osc_import_state client ost1 IDLE
8986
8987                 # ensure ost1 is connected
8988                 stat $DIR/$tfile >/dev/null || error "can't stat"
8989                 wait_osc_import_state client ost1 FULL
8990
8991                 osc_algo=$(get_osc_checksum_type OST0000)
8992                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8993         done
8994         return 0
8995 }
8996 run_test 77l "preferred checksum type is remembered after reconnected"
8997
8998 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8999 rm -f $F77_TMP
9000 unset F77_TMP
9001
9002 cleanup_test_78() {
9003         trap 0
9004         rm -f $DIR/$tfile
9005 }
9006
9007 test_78() { # bug 10901
9008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9009         remote_ost || skip_env "local OST"
9010
9011         NSEQ=5
9012         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9013         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9014         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9015         echo "MemTotal: $MEMTOTAL"
9016
9017         # reserve 256MB of memory for the kernel and other running processes,
9018         # and then take 1/2 of the remaining memory for the read/write buffers.
9019         if [ $MEMTOTAL -gt 512 ] ;then
9020                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9021         else
9022                 # for those poor memory-starved high-end clusters...
9023                 MEMTOTAL=$((MEMTOTAL / 2))
9024         fi
9025         echo "Mem to use for directio: $MEMTOTAL"
9026
9027         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9028         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9029         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9030         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9031                 head -n1)
9032         echo "Smallest OST: $SMALLESTOST"
9033         [[ $SMALLESTOST -lt 10240 ]] &&
9034                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9035
9036         trap cleanup_test_78 EXIT
9037
9038         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9039                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9040
9041         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9042         echo "File size: $F78SIZE"
9043         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9044         for i in $(seq 1 $NSEQ); do
9045                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9046                 echo directIO rdwr round $i of $NSEQ
9047                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9048         done
9049
9050         cleanup_test_78
9051 }
9052 run_test 78 "handle large O_DIRECT writes correctly ============"
9053
9054 test_79() { # bug 12743
9055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9056
9057         wait_delete_completed
9058
9059         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9060         BKFREE=$(calc_osc_kbytes kbytesfree)
9061         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9062
9063         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9064         DFTOTAL=`echo $STRING | cut -d, -f1`
9065         DFUSED=`echo $STRING  | cut -d, -f2`
9066         DFAVAIL=`echo $STRING | cut -d, -f3`
9067         DFFREE=$(($DFTOTAL - $DFUSED))
9068
9069         ALLOWANCE=$((64 * $OSTCOUNT))
9070
9071         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9072            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9073                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9074         fi
9075         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9076            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9077                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9078         fi
9079         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9080            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9081                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9082         fi
9083 }
9084 run_test 79 "df report consistency check ======================="
9085
9086 test_80() { # bug 10718
9087         remote_ost_nodsh && skip "remote OST with nodsh"
9088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9089
9090         # relax strong synchronous semantics for slow backends like ZFS
9091         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9092                 local soc="obdfilter.*.sync_lock_cancel"
9093                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9094
9095                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9096                 if [ -z "$save" ]; then
9097                         soc="obdfilter.*.sync_on_lock_cancel"
9098                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9099                 fi
9100
9101                 if [ "$save" != "never" ]; then
9102                         local hosts=$(comma_list $(osts_nodes))
9103
9104                         do_nodes $hosts $LCTL set_param $soc=never
9105                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9106                 fi
9107         fi
9108
9109         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9110         sync; sleep 1; sync
9111         local before=$(date +%s)
9112         cancel_lru_locks osc
9113         local after=$(date +%s)
9114         local diff=$((after - before))
9115         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9116
9117         rm -f $DIR/$tfile
9118 }
9119 run_test 80 "Page eviction is equally fast at high offsets too"
9120
9121 test_81a() { # LU-456
9122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9123         remote_ost_nodsh && skip "remote OST with nodsh"
9124
9125         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9126         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9127         do_facet ost1 lctl set_param fail_loc=0x80000228
9128
9129         # write should trigger a retry and success
9130         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9131         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9132         RC=$?
9133         if [ $RC -ne 0 ] ; then
9134                 error "write should success, but failed for $RC"
9135         fi
9136 }
9137 run_test 81a "OST should retry write when get -ENOSPC ==============="
9138
9139 test_81b() { # LU-456
9140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9141         remote_ost_nodsh && skip "remote OST with nodsh"
9142
9143         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9144         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9145         do_facet ost1 lctl set_param fail_loc=0x228
9146
9147         # write should retry several times and return -ENOSPC finally
9148         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9149         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9150         RC=$?
9151         ENOSPC=28
9152         if [ $RC -ne $ENOSPC ] ; then
9153                 error "dd should fail for -ENOSPC, but succeed."
9154         fi
9155 }
9156 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9157
9158 test_99() {
9159         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9160
9161         test_mkdir $DIR/$tdir.cvsroot
9162         chown $RUNAS_ID $DIR/$tdir.cvsroot
9163
9164         cd $TMP
9165         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9166
9167         cd /etc/init.d
9168         # some versions of cvs import exit(1) when asked to import links or
9169         # files they can't read.  ignore those files.
9170         local toignore=$(find . -type l -printf '-I %f\n' -o \
9171                          ! -perm /4 -printf '-I %f\n')
9172         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9173                 $tdir.reposname vtag rtag
9174
9175         cd $DIR
9176         test_mkdir $DIR/$tdir.reposname
9177         chown $RUNAS_ID $DIR/$tdir.reposname
9178         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9179
9180         cd $DIR/$tdir.reposname
9181         $RUNAS touch foo99
9182         $RUNAS cvs add -m 'addmsg' foo99
9183         $RUNAS cvs update
9184         $RUNAS cvs commit -m 'nomsg' foo99
9185         rm -fr $DIR/$tdir.cvsroot
9186 }
9187 run_test 99 "cvs strange file/directory operations"
9188
9189 test_100() {
9190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9191         [[ "$NETTYPE" =~ tcp ]] ||
9192                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9193         remote_ost_nodsh && skip "remote OST with nodsh"
9194         remote_mds_nodsh && skip "remote MDS with nodsh"
9195         remote_servers ||
9196                 skip "useless for local single node setup"
9197
9198         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9199                 [ "$PROT" != "tcp" ] && continue
9200                 RPORT=$(echo $REMOTE | cut -d: -f2)
9201                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9202
9203                 rc=0
9204                 LPORT=`echo $LOCAL | cut -d: -f2`
9205                 if [ $LPORT -ge 1024 ]; then
9206                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9207                         netstat -tna
9208                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9209                 fi
9210         done
9211         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9212 }
9213 run_test 100 "check local port using privileged port ==========="
9214
9215 function get_named_value()
9216 {
9217     local tag
9218
9219     tag=$1
9220     while read ;do
9221         line=$REPLY
9222         case $line in
9223         $tag*)
9224             echo $line | sed "s/^$tag[ ]*//"
9225             break
9226             ;;
9227         esac
9228     done
9229 }
9230
9231 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9232                    awk '/^max_cached_mb/ { print $2 }')
9233
9234 cleanup_101a() {
9235         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9236         trap 0
9237 }
9238
9239 test_101a() {
9240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9241
9242         local s
9243         local discard
9244         local nreads=10000
9245         local cache_limit=32
9246
9247         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9248         trap cleanup_101a EXIT
9249         $LCTL set_param -n llite.*.read_ahead_stats 0
9250         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9251
9252         #
9253         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9254         #
9255         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9256         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9257
9258         discard=0
9259         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9260                 get_named_value 'read but discarded' | cut -d" " -f1); do
9261                         discard=$(($discard + $s))
9262         done
9263         cleanup_101a
9264
9265         $LCTL get_param osc.*-osc*.rpc_stats
9266         $LCTL get_param llite.*.read_ahead_stats
9267
9268         # Discard is generally zero, but sometimes a few random reads line up
9269         # and trigger larger readahead, which is wasted & leads to discards.
9270         if [[ $(($discard)) -gt $nreads ]]; then
9271                 error "too many ($discard) discarded pages"
9272         fi
9273         rm -f $DIR/$tfile || true
9274 }
9275 run_test 101a "check read-ahead for random reads"
9276
9277 setup_test101bc() {
9278         test_mkdir $DIR/$tdir
9279         local ssize=$1
9280         local FILE_LENGTH=$2
9281         STRIPE_OFFSET=0
9282
9283         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9284
9285         local list=$(comma_list $(osts_nodes))
9286         set_osd_param $list '' read_cache_enable 0
9287         set_osd_param $list '' writethrough_cache_enable 0
9288
9289         trap cleanup_test101bc EXIT
9290         # prepare the read-ahead file
9291         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9292
9293         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9294                                 count=$FILE_SIZE_MB 2> /dev/null
9295
9296 }
9297
9298 cleanup_test101bc() {
9299         trap 0
9300         rm -rf $DIR/$tdir
9301         rm -f $DIR/$tfile
9302
9303         local list=$(comma_list $(osts_nodes))
9304         set_osd_param $list '' read_cache_enable 1
9305         set_osd_param $list '' writethrough_cache_enable 1
9306 }
9307
9308 calc_total() {
9309         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9310 }
9311
9312 ra_check_101() {
9313         local READ_SIZE=$1
9314         local STRIPE_SIZE=$2
9315         local FILE_LENGTH=$3
9316         local RA_INC=1048576
9317         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9318         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9319                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9320         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9321                         get_named_value 'read but discarded' |
9322                         cut -d" " -f1 | calc_total)
9323         if [[ $DISCARD -gt $discard_limit ]]; then
9324                 $LCTL get_param llite.*.read_ahead_stats
9325                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9326         else
9327                 echo "Read-ahead success for size ${READ_SIZE}"
9328         fi
9329 }
9330
9331 test_101b() {
9332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9333         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9334
9335         local STRIPE_SIZE=1048576
9336         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9337
9338         if [ $SLOW == "yes" ]; then
9339                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9340         else
9341                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9342         fi
9343
9344         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9345
9346         # prepare the read-ahead file
9347         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9348         cancel_lru_locks osc
9349         for BIDX in 2 4 8 16 32 64 128 256
9350         do
9351                 local BSIZE=$((BIDX*4096))
9352                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9353                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9354                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9355                 $LCTL set_param -n llite.*.read_ahead_stats 0
9356                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9357                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9358                 cancel_lru_locks osc
9359                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9360         done
9361         cleanup_test101bc
9362         true
9363 }
9364 run_test 101b "check stride-io mode read-ahead ================="
9365
9366 test_101c() {
9367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9368
9369         local STRIPE_SIZE=1048576
9370         local FILE_LENGTH=$((STRIPE_SIZE*100))
9371         local nreads=10000
9372         local rsize=65536
9373         local osc_rpc_stats
9374
9375         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9376
9377         cancel_lru_locks osc
9378         $LCTL set_param osc.*.rpc_stats 0
9379         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9380         $LCTL get_param osc.*.rpc_stats
9381         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9382                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9383                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9384                 local size
9385
9386                 if [ $lines -le 20 ]; then
9387                         echo "continue debug"
9388                         continue
9389                 fi
9390                 for size in 1 2 4 8; do
9391                         local rpc=$(echo "$stats" |
9392                                     awk '($1 == "'$size':") {print $2; exit; }')
9393                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9394                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9395                 done
9396                 echo "$osc_rpc_stats check passed!"
9397         done
9398         cleanup_test101bc
9399         true
9400 }
9401 run_test 101c "check stripe_size aligned read-ahead ================="
9402
9403 test_101d() {
9404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9405
9406         local file=$DIR/$tfile
9407         local sz_MB=${FILESIZE_101d:-80}
9408         local ra_MB=${READAHEAD_MB:-40}
9409
9410         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9411         [ $free_MB -lt $sz_MB ] &&
9412                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9413
9414         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9415         $LFS setstripe -c -1 $file || error "setstripe failed"
9416
9417         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9418         echo Cancel LRU locks on lustre client to flush the client cache
9419         cancel_lru_locks osc
9420
9421         echo Disable read-ahead
9422         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9423         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9424         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9425         $LCTL get_param -n llite.*.max_read_ahead_mb
9426
9427         echo "Reading the test file $file with read-ahead disabled"
9428         local sz_KB=$((sz_MB * 1024 / 4))
9429         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9430         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9431         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9432                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9433
9434         echo "Cancel LRU locks on lustre client to flush the client cache"
9435         cancel_lru_locks osc
9436         echo Enable read-ahead with ${ra_MB}MB
9437         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9438
9439         echo "Reading the test file $file with read-ahead enabled"
9440         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9441                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9442
9443         echo "read-ahead disabled time read $raOFF"
9444         echo "read-ahead enabled time read $raON"
9445
9446         rm -f $file
9447         wait_delete_completed
9448
9449         # use awk for this check instead of bash because it handles decimals
9450         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9451                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9452 }
9453 run_test 101d "file read with and without read-ahead enabled"
9454
9455 test_101e() {
9456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9457
9458         local file=$DIR/$tfile
9459         local size_KB=500  #KB
9460         local count=100
9461         local bsize=1024
9462
9463         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9464         local need_KB=$((count * size_KB))
9465         [[ $free_KB -le $need_KB ]] &&
9466                 skip_env "Need free space $need_KB, have $free_KB"
9467
9468         echo "Creating $count ${size_KB}K test files"
9469         for ((i = 0; i < $count; i++)); do
9470                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9471         done
9472
9473         echo "Cancel LRU locks on lustre client to flush the client cache"
9474         cancel_lru_locks $OSC
9475
9476         echo "Reset readahead stats"
9477         $LCTL set_param -n llite.*.read_ahead_stats 0
9478
9479         for ((i = 0; i < $count; i++)); do
9480                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9481         done
9482
9483         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9484                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9485
9486         for ((i = 0; i < $count; i++)); do
9487                 rm -rf $file.$i 2>/dev/null
9488         done
9489
9490         #10000 means 20% reads are missing in readahead
9491         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9492 }
9493 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9494
9495 test_101f() {
9496         which iozone || skip_env "no iozone installed"
9497
9498         local old_debug=$($LCTL get_param debug)
9499         old_debug=${old_debug#*=}
9500         $LCTL set_param debug="reada mmap"
9501
9502         # create a test file
9503         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9504
9505         echo Cancel LRU locks on lustre client to flush the client cache
9506         cancel_lru_locks osc
9507
9508         echo Reset readahead stats
9509         $LCTL set_param -n llite.*.read_ahead_stats 0
9510
9511         echo mmap read the file with small block size
9512         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9513                 > /dev/null 2>&1
9514
9515         echo checking missing pages
9516         $LCTL get_param llite.*.read_ahead_stats
9517         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9518                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9519
9520         $LCTL set_param debug="$old_debug"
9521         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9522         rm -f $DIR/$tfile
9523 }
9524 run_test 101f "check mmap read performance"
9525
9526 test_101g_brw_size_test() {
9527         local mb=$1
9528         local pages=$((mb * 1048576 / PAGE_SIZE))
9529         local file=$DIR/$tfile
9530
9531         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9532                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9533         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9534                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9535                         return 2
9536         done
9537
9538         stack_trap "rm -f $file" EXIT
9539         $LCTL set_param -n osc.*.rpc_stats=0
9540
9541         # 10 RPCs should be enough for the test
9542         local count=10
9543         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9544                 { error "dd write ${mb} MB blocks failed"; return 3; }
9545         cancel_lru_locks osc
9546         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9547                 { error "dd write ${mb} MB blocks failed"; return 4; }
9548
9549         # calculate number of full-sized read and write RPCs
9550         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9551                 sed -n '/pages per rpc/,/^$/p' |
9552                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9553                 END { print reads,writes }'))
9554         # allow one extra full-sized read RPC for async readahead
9555         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9556                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9557         [[ ${rpcs[1]} == $count ]] ||
9558                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9559 }
9560
9561 test_101g() {
9562         remote_ost_nodsh && skip "remote OST with nodsh"
9563
9564         local rpcs
9565         local osts=$(get_facets OST)
9566         local list=$(comma_list $(osts_nodes))
9567         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9568         local brw_size="obdfilter.*.brw_size"
9569
9570         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9571
9572         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9573
9574         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9575                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9576                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9577            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9578                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9579                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9580
9581                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9582                         suffix="M"
9583
9584                 if [[ $orig_mb -lt 16 ]]; then
9585                         save_lustre_params $osts "$brw_size" > $p
9586                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9587                                 error "set 16MB RPC size failed"
9588
9589                         echo "remount client to enable new RPC size"
9590                         remount_client $MOUNT || error "remount_client failed"
9591                 fi
9592
9593                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9594                 # should be able to set brw_size=12, but no rpc_stats for that
9595                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9596         fi
9597
9598         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9599
9600         if [[ $orig_mb -lt 16 ]]; then
9601                 restore_lustre_params < $p
9602                 remount_client $MOUNT || error "remount_client restore failed"
9603         fi
9604
9605         rm -f $p $DIR/$tfile
9606 }
9607 run_test 101g "Big bulk(4/16 MiB) readahead"
9608
9609 test_101h() {
9610         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9611
9612         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9613                 error "dd 70M file failed"
9614         echo Cancel LRU locks on lustre client to flush the client cache
9615         cancel_lru_locks osc
9616
9617         echo "Reset readahead stats"
9618         $LCTL set_param -n llite.*.read_ahead_stats 0
9619
9620         echo "Read 10M of data but cross 64M bundary"
9621         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9622         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9623                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9624         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9625         rm -f $p $DIR/$tfile
9626 }
9627 run_test 101h "Readahead should cover current read window"
9628
9629 test_101i() {
9630         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9631                 error "dd 10M file failed"
9632
9633         local max_per_file_mb=$($LCTL get_param -n \
9634                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9635         cancel_lru_locks osc
9636         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9637         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9638                 error "set max_read_ahead_per_file_mb to 1 failed"
9639
9640         echo "Reset readahead stats"
9641         $LCTL set_param llite.*.read_ahead_stats=0
9642
9643         dd if=$DIR/$tfile of=/dev/null bs=2M
9644
9645         $LCTL get_param llite.*.read_ahead_stats
9646         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9647                      awk '/misses/ { print $2 }')
9648         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9649         rm -f $DIR/$tfile
9650 }
9651 run_test 101i "allow current readahead to exceed reservation"
9652
9653 test_101j() {
9654         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9655                 error "setstripe $DIR/$tfile failed"
9656         local file_size=$((1048576 * 16))
9657         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9658         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9659
9660         echo Disable read-ahead
9661         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9662
9663         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9664         for blk in $PAGE_SIZE 1048576 $file_size; do
9665                 cancel_lru_locks osc
9666                 echo "Reset readahead stats"
9667                 $LCTL set_param -n llite.*.read_ahead_stats=0
9668                 local count=$(($file_size / $blk))
9669                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9670                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9671                              get_named_value 'failed to fast read' |
9672                              cut -d" " -f1 | calc_total)
9673                 $LCTL get_param -n llite.*.read_ahead_stats
9674                 [ $miss -eq $count ] || error "expected $count got $miss"
9675         done
9676
9677         rm -f $p $DIR/$tfile
9678 }
9679 run_test 101j "A complete read block should be submitted when no RA"
9680
9681 setup_test102() {
9682         test_mkdir $DIR/$tdir
9683         chown $RUNAS_ID $DIR/$tdir
9684         STRIPE_SIZE=65536
9685         STRIPE_OFFSET=1
9686         STRIPE_COUNT=$OSTCOUNT
9687         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9688
9689         trap cleanup_test102 EXIT
9690         cd $DIR
9691         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9692         cd $DIR/$tdir
9693         for num in 1 2 3 4; do
9694                 for count in $(seq 1 $STRIPE_COUNT); do
9695                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9696                                 local size=`expr $STRIPE_SIZE \* $num`
9697                                 local file=file"$num-$idx-$count"
9698                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9699                         done
9700                 done
9701         done
9702
9703         cd $DIR
9704         $1 tar cf $TMP/f102.tar $tdir --xattrs
9705 }
9706
9707 cleanup_test102() {
9708         trap 0
9709         rm -f $TMP/f102.tar
9710         rm -rf $DIR/d0.sanity/d102
9711 }
9712
9713 test_102a() {
9714         [ "$UID" != 0 ] && skip "must run as root"
9715         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9716                 skip_env "must have user_xattr"
9717
9718         [ -z "$(which setfattr 2>/dev/null)" ] &&
9719                 skip_env "could not find setfattr"
9720
9721         local testfile=$DIR/$tfile
9722
9723         touch $testfile
9724         echo "set/get xattr..."
9725         setfattr -n trusted.name1 -v value1 $testfile ||
9726                 error "setfattr -n trusted.name1=value1 $testfile failed"
9727         getfattr -n trusted.name1 $testfile 2> /dev/null |
9728           grep "trusted.name1=.value1" ||
9729                 error "$testfile missing trusted.name1=value1"
9730
9731         setfattr -n user.author1 -v author1 $testfile ||
9732                 error "setfattr -n user.author1=author1 $testfile failed"
9733         getfattr -n user.author1 $testfile 2> /dev/null |
9734           grep "user.author1=.author1" ||
9735                 error "$testfile missing trusted.author1=author1"
9736
9737         echo "listxattr..."
9738         setfattr -n trusted.name2 -v value2 $testfile ||
9739                 error "$testfile unable to set trusted.name2"
9740         setfattr -n trusted.name3 -v value3 $testfile ||
9741                 error "$testfile unable to set trusted.name3"
9742         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9743             grep "trusted.name" | wc -l) -eq 3 ] ||
9744                 error "$testfile missing 3 trusted.name xattrs"
9745
9746         setfattr -n user.author2 -v author2 $testfile ||
9747                 error "$testfile unable to set user.author2"
9748         setfattr -n user.author3 -v author3 $testfile ||
9749                 error "$testfile unable to set user.author3"
9750         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9751             grep "user.author" | wc -l) -eq 3 ] ||
9752                 error "$testfile missing 3 user.author xattrs"
9753
9754         echo "remove xattr..."
9755         setfattr -x trusted.name1 $testfile ||
9756                 error "$testfile error deleting trusted.name1"
9757         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9758                 error "$testfile did not delete trusted.name1 xattr"
9759
9760         setfattr -x user.author1 $testfile ||
9761                 error "$testfile error deleting user.author1"
9762         echo "set lustre special xattr ..."
9763         $LFS setstripe -c1 $testfile
9764         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9765                 awk -F "=" '/trusted.lov/ { print $2 }' )
9766         setfattr -n "trusted.lov" -v $lovea $testfile ||
9767                 error "$testfile doesn't ignore setting trusted.lov again"
9768         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9769                 error "$testfile allow setting invalid trusted.lov"
9770         rm -f $testfile
9771 }
9772 run_test 102a "user xattr test =================================="
9773
9774 check_102b_layout() {
9775         local layout="$*"
9776         local testfile=$DIR/$tfile
9777
9778         echo "test layout '$layout'"
9779         $LFS setstripe $layout $testfile || error "setstripe failed"
9780         $LFS getstripe -y $testfile
9781
9782         echo "get/set/list trusted.lov xattr ..." # b=10930
9783         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9784         [[ "$value" =~ "trusted.lov" ]] ||
9785                 error "can't get trusted.lov from $testfile"
9786         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9787                 error "getstripe failed"
9788
9789         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9790
9791         value=$(cut -d= -f2 <<<$value)
9792         # LU-13168: truncated xattr should fail if short lov_user_md header
9793         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9794                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9795         for len in $lens; do
9796                 echo "setfattr $len $testfile.2"
9797                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9798                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9799         done
9800         local stripe_size=$($LFS getstripe -S $testfile.2)
9801         local stripe_count=$($LFS getstripe -c $testfile.2)
9802         [[ $stripe_size -eq 65536 ]] ||
9803                 error "stripe size $stripe_size != 65536"
9804         [[ $stripe_count -eq $stripe_count_orig ]] ||
9805                 error "stripe count $stripe_count != $stripe_count_orig"
9806         rm $testfile $testfile.2
9807 }
9808
9809 test_102b() {
9810         [ -z "$(which setfattr 2>/dev/null)" ] &&
9811                 skip_env "could not find setfattr"
9812         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9813
9814         # check plain layout
9815         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9816
9817         # and also check composite layout
9818         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9819
9820 }
9821 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9822
9823 test_102c() {
9824         [ -z "$(which setfattr 2>/dev/null)" ] &&
9825                 skip_env "could not find setfattr"
9826         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9827
9828         # b10930: get/set/list lustre.lov xattr
9829         echo "get/set/list lustre.lov xattr ..."
9830         test_mkdir $DIR/$tdir
9831         chown $RUNAS_ID $DIR/$tdir
9832         local testfile=$DIR/$tdir/$tfile
9833         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9834                 error "setstripe failed"
9835         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9836                 error "getstripe failed"
9837         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9838         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9839
9840         local testfile2=${testfile}2
9841         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9842                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9843
9844         $RUNAS $MCREATE $testfile2
9845         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9846         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9847         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9848         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9849         [ $stripe_count -eq $STRIPECOUNT ] ||
9850                 error "stripe count $stripe_count != $STRIPECOUNT"
9851 }
9852 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9853
9854 compare_stripe_info1() {
9855         local stripe_index_all_zero=true
9856
9857         for num in 1 2 3 4; do
9858                 for count in $(seq 1 $STRIPE_COUNT); do
9859                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9860                                 local size=$((STRIPE_SIZE * num))
9861                                 local file=file"$num-$offset-$count"
9862                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9863                                 [[ $stripe_size -ne $size ]] &&
9864                                     error "$file: size $stripe_size != $size"
9865                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9866                                 # allow fewer stripes to be created, ORI-601
9867                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9868                                     error "$file: count $stripe_count != $count"
9869                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9870                                 [[ $stripe_index -ne 0 ]] &&
9871                                         stripe_index_all_zero=false
9872                         done
9873                 done
9874         done
9875         $stripe_index_all_zero &&
9876                 error "all files are being extracted starting from OST index 0"
9877         return 0
9878 }
9879
9880 have_xattrs_include() {
9881         tar --help | grep -q xattrs-include &&
9882                 echo --xattrs-include="lustre.*"
9883 }
9884
9885 test_102d() {
9886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9887         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9888
9889         XINC=$(have_xattrs_include)
9890         setup_test102
9891         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9892         cd $DIR/$tdir/$tdir
9893         compare_stripe_info1
9894 }
9895 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9896
9897 test_102f() {
9898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9899         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9900
9901         XINC=$(have_xattrs_include)
9902         setup_test102
9903         test_mkdir $DIR/$tdir.restore
9904         cd $DIR
9905         tar cf - --xattrs $tdir | tar xf - \
9906                 -C $DIR/$tdir.restore --xattrs $XINC
9907         cd $DIR/$tdir.restore/$tdir
9908         compare_stripe_info1
9909 }
9910 run_test 102f "tar copy files, not keep osts"
9911
9912 grow_xattr() {
9913         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9914                 skip "must have user_xattr"
9915         [ -z "$(which setfattr 2>/dev/null)" ] &&
9916                 skip_env "could not find setfattr"
9917         [ -z "$(which getfattr 2>/dev/null)" ] &&
9918                 skip_env "could not find getfattr"
9919
9920         local xsize=${1:-1024}  # in bytes
9921         local file=$DIR/$tfile
9922         local value="$(generate_string $xsize)"
9923         local xbig=trusted.big
9924         local toobig=$2
9925
9926         touch $file
9927         log "save $xbig on $file"
9928         if [ -z "$toobig" ]
9929         then
9930                 setfattr -n $xbig -v $value $file ||
9931                         error "saving $xbig on $file failed"
9932         else
9933                 setfattr -n $xbig -v $value $file &&
9934                         error "saving $xbig on $file succeeded"
9935                 return 0
9936         fi
9937
9938         local orig=$(get_xattr_value $xbig $file)
9939         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9940
9941         local xsml=trusted.sml
9942         log "save $xsml on $file"
9943         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9944
9945         local new=$(get_xattr_value $xbig $file)
9946         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9947
9948         log "grow $xsml on $file"
9949         setfattr -n $xsml -v "$value" $file ||
9950                 error "growing $xsml on $file failed"
9951
9952         new=$(get_xattr_value $xbig $file)
9953         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9954         log "$xbig still valid after growing $xsml"
9955
9956         rm -f $file
9957 }
9958
9959 test_102h() { # bug 15777
9960         grow_xattr 1024
9961 }
9962 run_test 102h "grow xattr from inside inode to external block"
9963
9964 test_102ha() {
9965         large_xattr_enabled || skip_env "ea_inode feature disabled"
9966
9967         echo "setting xattr of max xattr size: $(max_xattr_size)"
9968         grow_xattr $(max_xattr_size)
9969
9970         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9971         echo "This should fail:"
9972         grow_xattr $(($(max_xattr_size) + 10)) 1
9973 }
9974 run_test 102ha "grow xattr from inside inode to external inode"
9975
9976 test_102i() { # bug 17038
9977         [ -z "$(which getfattr 2>/dev/null)" ] &&
9978                 skip "could not find getfattr"
9979
9980         touch $DIR/$tfile
9981         ln -s $DIR/$tfile $DIR/${tfile}link
9982         getfattr -n trusted.lov $DIR/$tfile ||
9983                 error "lgetxattr on $DIR/$tfile failed"
9984         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9985                 grep -i "no such attr" ||
9986                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9987         rm -f $DIR/$tfile $DIR/${tfile}link
9988 }
9989 run_test 102i "lgetxattr test on symbolic link ============"
9990
9991 test_102j() {
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 "$RUNAS"
9997         chown $RUNAS_ID $DIR/$tdir
9998         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9999         cd $DIR/$tdir/$tdir
10000         compare_stripe_info1 "$RUNAS"
10001 }
10002 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10003
10004 test_102k() {
10005         [ -z "$(which setfattr 2>/dev/null)" ] &&
10006                 skip "could not find setfattr"
10007
10008         touch $DIR/$tfile
10009         # b22187 just check that does not crash for regular file.
10010         setfattr -n trusted.lov $DIR/$tfile
10011         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10012         local test_kdir=$DIR/$tdir
10013         test_mkdir $test_kdir
10014         local default_size=$($LFS getstripe -S $test_kdir)
10015         local default_count=$($LFS getstripe -c $test_kdir)
10016         local default_offset=$($LFS getstripe -i $test_kdir)
10017         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10018                 error 'dir setstripe failed'
10019         setfattr -n trusted.lov $test_kdir
10020         local stripe_size=$($LFS getstripe -S $test_kdir)
10021         local stripe_count=$($LFS getstripe -c $test_kdir)
10022         local stripe_offset=$($LFS getstripe -i $test_kdir)
10023         [ $stripe_size -eq $default_size ] ||
10024                 error "stripe size $stripe_size != $default_size"
10025         [ $stripe_count -eq $default_count ] ||
10026                 error "stripe count $stripe_count != $default_count"
10027         [ $stripe_offset -eq $default_offset ] ||
10028                 error "stripe offset $stripe_offset != $default_offset"
10029         rm -rf $DIR/$tfile $test_kdir
10030 }
10031 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10032
10033 test_102l() {
10034         [ -z "$(which getfattr 2>/dev/null)" ] &&
10035                 skip "could not find getfattr"
10036
10037         # LU-532 trusted. xattr is invisible to non-root
10038         local testfile=$DIR/$tfile
10039
10040         touch $testfile
10041
10042         echo "listxattr as user..."
10043         chown $RUNAS_ID $testfile
10044         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10045             grep -q "trusted" &&
10046                 error "$testfile trusted xattrs are user visible"
10047
10048         return 0;
10049 }
10050 run_test 102l "listxattr size test =================================="
10051
10052 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10053         local path=$DIR/$tfile
10054         touch $path
10055
10056         listxattr_size_check $path || error "listattr_size_check $path failed"
10057 }
10058 run_test 102m "Ensure listxattr fails on small bufffer ========"
10059
10060 cleanup_test102
10061
10062 getxattr() { # getxattr path name
10063         # Return the base64 encoding of the value of xattr name on path.
10064         local path=$1
10065         local name=$2
10066
10067         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10068         # file: $path
10069         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10070         #
10071         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10072
10073         getfattr --absolute-names --encoding=base64 --name=$name $path |
10074                 awk -F= -v name=$name '$1 == name {
10075                         print substr($0, index($0, "=") + 1);
10076         }'
10077 }
10078
10079 test_102n() { # LU-4101 mdt: protect internal xattrs
10080         [ -z "$(which setfattr 2>/dev/null)" ] &&
10081                 skip "could not find setfattr"
10082         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10083         then
10084                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10085         fi
10086
10087         local file0=$DIR/$tfile.0
10088         local file1=$DIR/$tfile.1
10089         local xattr0=$TMP/$tfile.0
10090         local xattr1=$TMP/$tfile.1
10091         local namelist="lov lma lmv link fid version som hsm"
10092         local name
10093         local value
10094
10095         rm -rf $file0 $file1 $xattr0 $xattr1
10096         touch $file0 $file1
10097
10098         # Get 'before' xattrs of $file1.
10099         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10100
10101         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10102                 namelist+=" lfsck_namespace"
10103         for name in $namelist; do
10104                 # Try to copy xattr from $file0 to $file1.
10105                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10106
10107                 setfattr --name=trusted.$name --value="$value" $file1 ||
10108                         error "setxattr 'trusted.$name' failed"
10109
10110                 # Try to set a garbage xattr.
10111                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10112
10113                 if [[ x$name == "xlov" ]]; then
10114                         setfattr --name=trusted.lov --value="$value" $file1 &&
10115                         error "setxattr invalid 'trusted.lov' success"
10116                 else
10117                         setfattr --name=trusted.$name --value="$value" $file1 ||
10118                                 error "setxattr invalid 'trusted.$name' failed"
10119                 fi
10120
10121                 # Try to remove the xattr from $file1. We don't care if this
10122                 # appears to succeed or fail, we just don't want there to be
10123                 # any changes or crashes.
10124                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10125         done
10126
10127         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10128         then
10129                 name="lfsck_ns"
10130                 # Try to copy xattr from $file0 to $file1.
10131                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10132
10133                 setfattr --name=trusted.$name --value="$value" $file1 ||
10134                         error "setxattr 'trusted.$name' failed"
10135
10136                 # Try to set a garbage xattr.
10137                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10138
10139                 setfattr --name=trusted.$name --value="$value" $file1 ||
10140                         error "setxattr 'trusted.$name' failed"
10141
10142                 # Try to remove the xattr from $file1. We don't care if this
10143                 # appears to succeed or fail, we just don't want there to be
10144                 # any changes or crashes.
10145                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10146         fi
10147
10148         # Get 'after' xattrs of file1.
10149         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10150
10151         if ! diff $xattr0 $xattr1; then
10152                 error "before and after xattrs of '$file1' differ"
10153         fi
10154
10155         rm -rf $file0 $file1 $xattr0 $xattr1
10156
10157         return 0
10158 }
10159 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10160
10161 test_102p() { # LU-4703 setxattr did not check ownership
10162         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10163                 skip "MDS needs to be at least 2.5.56"
10164
10165         local testfile=$DIR/$tfile
10166
10167         touch $testfile
10168
10169         echo "setfacl as user..."
10170         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10171         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10172
10173         echo "setfattr as user..."
10174         setfacl -m "u:$RUNAS_ID:---" $testfile
10175         $RUNAS setfattr -x system.posix_acl_access $testfile
10176         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10177 }
10178 run_test 102p "check setxattr(2) correctly fails without permission"
10179
10180 test_102q() {
10181         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10182                 skip "MDS needs to be at least 2.6.92"
10183
10184         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10185 }
10186 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10187
10188 test_102r() {
10189         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10190                 skip "MDS needs to be at least 2.6.93"
10191
10192         touch $DIR/$tfile || error "touch"
10193         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10194         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10195         rm $DIR/$tfile || error "rm"
10196
10197         #normal directory
10198         mkdir -p $DIR/$tdir || error "mkdir"
10199         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10200         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10201         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10202                 error "$testfile error deleting user.author1"
10203         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10204                 grep "user.$(basename $tdir)" &&
10205                 error "$tdir did not delete user.$(basename $tdir)"
10206         rmdir $DIR/$tdir || error "rmdir"
10207
10208         #striped directory
10209         test_mkdir $DIR/$tdir
10210         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10211         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10212         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10213                 error "$testfile error deleting user.author1"
10214         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10215                 grep "user.$(basename $tdir)" &&
10216                 error "$tdir did not delete user.$(basename $tdir)"
10217         rmdir $DIR/$tdir || error "rm striped dir"
10218 }
10219 run_test 102r "set EAs with empty values"
10220
10221 test_102s() {
10222         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10223                 skip "MDS needs to be at least 2.11.52"
10224
10225         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10226
10227         save_lustre_params client "llite.*.xattr_cache" > $save
10228
10229         for cache in 0 1; do
10230                 lctl set_param llite.*.xattr_cache=$cache
10231
10232                 rm -f $DIR/$tfile
10233                 touch $DIR/$tfile || error "touch"
10234                 for prefix in lustre security system trusted user; do
10235                         # Note getxattr() may fail with 'Operation not
10236                         # supported' or 'No such attribute' depending
10237                         # on prefix and cache.
10238                         getfattr -n $prefix.n102s $DIR/$tfile &&
10239                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10240                 done
10241         done
10242
10243         restore_lustre_params < $save
10244 }
10245 run_test 102s "getting nonexistent xattrs should fail"
10246
10247 test_102t() {
10248         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10249                 skip "MDS needs to be at least 2.11.52"
10250
10251         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10252
10253         save_lustre_params client "llite.*.xattr_cache" > $save
10254
10255         for cache in 0 1; do
10256                 lctl set_param llite.*.xattr_cache=$cache
10257
10258                 for buf_size in 0 256; do
10259                         rm -f $DIR/$tfile
10260                         touch $DIR/$tfile || error "touch"
10261                         setfattr -n user.multiop $DIR/$tfile
10262                         $MULTIOP $DIR/$tfile oa$buf_size ||
10263                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10264                 done
10265         done
10266
10267         restore_lustre_params < $save
10268 }
10269 run_test 102t "zero length xattr values handled correctly"
10270
10271 run_acl_subtest()
10272 {
10273     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10274     return $?
10275 }
10276
10277 test_103a() {
10278         [ "$UID" != 0 ] && skip "must run as root"
10279         $GSS && skip_env "could not run under gss"
10280         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10281                 skip_env "must have acl enabled"
10282         [ -z "$(which setfacl 2>/dev/null)" ] &&
10283                 skip_env "could not find setfacl"
10284         remote_mds_nodsh && skip "remote MDS with nodsh"
10285
10286         gpasswd -a daemon bin                           # LU-5641
10287         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10288
10289         declare -a identity_old
10290
10291         for num in $(seq $MDSCOUNT); do
10292                 switch_identity $num true || identity_old[$num]=$?
10293         done
10294
10295         SAVE_UMASK=$(umask)
10296         umask 0022
10297         mkdir -p $DIR/$tdir
10298         cd $DIR/$tdir
10299
10300         echo "performing cp ..."
10301         run_acl_subtest cp || error "run_acl_subtest cp failed"
10302         echo "performing getfacl-noacl..."
10303         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10304         echo "performing misc..."
10305         run_acl_subtest misc || error  "misc test failed"
10306         echo "performing permissions..."
10307         run_acl_subtest permissions || error "permissions failed"
10308         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10309         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10310                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10311                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10312         then
10313                 echo "performing permissions xattr..."
10314                 run_acl_subtest permissions_xattr ||
10315                         error "permissions_xattr failed"
10316         fi
10317         echo "performing setfacl..."
10318         run_acl_subtest setfacl || error  "setfacl test failed"
10319
10320         # inheritance test got from HP
10321         echo "performing inheritance..."
10322         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10323         chmod +x make-tree || error "chmod +x failed"
10324         run_acl_subtest inheritance || error "inheritance test failed"
10325         rm -f make-tree
10326
10327         echo "LU-974 ignore umask when acl is enabled..."
10328         run_acl_subtest 974 || error "LU-974 umask test failed"
10329         if [ $MDSCOUNT -ge 2 ]; then
10330                 run_acl_subtest 974_remote ||
10331                         error "LU-974 umask test failed under remote dir"
10332         fi
10333
10334         echo "LU-2561 newly created file is same size as directory..."
10335         if [ "$mds1_FSTYPE" != "zfs" ]; then
10336                 run_acl_subtest 2561 || error "LU-2561 test failed"
10337         else
10338                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10339         fi
10340
10341         run_acl_subtest 4924 || error "LU-4924 test failed"
10342
10343         cd $SAVE_PWD
10344         umask $SAVE_UMASK
10345
10346         for num in $(seq $MDSCOUNT); do
10347                 if [ "${identity_old[$num]}" = 1 ]; then
10348                         switch_identity $num false || identity_old[$num]=$?
10349                 fi
10350         done
10351 }
10352 run_test 103a "acl test"
10353
10354 test_103b() {
10355         declare -a pids
10356         local U
10357
10358         for U in {0..511}; do
10359                 {
10360                 local O=$(printf "%04o" $U)
10361
10362                 umask $(printf "%04o" $((511 ^ $O)))
10363                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10364                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10365
10366                 (( $S == ($O & 0666) )) ||
10367                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10368
10369                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10370                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10371                 (( $S == ($O & 0666) )) ||
10372                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10373
10374                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10375                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10376                 (( $S == ($O & 0666) )) ||
10377                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10378                 rm -f $DIR/$tfile.[smp]$0
10379                 } &
10380                 local pid=$!
10381
10382                 # limit the concurrently running threads to 64. LU-11878
10383                 local idx=$((U % 64))
10384                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10385                 pids[idx]=$pid
10386         done
10387         wait
10388 }
10389 run_test 103b "umask lfs setstripe"
10390
10391 test_103c() {
10392         mkdir -p $DIR/$tdir
10393         cp -rp $DIR/$tdir $DIR/$tdir.bak
10394
10395         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10396                 error "$DIR/$tdir shouldn't contain default ACL"
10397         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10398                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10399         true
10400 }
10401 run_test 103c "'cp -rp' won't set empty acl"
10402
10403 test_104a() {
10404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10405
10406         touch $DIR/$tfile
10407         lfs df || error "lfs df failed"
10408         lfs df -ih || error "lfs df -ih failed"
10409         lfs df -h $DIR || error "lfs df -h $DIR failed"
10410         lfs df -i $DIR || error "lfs df -i $DIR failed"
10411         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10412         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10413
10414         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10415         lctl --device %$OSC deactivate
10416         lfs df || error "lfs df with deactivated OSC failed"
10417         lctl --device %$OSC activate
10418         # wait the osc back to normal
10419         wait_osc_import_ready client ost
10420
10421         lfs df || error "lfs df with reactivated OSC failed"
10422         rm -f $DIR/$tfile
10423 }
10424 run_test 104a "lfs df [-ih] [path] test ========================="
10425
10426 test_104b() {
10427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10428         [ $RUNAS_ID -eq $UID ] &&
10429                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10430
10431         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10432                         grep "Permission denied" | wc -l)))
10433         if [ $denied_cnt -ne 0 ]; then
10434                 error "lfs check servers test failed"
10435         fi
10436 }
10437 run_test 104b "$RUNAS lfs check servers test ===================="
10438
10439 test_105a() {
10440         # doesn't work on 2.4 kernels
10441         touch $DIR/$tfile
10442         if $(flock_is_enabled); then
10443                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10444         else
10445                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10446         fi
10447         rm -f $DIR/$tfile
10448 }
10449 run_test 105a "flock when mounted without -o flock test ========"
10450
10451 test_105b() {
10452         touch $DIR/$tfile
10453         if $(flock_is_enabled); then
10454                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10455         else
10456                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10457         fi
10458         rm -f $DIR/$tfile
10459 }
10460 run_test 105b "fcntl when mounted without -o flock test ========"
10461
10462 test_105c() {
10463         touch $DIR/$tfile
10464         if $(flock_is_enabled); then
10465                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10466         else
10467                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10468         fi
10469         rm -f $DIR/$tfile
10470 }
10471 run_test 105c "lockf when mounted without -o flock test"
10472
10473 test_105d() { # bug 15924
10474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10475
10476         test_mkdir $DIR/$tdir
10477         flock_is_enabled || skip_env "mount w/o flock enabled"
10478         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10479         $LCTL set_param fail_loc=0x80000315
10480         flocks_test 2 $DIR/$tdir
10481 }
10482 run_test 105d "flock race (should not freeze) ========"
10483
10484 test_105e() { # bug 22660 && 22040
10485         flock_is_enabled || skip_env "mount w/o flock enabled"
10486
10487         touch $DIR/$tfile
10488         flocks_test 3 $DIR/$tfile
10489 }
10490 run_test 105e "Two conflicting flocks from same process"
10491
10492 test_106() { #bug 10921
10493         test_mkdir $DIR/$tdir
10494         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10495         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10496 }
10497 run_test 106 "attempt exec of dir followed by chown of that dir"
10498
10499 test_107() {
10500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10501
10502         CDIR=`pwd`
10503         local file=core
10504
10505         cd $DIR
10506         rm -f $file
10507
10508         local save_pattern=$(sysctl -n kernel.core_pattern)
10509         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10510         sysctl -w kernel.core_pattern=$file
10511         sysctl -w kernel.core_uses_pid=0
10512
10513         ulimit -c unlimited
10514         sleep 60 &
10515         SLEEPPID=$!
10516
10517         sleep 1
10518
10519         kill -s 11 $SLEEPPID
10520         wait $SLEEPPID
10521         if [ -e $file ]; then
10522                 size=`stat -c%s $file`
10523                 [ $size -eq 0 ] && error "Fail to create core file $file"
10524         else
10525                 error "Fail to create core file $file"
10526         fi
10527         rm -f $file
10528         sysctl -w kernel.core_pattern=$save_pattern
10529         sysctl -w kernel.core_uses_pid=$save_uses_pid
10530         cd $CDIR
10531 }
10532 run_test 107 "Coredump on SIG"
10533
10534 test_110() {
10535         test_mkdir $DIR/$tdir
10536         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10537         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10538                 error "mkdir with 256 char should fail, but did not"
10539         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10540                 error "create with 255 char failed"
10541         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10542                 error "create with 256 char should fail, but did not"
10543
10544         ls -l $DIR/$tdir
10545         rm -rf $DIR/$tdir
10546 }
10547 run_test 110 "filename length checking"
10548
10549 #
10550 # Purpose: To verify dynamic thread (OSS) creation.
10551 #
10552 test_115() {
10553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10554         remote_ost_nodsh && skip "remote OST with nodsh"
10555
10556         # Lustre does not stop service threads once they are started.
10557         # Reset number of running threads to default.
10558         stopall
10559         setupall
10560
10561         local OSTIO_pre
10562         local save_params="$TMP/sanity-$TESTNAME.parameters"
10563
10564         # Get ll_ost_io count before I/O
10565         OSTIO_pre=$(do_facet ost1 \
10566                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10567         # Exit if lustre is not running (ll_ost_io not running).
10568         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10569
10570         echo "Starting with $OSTIO_pre threads"
10571         local thread_max=$((OSTIO_pre * 2))
10572         local rpc_in_flight=$((thread_max * 2))
10573         # Number of I/O Process proposed to be started.
10574         local nfiles
10575         local facets=$(get_facets OST)
10576
10577         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10578         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10579
10580         # Set in_flight to $rpc_in_flight
10581         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10582                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10583         nfiles=${rpc_in_flight}
10584         # Set ost thread_max to $thread_max
10585         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10586
10587         # 5 Minutes should be sufficient for max number of OSS
10588         # threads(thread_max) to be created.
10589         local timeout=300
10590
10591         # Start I/O.
10592         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10593         test_mkdir $DIR/$tdir
10594         for i in $(seq $nfiles); do
10595                 local file=$DIR/$tdir/${tfile}-$i
10596                 $LFS setstripe -c -1 -i 0 $file
10597                 ($WTL $file $timeout)&
10598         done
10599
10600         # I/O Started - Wait for thread_started to reach thread_max or report
10601         # error if thread_started is more than thread_max.
10602         echo "Waiting for thread_started to reach thread_max"
10603         local thread_started=0
10604         local end_time=$((SECONDS + timeout))
10605
10606         while [ $SECONDS -le $end_time ] ; do
10607                 echo -n "."
10608                 # Get ost i/o thread_started count.
10609                 thread_started=$(do_facet ost1 \
10610                         "$LCTL get_param \
10611                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10612                 # Break out if thread_started is equal/greater than thread_max
10613                 if [[ $thread_started -ge $thread_max ]]; then
10614                         echo ll_ost_io thread_started $thread_started, \
10615                                 equal/greater than thread_max $thread_max
10616                         break
10617                 fi
10618                 sleep 1
10619         done
10620
10621         # Cleanup - We have the numbers, Kill i/o jobs if running.
10622         jobcount=($(jobs -p))
10623         for i in $(seq 0 $((${#jobcount[@]}-1)))
10624         do
10625                 kill -9 ${jobcount[$i]}
10626                 if [ $? -ne 0 ] ; then
10627                         echo Warning: \
10628                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10629                 fi
10630         done
10631
10632         # Cleanup files left by WTL binary.
10633         for i in $(seq $nfiles); do
10634                 local file=$DIR/$tdir/${tfile}-$i
10635                 rm -rf $file
10636                 if [ $? -ne 0 ] ; then
10637                         echo "Warning: Failed to delete file $file"
10638                 fi
10639         done
10640
10641         restore_lustre_params <$save_params
10642         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10643
10644         # Error out if no new thread has started or Thread started is greater
10645         # than thread max.
10646         if [[ $thread_started -le $OSTIO_pre ||
10647                         $thread_started -gt $thread_max ]]; then
10648                 error "ll_ost_io: thread_started $thread_started" \
10649                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10650                       "No new thread started or thread started greater " \
10651                       "than thread_max."
10652         fi
10653 }
10654 run_test 115 "verify dynamic thread creation===================="
10655
10656 free_min_max () {
10657         wait_delete_completed
10658         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10659         echo "OST kbytes available: ${AVAIL[@]}"
10660         MAXV=${AVAIL[0]}
10661         MAXI=0
10662         MINV=${AVAIL[0]}
10663         MINI=0
10664         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10665                 #echo OST $i: ${AVAIL[i]}kb
10666                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10667                         MAXV=${AVAIL[i]}
10668                         MAXI=$i
10669                 fi
10670                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10671                         MINV=${AVAIL[i]}
10672                         MINI=$i
10673                 fi
10674         done
10675         echo "Min free space: OST $MINI: $MINV"
10676         echo "Max free space: OST $MAXI: $MAXV"
10677 }
10678
10679 test_116a() { # was previously test_116()
10680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10681         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10682         remote_mds_nodsh && skip "remote MDS with nodsh"
10683
10684         echo -n "Free space priority "
10685         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10686                 head -n1
10687         declare -a AVAIL
10688         free_min_max
10689
10690         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10691         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10692         trap simple_cleanup_common EXIT
10693
10694         # Check if we need to generate uneven OSTs
10695         test_mkdir -p $DIR/$tdir/OST${MINI}
10696         local FILL=$((MINV / 4))
10697         local DIFF=$((MAXV - MINV))
10698         local DIFF2=$((DIFF * 100 / MINV))
10699
10700         local threshold=$(do_facet $SINGLEMDS \
10701                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10702         threshold=${threshold%%%}
10703         echo -n "Check for uneven OSTs: "
10704         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10705
10706         if [[ $DIFF2 -gt $threshold ]]; then
10707                 echo "ok"
10708                 echo "Don't need to fill OST$MINI"
10709         else
10710                 # generate uneven OSTs. Write 2% over the QOS threshold value
10711                 echo "no"
10712                 DIFF=$((threshold - DIFF2 + 2))
10713                 DIFF2=$((MINV * DIFF / 100))
10714                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10715                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10716                         error "setstripe failed"
10717                 DIFF=$((DIFF2 / 2048))
10718                 i=0
10719                 while [ $i -lt $DIFF ]; do
10720                         i=$((i + 1))
10721                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10722                                 bs=2M count=1 2>/dev/null
10723                         echo -n .
10724                 done
10725                 echo .
10726                 sync
10727                 sleep_maxage
10728                 free_min_max
10729         fi
10730
10731         DIFF=$((MAXV - MINV))
10732         DIFF2=$((DIFF * 100 / MINV))
10733         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10734         if [ $DIFF2 -gt $threshold ]; then
10735                 echo "ok"
10736         else
10737                 echo "failed - QOS mode won't be used"
10738                 simple_cleanup_common
10739                 skip "QOS imbalance criteria not met"
10740         fi
10741
10742         MINI1=$MINI
10743         MINV1=$MINV
10744         MAXI1=$MAXI
10745         MAXV1=$MAXV
10746
10747         # now fill using QOS
10748         $LFS setstripe -c 1 $DIR/$tdir
10749         FILL=$((FILL / 200))
10750         if [ $FILL -gt 600 ]; then
10751                 FILL=600
10752         fi
10753         echo "writing $FILL files to QOS-assigned OSTs"
10754         i=0
10755         while [ $i -lt $FILL ]; do
10756                 i=$((i + 1))
10757                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10758                         count=1 2>/dev/null
10759                 echo -n .
10760         done
10761         echo "wrote $i 200k files"
10762         sync
10763         sleep_maxage
10764
10765         echo "Note: free space may not be updated, so measurements might be off"
10766         free_min_max
10767         DIFF2=$((MAXV - MINV))
10768         echo "free space delta: orig $DIFF final $DIFF2"
10769         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10770         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10771         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10772         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10773         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10774         if [[ $DIFF -gt 0 ]]; then
10775                 FILL=$((DIFF2 * 100 / DIFF - 100))
10776                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10777         fi
10778
10779         # Figure out which files were written where
10780         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10781                awk '/'$MINI1': / {print $2; exit}')
10782         echo $UUID
10783         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10784         echo "$MINC files created on smaller OST $MINI1"
10785         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10786                awk '/'$MAXI1': / {print $2; exit}')
10787         echo $UUID
10788         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10789         echo "$MAXC files created on larger OST $MAXI1"
10790         if [[ $MINC -gt 0 ]]; then
10791                 FILL=$((MAXC * 100 / MINC - 100))
10792                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10793         fi
10794         [[ $MAXC -gt $MINC ]] ||
10795                 error_ignore LU-9 "stripe QOS didn't balance free space"
10796         simple_cleanup_common
10797 }
10798 run_test 116a "stripe QOS: free space balance ==================="
10799
10800 test_116b() { # LU-2093
10801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10802         remote_mds_nodsh && skip "remote MDS with nodsh"
10803
10804 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10805         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10806                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10807         [ -z "$old_rr" ] && skip "no QOS"
10808         do_facet $SINGLEMDS lctl set_param \
10809                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10810         mkdir -p $DIR/$tdir
10811         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10812         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10813         do_facet $SINGLEMDS lctl set_param fail_loc=0
10814         rm -rf $DIR/$tdir
10815         do_facet $SINGLEMDS lctl set_param \
10816                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10817 }
10818 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10819
10820 test_117() # bug 10891
10821 {
10822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10823
10824         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10825         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10826         lctl set_param fail_loc=0x21e
10827         > $DIR/$tfile || error "truncate failed"
10828         lctl set_param fail_loc=0
10829         echo "Truncate succeeded."
10830         rm -f $DIR/$tfile
10831 }
10832 run_test 117 "verify osd extend =========="
10833
10834 NO_SLOW_RESENDCOUNT=4
10835 export OLD_RESENDCOUNT=""
10836 set_resend_count () {
10837         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10838         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10839         lctl set_param -n $PROC_RESENDCOUNT $1
10840         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10841 }
10842
10843 # for reduce test_118* time (b=14842)
10844 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10845
10846 # Reset async IO behavior after error case
10847 reset_async() {
10848         FILE=$DIR/reset_async
10849
10850         # Ensure all OSCs are cleared
10851         $LFS setstripe -c -1 $FILE
10852         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10853         sync
10854         rm $FILE
10855 }
10856
10857 test_118a() #bug 11710
10858 {
10859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10860
10861         reset_async
10862
10863         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10864         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10865         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10866
10867         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10868                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10869                 return 1;
10870         fi
10871         rm -f $DIR/$tfile
10872 }
10873 run_test 118a "verify O_SYNC works =========="
10874
10875 test_118b()
10876 {
10877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10878         remote_ost_nodsh && skip "remote OST with nodsh"
10879
10880         reset_async
10881
10882         #define OBD_FAIL_SRV_ENOENT 0x217
10883         set_nodes_failloc "$(osts_nodes)" 0x217
10884         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10885         RC=$?
10886         set_nodes_failloc "$(osts_nodes)" 0
10887         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10888         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10889                     grep -c writeback)
10890
10891         if [[ $RC -eq 0 ]]; then
10892                 error "Must return error due to dropped pages, rc=$RC"
10893                 return 1;
10894         fi
10895
10896         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10897                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10898                 return 1;
10899         fi
10900
10901         echo "Dirty pages not leaked on ENOENT"
10902
10903         # Due to the above error the OSC will issue all RPCs syncronously
10904         # until a subsequent RPC completes successfully without error.
10905         $MULTIOP $DIR/$tfile Ow4096yc
10906         rm -f $DIR/$tfile
10907
10908         return 0
10909 }
10910 run_test 118b "Reclaim dirty pages on fatal error =========="
10911
10912 test_118c()
10913 {
10914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10915
10916         # for 118c, restore the original resend count, LU-1940
10917         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10918                                 set_resend_count $OLD_RESENDCOUNT
10919         remote_ost_nodsh && skip "remote OST with nodsh"
10920
10921         reset_async
10922
10923         #define OBD_FAIL_OST_EROFS               0x216
10924         set_nodes_failloc "$(osts_nodes)" 0x216
10925
10926         # multiop should block due to fsync until pages are written
10927         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10928         MULTIPID=$!
10929         sleep 1
10930
10931         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10932                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10933         fi
10934
10935         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10936                     grep -c writeback)
10937         if [[ $WRITEBACK -eq 0 ]]; then
10938                 error "No page in writeback, writeback=$WRITEBACK"
10939         fi
10940
10941         set_nodes_failloc "$(osts_nodes)" 0
10942         wait $MULTIPID
10943         RC=$?
10944         if [[ $RC -ne 0 ]]; then
10945                 error "Multiop fsync failed, rc=$RC"
10946         fi
10947
10948         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10949         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10950                     grep -c writeback)
10951         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10952                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10953         fi
10954
10955         rm -f $DIR/$tfile
10956         echo "Dirty pages flushed via fsync on EROFS"
10957         return 0
10958 }
10959 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10960
10961 # continue to use small resend count to reduce test_118* time (b=14842)
10962 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10963
10964 test_118d()
10965 {
10966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10967         remote_ost_nodsh && skip "remote OST with nodsh"
10968
10969         reset_async
10970
10971         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10972         set_nodes_failloc "$(osts_nodes)" 0x214
10973         # multiop should block due to fsync until pages are written
10974         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10975         MULTIPID=$!
10976         sleep 1
10977
10978         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10979                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10980         fi
10981
10982         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10983                     grep -c writeback)
10984         if [[ $WRITEBACK -eq 0 ]]; then
10985                 error "No page in writeback, writeback=$WRITEBACK"
10986         fi
10987
10988         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10989         set_nodes_failloc "$(osts_nodes)" 0
10990
10991         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10992         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10993                     grep -c writeback)
10994         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10995                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10996         fi
10997
10998         rm -f $DIR/$tfile
10999         echo "Dirty pages gaurenteed flushed via fsync"
11000         return 0
11001 }
11002 run_test 118d "Fsync validation inject a delay of the bulk =========="
11003
11004 test_118f() {
11005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11006
11007         reset_async
11008
11009         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11010         lctl set_param fail_loc=0x8000040a
11011
11012         # Should simulate EINVAL error which is fatal
11013         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11014         RC=$?
11015         if [[ $RC -eq 0 ]]; then
11016                 error "Must return error due to dropped pages, rc=$RC"
11017         fi
11018
11019         lctl set_param fail_loc=0x0
11020
11021         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11022         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11023         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11024                     grep -c writeback)
11025         if [[ $LOCKED -ne 0 ]]; then
11026                 error "Locked pages remain in cache, locked=$LOCKED"
11027         fi
11028
11029         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11030                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11031         fi
11032
11033         rm -f $DIR/$tfile
11034         echo "No pages locked after fsync"
11035
11036         reset_async
11037         return 0
11038 }
11039 run_test 118f "Simulate unrecoverable OSC side error =========="
11040
11041 test_118g() {
11042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11043
11044         reset_async
11045
11046         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11047         lctl set_param fail_loc=0x406
11048
11049         # simulate local -ENOMEM
11050         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11051         RC=$?
11052
11053         lctl set_param fail_loc=0
11054         if [[ $RC -eq 0 ]]; then
11055                 error "Must return error due to dropped pages, rc=$RC"
11056         fi
11057
11058         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11059         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11060         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11061                         grep -c writeback)
11062         if [[ $LOCKED -ne 0 ]]; then
11063                 error "Locked pages remain in cache, locked=$LOCKED"
11064         fi
11065
11066         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11067                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11068         fi
11069
11070         rm -f $DIR/$tfile
11071         echo "No pages locked after fsync"
11072
11073         reset_async
11074         return 0
11075 }
11076 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11077
11078 test_118h() {
11079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11080         remote_ost_nodsh && skip "remote OST with nodsh"
11081
11082         reset_async
11083
11084         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11085         set_nodes_failloc "$(osts_nodes)" 0x20e
11086         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11087         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11088         RC=$?
11089
11090         set_nodes_failloc "$(osts_nodes)" 0
11091         if [[ $RC -eq 0 ]]; then
11092                 error "Must return error due to dropped pages, rc=$RC"
11093         fi
11094
11095         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11096         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11097         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11098                     grep -c writeback)
11099         if [[ $LOCKED -ne 0 ]]; then
11100                 error "Locked pages remain in cache, locked=$LOCKED"
11101         fi
11102
11103         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11104                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11105         fi
11106
11107         rm -f $DIR/$tfile
11108         echo "No pages locked after fsync"
11109
11110         return 0
11111 }
11112 run_test 118h "Verify timeout in handling recoverables errors  =========="
11113
11114 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11115
11116 test_118i() {
11117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11118         remote_ost_nodsh && skip "remote OST with nodsh"
11119
11120         reset_async
11121
11122         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11123         set_nodes_failloc "$(osts_nodes)" 0x20e
11124
11125         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11126         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11127         PID=$!
11128         sleep 5
11129         set_nodes_failloc "$(osts_nodes)" 0
11130
11131         wait $PID
11132         RC=$?
11133         if [[ $RC -ne 0 ]]; then
11134                 error "got error, but should be not, rc=$RC"
11135         fi
11136
11137         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11138         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11139         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11140         if [[ $LOCKED -ne 0 ]]; then
11141                 error "Locked pages remain in cache, locked=$LOCKED"
11142         fi
11143
11144         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11145                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11146         fi
11147
11148         rm -f $DIR/$tfile
11149         echo "No pages locked after fsync"
11150
11151         return 0
11152 }
11153 run_test 118i "Fix error before timeout in recoverable error  =========="
11154
11155 [ "$SLOW" = "no" ] && set_resend_count 4
11156
11157 test_118j() {
11158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11159         remote_ost_nodsh && skip "remote OST with nodsh"
11160
11161         reset_async
11162
11163         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11164         set_nodes_failloc "$(osts_nodes)" 0x220
11165
11166         # return -EIO from OST
11167         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11168         RC=$?
11169         set_nodes_failloc "$(osts_nodes)" 0x0
11170         if [[ $RC -eq 0 ]]; then
11171                 error "Must return error due to dropped pages, rc=$RC"
11172         fi
11173
11174         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11175         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11176         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11177         if [[ $LOCKED -ne 0 ]]; then
11178                 error "Locked pages remain in cache, locked=$LOCKED"
11179         fi
11180
11181         # in recoverable error on OST we want resend and stay until it finished
11182         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11183                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11184         fi
11185
11186         rm -f $DIR/$tfile
11187         echo "No pages locked after fsync"
11188
11189         return 0
11190 }
11191 run_test 118j "Simulate unrecoverable OST side error =========="
11192
11193 test_118k()
11194 {
11195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11196         remote_ost_nodsh && skip "remote OSTs with nodsh"
11197
11198         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11199         set_nodes_failloc "$(osts_nodes)" 0x20e
11200         test_mkdir $DIR/$tdir
11201
11202         for ((i=0;i<10;i++)); do
11203                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11204                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11205                 SLEEPPID=$!
11206                 sleep 0.500s
11207                 kill $SLEEPPID
11208                 wait $SLEEPPID
11209         done
11210
11211         set_nodes_failloc "$(osts_nodes)" 0
11212         rm -rf $DIR/$tdir
11213 }
11214 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11215
11216 test_118l() # LU-646
11217 {
11218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11219
11220         test_mkdir $DIR/$tdir
11221         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11222         rm -rf $DIR/$tdir
11223 }
11224 run_test 118l "fsync dir"
11225
11226 test_118m() # LU-3066
11227 {
11228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11229
11230         test_mkdir $DIR/$tdir
11231         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11232         rm -rf $DIR/$tdir
11233 }
11234 run_test 118m "fdatasync dir ========="
11235
11236 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11237
11238 test_118n()
11239 {
11240         local begin
11241         local end
11242
11243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11244         remote_ost_nodsh && skip "remote OSTs with nodsh"
11245
11246         # Sleep to avoid a cached response.
11247         #define OBD_STATFS_CACHE_SECONDS 1
11248         sleep 2
11249
11250         # Inject a 10 second delay in the OST_STATFS handler.
11251         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11252         set_nodes_failloc "$(osts_nodes)" 0x242
11253
11254         begin=$SECONDS
11255         stat --file-system $MOUNT > /dev/null
11256         end=$SECONDS
11257
11258         set_nodes_failloc "$(osts_nodes)" 0
11259
11260         if ((end - begin > 20)); then
11261             error "statfs took $((end - begin)) seconds, expected 10"
11262         fi
11263 }
11264 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11265
11266 test_119a() # bug 11737
11267 {
11268         BSIZE=$((512 * 1024))
11269         directio write $DIR/$tfile 0 1 $BSIZE
11270         # We ask to read two blocks, which is more than a file size.
11271         # directio will indicate an error when requested and actual
11272         # sizes aren't equeal (a normal situation in this case) and
11273         # print actual read amount.
11274         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11275         if [ "$NOB" != "$BSIZE" ]; then
11276                 error "read $NOB bytes instead of $BSIZE"
11277         fi
11278         rm -f $DIR/$tfile
11279 }
11280 run_test 119a "Short directIO read must return actual read amount"
11281
11282 test_119b() # bug 11737
11283 {
11284         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11285
11286         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11287         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11288         sync
11289         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11290                 error "direct read failed"
11291         rm -f $DIR/$tfile
11292 }
11293 run_test 119b "Sparse directIO read must return actual read amount"
11294
11295 test_119c() # bug 13099
11296 {
11297         BSIZE=1048576
11298         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11299         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11300         rm -f $DIR/$tfile
11301 }
11302 run_test 119c "Testing for direct read hitting hole"
11303
11304 test_119d() # bug 15950
11305 {
11306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11307
11308         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11309         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11310         BSIZE=1048576
11311         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11312         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11313         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11314         lctl set_param fail_loc=0x40d
11315         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11316         pid_dio=$!
11317         sleep 1
11318         cat $DIR/$tfile > /dev/null &
11319         lctl set_param fail_loc=0
11320         pid_reads=$!
11321         wait $pid_dio
11322         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11323         sleep 2
11324         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11325         error "the read rpcs have not completed in 2s"
11326         rm -f $DIR/$tfile
11327         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11328 }
11329 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11330
11331 test_120a() {
11332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11333         remote_mds_nodsh && skip "remote MDS with nodsh"
11334         test_mkdir -i0 -c1 $DIR/$tdir
11335         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11336                 skip_env "no early lock cancel on server"
11337
11338         lru_resize_disable mdc
11339         lru_resize_disable osc
11340         cancel_lru_locks mdc
11341         # asynchronous object destroy at MDT could cause bl ast to client
11342         cancel_lru_locks osc
11343
11344         stat $DIR/$tdir > /dev/null
11345         can1=$(do_facet mds1 \
11346                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11347                awk '/ldlm_cancel/ {print $2}')
11348         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11349                awk '/ldlm_bl_callback/ {print $2}')
11350         test_mkdir -i0 -c1 $DIR/$tdir/d1
11351         can2=$(do_facet mds1 \
11352                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11353                awk '/ldlm_cancel/ {print $2}')
11354         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11355                awk '/ldlm_bl_callback/ {print $2}')
11356         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11357         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11358         lru_resize_enable mdc
11359         lru_resize_enable osc
11360 }
11361 run_test 120a "Early Lock Cancel: mkdir test"
11362
11363 test_120b() {
11364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11365         remote_mds_nodsh && skip "remote MDS with nodsh"
11366         test_mkdir $DIR/$tdir
11367         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11368                 skip_env "no early lock cancel on server"
11369
11370         lru_resize_disable mdc
11371         lru_resize_disable osc
11372         cancel_lru_locks mdc
11373         stat $DIR/$tdir > /dev/null
11374         can1=$(do_facet $SINGLEMDS \
11375                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11376                awk '/ldlm_cancel/ {print $2}')
11377         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11378                awk '/ldlm_bl_callback/ {print $2}')
11379         touch $DIR/$tdir/f1
11380         can2=$(do_facet $SINGLEMDS \
11381                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11382                awk '/ldlm_cancel/ {print $2}')
11383         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11384                awk '/ldlm_bl_callback/ {print $2}')
11385         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11386         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11387         lru_resize_enable mdc
11388         lru_resize_enable osc
11389 }
11390 run_test 120b "Early Lock Cancel: create test"
11391
11392 test_120c() {
11393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11394         remote_mds_nodsh && skip "remote MDS with nodsh"
11395         test_mkdir -i0 -c1 $DIR/$tdir
11396         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11397                 skip "no early lock cancel on server"
11398
11399         lru_resize_disable mdc
11400         lru_resize_disable osc
11401         test_mkdir -i0 -c1 $DIR/$tdir/d1
11402         test_mkdir -i0 -c1 $DIR/$tdir/d2
11403         touch $DIR/$tdir/d1/f1
11404         cancel_lru_locks mdc
11405         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11406         can1=$(do_facet mds1 \
11407                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11408                awk '/ldlm_cancel/ {print $2}')
11409         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11410                awk '/ldlm_bl_callback/ {print $2}')
11411         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11412         can2=$(do_facet mds1 \
11413                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11414                awk '/ldlm_cancel/ {print $2}')
11415         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11416                awk '/ldlm_bl_callback/ {print $2}')
11417         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11418         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11419         lru_resize_enable mdc
11420         lru_resize_enable osc
11421 }
11422 run_test 120c "Early Lock Cancel: link test"
11423
11424 test_120d() {
11425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11426         remote_mds_nodsh && skip "remote MDS with nodsh"
11427         test_mkdir -i0 -c1 $DIR/$tdir
11428         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11429                 skip_env "no early lock cancel on server"
11430
11431         lru_resize_disable mdc
11432         lru_resize_disable osc
11433         touch $DIR/$tdir
11434         cancel_lru_locks mdc
11435         stat $DIR/$tdir > /dev/null
11436         can1=$(do_facet mds1 \
11437                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11438                awk '/ldlm_cancel/ {print $2}')
11439         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11440                awk '/ldlm_bl_callback/ {print $2}')
11441         chmod a+x $DIR/$tdir
11442         can2=$(do_facet mds1 \
11443                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11444                awk '/ldlm_cancel/ {print $2}')
11445         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11446                awk '/ldlm_bl_callback/ {print $2}')
11447         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11448         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11449         lru_resize_enable mdc
11450         lru_resize_enable osc
11451 }
11452 run_test 120d "Early Lock Cancel: setattr test"
11453
11454 test_120e() {
11455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11456         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11457                 skip_env "no early lock cancel on server"
11458         remote_mds_nodsh && skip "remote MDS with nodsh"
11459
11460         local dlmtrace_set=false
11461
11462         test_mkdir -i0 -c1 $DIR/$tdir
11463         lru_resize_disable mdc
11464         lru_resize_disable osc
11465         ! $LCTL get_param debug | grep -q dlmtrace &&
11466                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11467         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11468         cancel_lru_locks mdc
11469         cancel_lru_locks osc
11470         dd if=$DIR/$tdir/f1 of=/dev/null
11471         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11472         # XXX client can not do early lock cancel of OST lock
11473         # during unlink (LU-4206), so cancel osc lock now.
11474         sleep 2
11475         cancel_lru_locks osc
11476         can1=$(do_facet mds1 \
11477                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11478                awk '/ldlm_cancel/ {print $2}')
11479         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11480                awk '/ldlm_bl_callback/ {print $2}')
11481         unlink $DIR/$tdir/f1
11482         sleep 5
11483         can2=$(do_facet mds1 \
11484                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11485                awk '/ldlm_cancel/ {print $2}')
11486         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11487                awk '/ldlm_bl_callback/ {print $2}')
11488         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11489                 $LCTL dk $TMP/cancel.debug.txt
11490         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11491                 $LCTL dk $TMP/blocking.debug.txt
11492         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11493         lru_resize_enable mdc
11494         lru_resize_enable osc
11495 }
11496 run_test 120e "Early Lock Cancel: unlink test"
11497
11498 test_120f() {
11499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11500         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11501                 skip_env "no early lock cancel on server"
11502         remote_mds_nodsh && skip "remote MDS with nodsh"
11503
11504         test_mkdir -i0 -c1 $DIR/$tdir
11505         lru_resize_disable mdc
11506         lru_resize_disable osc
11507         test_mkdir -i0 -c1 $DIR/$tdir/d1
11508         test_mkdir -i0 -c1 $DIR/$tdir/d2
11509         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11510         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11511         cancel_lru_locks mdc
11512         cancel_lru_locks osc
11513         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11514         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11515         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11516         # XXX client can not do early lock cancel of OST lock
11517         # during rename (LU-4206), so cancel osc lock now.
11518         sleep 2
11519         cancel_lru_locks osc
11520         can1=$(do_facet mds1 \
11521                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11522                awk '/ldlm_cancel/ {print $2}')
11523         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11524                awk '/ldlm_bl_callback/ {print $2}')
11525         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11526         sleep 5
11527         can2=$(do_facet mds1 \
11528                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11529                awk '/ldlm_cancel/ {print $2}')
11530         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11531                awk '/ldlm_bl_callback/ {print $2}')
11532         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11533         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11534         lru_resize_enable mdc
11535         lru_resize_enable osc
11536 }
11537 run_test 120f "Early Lock Cancel: rename test"
11538
11539 test_120g() {
11540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11541         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11542                 skip_env "no early lock cancel on server"
11543         remote_mds_nodsh && skip "remote MDS with nodsh"
11544
11545         lru_resize_disable mdc
11546         lru_resize_disable osc
11547         count=10000
11548         echo create $count files
11549         test_mkdir $DIR/$tdir
11550         cancel_lru_locks mdc
11551         cancel_lru_locks osc
11552         t0=$(date +%s)
11553
11554         can0=$(do_facet $SINGLEMDS \
11555                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11556                awk '/ldlm_cancel/ {print $2}')
11557         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11558                awk '/ldlm_bl_callback/ {print $2}')
11559         createmany -o $DIR/$tdir/f $count
11560         sync
11561         can1=$(do_facet $SINGLEMDS \
11562                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11563                awk '/ldlm_cancel/ {print $2}')
11564         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11565                awk '/ldlm_bl_callback/ {print $2}')
11566         t1=$(date +%s)
11567         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11568         echo rm $count files
11569         rm -r $DIR/$tdir
11570         sync
11571         can2=$(do_facet $SINGLEMDS \
11572                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11573                awk '/ldlm_cancel/ {print $2}')
11574         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11575                awk '/ldlm_bl_callback/ {print $2}')
11576         t2=$(date +%s)
11577         echo total: $count removes in $((t2-t1))
11578         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11579         sleep 2
11580         # wait for commitment of removal
11581         lru_resize_enable mdc
11582         lru_resize_enable osc
11583 }
11584 run_test 120g "Early Lock Cancel: performance test"
11585
11586 test_121() { #bug #10589
11587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11588
11589         rm -rf $DIR/$tfile
11590         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11591 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11592         lctl set_param fail_loc=0x310
11593         cancel_lru_locks osc > /dev/null
11594         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11595         lctl set_param fail_loc=0
11596         [[ $reads -eq $writes ]] ||
11597                 error "read $reads blocks, must be $writes blocks"
11598 }
11599 run_test 121 "read cancel race ========="
11600
11601 test_123a_base() { # was test 123, statahead(bug 11401)
11602         local lsx="$1"
11603
11604         SLOWOK=0
11605         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11606                 log "testing UP system. Performance may be lower than expected."
11607                 SLOWOK=1
11608         fi
11609
11610         rm -rf $DIR/$tdir
11611         test_mkdir $DIR/$tdir
11612         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11613         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11614         MULT=10
11615         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11616                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11617
11618                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11619                 lctl set_param -n llite.*.statahead_max 0
11620                 lctl get_param llite.*.statahead_max
11621                 cancel_lru_locks mdc
11622                 cancel_lru_locks osc
11623                 stime=$(date +%s)
11624                 time $lsx $DIR/$tdir | wc -l
11625                 etime=$(date +%s)
11626                 delta=$((etime - stime))
11627                 log "$lsx $i files without statahead: $delta sec"
11628                 lctl set_param llite.*.statahead_max=$max
11629
11630                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11631                         grep "statahead wrong:" | awk '{print $3}')
11632                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11633                 cancel_lru_locks mdc
11634                 cancel_lru_locks osc
11635                 stime=$(date +%s)
11636                 time $lsx $DIR/$tdir | wc -l
11637                 etime=$(date +%s)
11638                 delta_sa=$((etime - stime))
11639                 log "$lsx $i files with statahead: $delta_sa sec"
11640                 lctl get_param -n llite.*.statahead_stats
11641                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11642                         grep "statahead wrong:" | awk '{print $3}')
11643
11644                 [[ $swrong -lt $ewrong ]] &&
11645                         log "statahead was stopped, maybe too many locks held!"
11646                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11647
11648                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11649                         max=$(lctl get_param -n llite.*.statahead_max |
11650                                 head -n 1)
11651                         lctl set_param -n llite.*.statahead_max 0
11652                         lctl get_param llite.*.statahead_max
11653                         cancel_lru_locks mdc
11654                         cancel_lru_locks osc
11655                         stime=$(date +%s)
11656                         time $lsx $DIR/$tdir | wc -l
11657                         etime=$(date +%s)
11658                         delta=$((etime - stime))
11659                         log "$lsx $i files again without statahead: $delta sec"
11660                         lctl set_param llite.*.statahead_max=$max
11661                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11662                                 if [  $SLOWOK -eq 0 ]; then
11663                                         error "$lsx $i files is slower with statahead!"
11664                                 else
11665                                         log "$lsx $i files is slower with statahead!"
11666                                 fi
11667                                 break
11668                         fi
11669                 fi
11670
11671                 [ $delta -gt 20 ] && break
11672                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11673                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11674         done
11675         log "$lsx done"
11676
11677         stime=$(date +%s)
11678         rm -r $DIR/$tdir
11679         sync
11680         etime=$(date +%s)
11681         delta=$((etime - stime))
11682         log "rm -r $DIR/$tdir/: $delta seconds"
11683         log "rm done"
11684         lctl get_param -n llite.*.statahead_stats
11685 }
11686
11687 test_123aa() {
11688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11689
11690         test_123a_base "ls -l"
11691 }
11692 run_test 123aa "verify statahead work"
11693
11694 test_123ab() {
11695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11696
11697         statx_supported || skip_env "Test must be statx() syscall supported"
11698
11699         test_123a_base "$STATX -l"
11700 }
11701 run_test 123ab "verify statahead work by using statx"
11702
11703 test_123ac() {
11704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11705
11706         statx_supported || skip_env "Test must be statx() syscall supported"
11707
11708         local rpcs_before
11709         local rpcs_after
11710         local agl_before
11711         local agl_after
11712
11713         cancel_lru_locks $OSC
11714         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11715         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11716                 awk '/agl.total:/ {print $3}')
11717         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11718         test_123a_base "$STATX --cached=always -D"
11719         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11720                 awk '/agl.total:/ {print $3}')
11721         [ $agl_before -eq $agl_after ] ||
11722                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11723         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11724         [ $rpcs_after -eq $rpcs_before ] ||
11725                 error "$STATX should not send glimpse RPCs to $OSC"
11726 }
11727 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11728
11729 test_123b () { # statahead(bug 15027)
11730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11731
11732         test_mkdir $DIR/$tdir
11733         createmany -o $DIR/$tdir/$tfile-%d 1000
11734
11735         cancel_lru_locks mdc
11736         cancel_lru_locks osc
11737
11738 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11739         lctl set_param fail_loc=0x80000803
11740         ls -lR $DIR/$tdir > /dev/null
11741         log "ls done"
11742         lctl set_param fail_loc=0x0
11743         lctl get_param -n llite.*.statahead_stats
11744         rm -r $DIR/$tdir
11745         sync
11746
11747 }
11748 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11749
11750 test_123c() {
11751         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11752
11753         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11754         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11755         touch $DIR/$tdir.1/{1..3}
11756         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11757
11758         remount_client $MOUNT
11759
11760         $MULTIOP $DIR/$tdir.0 Q
11761
11762         # let statahead to complete
11763         ls -l $DIR/$tdir.0 > /dev/null
11764
11765         testid=$(echo $TESTNAME | tr '_' ' ')
11766         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11767                 error "statahead warning" || true
11768 }
11769 run_test 123c "Can not initialize inode warning on DNE statahead"
11770
11771 test_124a() {
11772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11773         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11774                 skip_env "no lru resize on server"
11775
11776         local NR=2000
11777
11778         test_mkdir $DIR/$tdir
11779
11780         log "create $NR files at $DIR/$tdir"
11781         createmany -o $DIR/$tdir/f $NR ||
11782                 error "failed to create $NR files in $DIR/$tdir"
11783
11784         cancel_lru_locks mdc
11785         ls -l $DIR/$tdir > /dev/null
11786
11787         local NSDIR=""
11788         local LRU_SIZE=0
11789         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11790                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11791                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11792                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11793                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11794                         log "NSDIR=$NSDIR"
11795                         log "NS=$(basename $NSDIR)"
11796                         break
11797                 fi
11798         done
11799
11800         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11801                 skip "Not enough cached locks created!"
11802         fi
11803         log "LRU=$LRU_SIZE"
11804
11805         local SLEEP=30
11806
11807         # We know that lru resize allows one client to hold $LIMIT locks
11808         # for 10h. After that locks begin to be killed by client.
11809         local MAX_HRS=10
11810         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11811         log "LIMIT=$LIMIT"
11812         if [ $LIMIT -lt $LRU_SIZE ]; then
11813                 skip "Limit is too small $LIMIT"
11814         fi
11815
11816         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11817         # killing locks. Some time was spent for creating locks. This means
11818         # that up to the moment of sleep finish we must have killed some of
11819         # them (10-100 locks). This depends on how fast ther were created.
11820         # Many of them were touched in almost the same moment and thus will
11821         # be killed in groups.
11822         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
11823
11824         # Use $LRU_SIZE_B here to take into account real number of locks
11825         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11826         local LRU_SIZE_B=$LRU_SIZE
11827         log "LVF=$LVF"
11828         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11829         log "OLD_LVF=$OLD_LVF"
11830         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11831
11832         # Let's make sure that we really have some margin. Client checks
11833         # cached locks every 10 sec.
11834         SLEEP=$((SLEEP+20))
11835         log "Sleep ${SLEEP} sec"
11836         local SEC=0
11837         while ((SEC<$SLEEP)); do
11838                 echo -n "..."
11839                 sleep 5
11840                 SEC=$((SEC+5))
11841                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11842                 echo -n "$LRU_SIZE"
11843         done
11844         echo ""
11845         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11846         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11847
11848         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11849                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11850                 unlinkmany $DIR/$tdir/f $NR
11851                 return
11852         }
11853
11854         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11855         log "unlink $NR files at $DIR/$tdir"
11856         unlinkmany $DIR/$tdir/f $NR
11857 }
11858 run_test 124a "lru resize ======================================="
11859
11860 get_max_pool_limit()
11861 {
11862         local limit=$($LCTL get_param \
11863                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11864         local max=0
11865         for l in $limit; do
11866                 if [[ $l -gt $max ]]; then
11867                         max=$l
11868                 fi
11869         done
11870         echo $max
11871 }
11872
11873 test_124b() {
11874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11875         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11876                 skip_env "no lru resize on server"
11877
11878         LIMIT=$(get_max_pool_limit)
11879
11880         NR=$(($(default_lru_size)*20))
11881         if [[ $NR -gt $LIMIT ]]; then
11882                 log "Limit lock number by $LIMIT locks"
11883                 NR=$LIMIT
11884         fi
11885
11886         IFree=$(mdsrate_inodes_available)
11887         if [ $IFree -lt $NR ]; then
11888                 log "Limit lock number by $IFree inodes"
11889                 NR=$IFree
11890         fi
11891
11892         lru_resize_disable mdc
11893         test_mkdir -p $DIR/$tdir/disable_lru_resize
11894
11895         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11896         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11897         cancel_lru_locks mdc
11898         stime=`date +%s`
11899         PID=""
11900         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11901         PID="$PID $!"
11902         sleep 2
11903         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11904         PID="$PID $!"
11905         sleep 2
11906         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11907         PID="$PID $!"
11908         wait $PID
11909         etime=`date +%s`
11910         nolruresize_delta=$((etime-stime))
11911         log "ls -la time: $nolruresize_delta seconds"
11912         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11913         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11914
11915         lru_resize_enable mdc
11916         test_mkdir -p $DIR/$tdir/enable_lru_resize
11917
11918         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11919         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11920         cancel_lru_locks mdc
11921         stime=`date +%s`
11922         PID=""
11923         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11924         PID="$PID $!"
11925         sleep 2
11926         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11927         PID="$PID $!"
11928         sleep 2
11929         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11930         PID="$PID $!"
11931         wait $PID
11932         etime=`date +%s`
11933         lruresize_delta=$((etime-stime))
11934         log "ls -la time: $lruresize_delta seconds"
11935         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11936
11937         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11938                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11939         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11940                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11941         else
11942                 log "lru resize performs the same with no lru resize"
11943         fi
11944         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11945 }
11946 run_test 124b "lru resize (performance test) ======================="
11947
11948 test_124c() {
11949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11950         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11951                 skip_env "no lru resize on server"
11952
11953         # cache ununsed locks on client
11954         local nr=100
11955         cancel_lru_locks mdc
11956         test_mkdir $DIR/$tdir
11957         createmany -o $DIR/$tdir/f $nr ||
11958                 error "failed to create $nr files in $DIR/$tdir"
11959         ls -l $DIR/$tdir > /dev/null
11960
11961         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11962         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11963         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11964         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11965         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11966
11967         # set lru_max_age to 1 sec
11968         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11969         echo "sleep $((recalc_p * 2)) seconds..."
11970         sleep $((recalc_p * 2))
11971
11972         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11973         # restore lru_max_age
11974         $LCTL set_param -n $nsdir.lru_max_age $max_age
11975         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11976         unlinkmany $DIR/$tdir/f $nr
11977 }
11978 run_test 124c "LRUR cancel very aged locks"
11979
11980 test_124d() {
11981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11982         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11983                 skip_env "no lru resize on server"
11984
11985         # cache ununsed locks on client
11986         local nr=100
11987
11988         lru_resize_disable mdc
11989         stack_trap "lru_resize_enable mdc" EXIT
11990
11991         cancel_lru_locks mdc
11992
11993         # asynchronous object destroy at MDT could cause bl ast to client
11994         test_mkdir $DIR/$tdir
11995         createmany -o $DIR/$tdir/f $nr ||
11996                 error "failed to create $nr files in $DIR/$tdir"
11997         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11998
11999         ls -l $DIR/$tdir > /dev/null
12000
12001         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12002         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12003         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12004         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12005
12006         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12007
12008         # set lru_max_age to 1 sec
12009         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12010         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12011
12012         echo "sleep $((recalc_p * 2)) seconds..."
12013         sleep $((recalc_p * 2))
12014
12015         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12016
12017         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12018 }
12019 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12020
12021 test_125() { # 13358
12022         $LCTL get_param -n llite.*.client_type | grep -q local ||
12023                 skip "must run as local client"
12024         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12025                 skip_env "must have acl enabled"
12026         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12027
12028         test_mkdir $DIR/$tdir
12029         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12030         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12031         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12032 }
12033 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12034
12035 test_126() { # bug 12829/13455
12036         $GSS && skip_env "must run as gss disabled"
12037         $LCTL get_param -n llite.*.client_type | grep -q local ||
12038                 skip "must run as local client"
12039         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12040
12041         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12042         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12043         rm -f $DIR/$tfile
12044         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12045 }
12046 run_test 126 "check that the fsgid provided by the client is taken into account"
12047
12048 test_127a() { # bug 15521
12049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12050         local name count samp unit min max sum sumsq
12051
12052         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12053         echo "stats before reset"
12054         $LCTL get_param osc.*.stats
12055         $LCTL set_param osc.*.stats=0
12056         local fsize=$((2048 * 1024))
12057
12058         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12059         cancel_lru_locks osc
12060         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12061
12062         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12063         stack_trap "rm -f $TMP/$tfile.tmp"
12064         while read name count samp unit min max sum sumsq; do
12065                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12066                 [ ! $min ] && error "Missing min value for $name proc entry"
12067                 eval $name=$count || error "Wrong proc format"
12068
12069                 case $name in
12070                 read_bytes|write_bytes)
12071                         [[ "$unit" =~ "bytes" ]] ||
12072                                 error "unit is not 'bytes': $unit"
12073                         (( $min >= 4096 )) || error "min is too small: $min"
12074                         (( $min <= $fsize )) || error "min is too big: $min"
12075                         (( $max >= 4096 )) || error "max is too small: $max"
12076                         (( $max <= $fsize )) || error "max is too big: $max"
12077                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12078                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12079                                 error "sumsquare is too small: $sumsq"
12080                         (( $sumsq <= $fsize * $fsize )) ||
12081                                 error "sumsquare is too big: $sumsq"
12082                         ;;
12083                 ost_read|ost_write)
12084                         [[ "$unit" =~ "usec" ]] ||
12085                                 error "unit is not 'usec': $unit"
12086                         ;;
12087                 *)      ;;
12088                 esac
12089         done < $DIR/$tfile.tmp
12090
12091         #check that we actually got some stats
12092         [ "$read_bytes" ] || error "Missing read_bytes stats"
12093         [ "$write_bytes" ] || error "Missing write_bytes stats"
12094         [ "$read_bytes" != 0 ] || error "no read done"
12095         [ "$write_bytes" != 0 ] || error "no write done"
12096 }
12097 run_test 127a "verify the client stats are sane"
12098
12099 test_127b() { # bug LU-333
12100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12101         local name count samp unit min max sum sumsq
12102
12103         echo "stats before reset"
12104         $LCTL get_param llite.*.stats
12105         $LCTL set_param llite.*.stats=0
12106
12107         # perform 2 reads and writes so MAX is different from SUM.
12108         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12109         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12110         cancel_lru_locks osc
12111         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12112         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12113
12114         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12115         stack_trap "rm -f $TMP/$tfile.tmp"
12116         while read name count samp unit min max sum sumsq; do
12117                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12118                 eval $name=$count || error "Wrong proc format"
12119
12120                 case $name in
12121                 read_bytes|write_bytes)
12122                         [[ "$unit" =~ "bytes" ]] ||
12123                                 error "unit is not 'bytes': $unit"
12124                         (( $count == 2 )) || error "count is not 2: $count"
12125                         (( $min == $PAGE_SIZE )) ||
12126                                 error "min is not $PAGE_SIZE: $min"
12127                         (( $max == $PAGE_SIZE )) ||
12128                                 error "max is not $PAGE_SIZE: $max"
12129                         (( $sum == $PAGE_SIZE * 2 )) ||
12130                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12131                         ;;
12132                 read|write)
12133                         [[ "$unit" =~ "usec" ]] ||
12134                                 error "unit is not 'usec': $unit"
12135                         ;;
12136                 *)      ;;
12137                 esac
12138         done < $TMP/$tfile.tmp
12139
12140         #check that we actually got some stats
12141         [ "$read_bytes" ] || error "Missing read_bytes stats"
12142         [ "$write_bytes" ] || error "Missing write_bytes stats"
12143         [ "$read_bytes" != 0 ] || error "no read done"
12144         [ "$write_bytes" != 0 ] || error "no write done"
12145 }
12146 run_test 127b "verify the llite client stats are sane"
12147
12148 test_127c() { # LU-12394
12149         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12150         local size
12151         local bsize
12152         local reads
12153         local writes
12154         local count
12155
12156         $LCTL set_param llite.*.extents_stats=1
12157         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12158
12159         # Use two stripes so there is enough space in default config
12160         $LFS setstripe -c 2 $DIR/$tfile
12161
12162         # Extent stats start at 0-4K and go in power of two buckets
12163         # LL_HIST_START = 12 --> 2^12 = 4K
12164         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12165         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12166         # small configs
12167         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12168                 do
12169                 # Write and read, 2x each, second time at a non-zero offset
12170                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12171                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12172                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12173                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12174                 rm -f $DIR/$tfile
12175         done
12176
12177         $LCTL get_param llite.*.extents_stats
12178
12179         count=2
12180         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12181                 do
12182                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12183                                 grep -m 1 $bsize)
12184                 reads=$(echo $bucket | awk '{print $5}')
12185                 writes=$(echo $bucket | awk '{print $9}')
12186                 [ "$reads" -eq $count ] ||
12187                         error "$reads reads in < $bsize bucket, expect $count"
12188                 [ "$writes" -eq $count ] ||
12189                         error "$writes writes in < $bsize bucket, expect $count"
12190         done
12191
12192         # Test mmap write and read
12193         $LCTL set_param llite.*.extents_stats=c
12194         size=512
12195         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12196         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12197         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12198
12199         $LCTL get_param llite.*.extents_stats
12200
12201         count=$(((size*1024) / PAGE_SIZE))
12202
12203         bsize=$((2 * PAGE_SIZE / 1024))K
12204
12205         bucket=$($LCTL get_param -n llite.*.extents_stats |
12206                         grep -m 1 $bsize)
12207         reads=$(echo $bucket | awk '{print $5}')
12208         writes=$(echo $bucket | awk '{print $9}')
12209         # mmap writes fault in the page first, creating an additonal read
12210         [ "$reads" -eq $((2 * count)) ] ||
12211                 error "$reads reads in < $bsize bucket, expect $count"
12212         [ "$writes" -eq $count ] ||
12213                 error "$writes writes in < $bsize bucket, expect $count"
12214 }
12215 run_test 127c "test llite extent stats with regular & mmap i/o"
12216
12217 test_128() { # bug 15212
12218         touch $DIR/$tfile
12219         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12220                 find $DIR/$tfile
12221                 find $DIR/$tfile
12222         EOF
12223
12224         result=$(grep error $TMP/$tfile.log)
12225         rm -f $DIR/$tfile $TMP/$tfile.log
12226         [ -z "$result" ] ||
12227                 error "consecutive find's under interactive lfs failed"
12228 }
12229 run_test 128 "interactive lfs for 2 consecutive find's"
12230
12231 set_dir_limits () {
12232         local mntdev
12233         local canondev
12234         local node
12235
12236         local ldproc=/proc/fs/ldiskfs
12237         local facets=$(get_facets MDS)
12238
12239         for facet in ${facets//,/ }; do
12240                 canondev=$(ldiskfs_canon \
12241                            *.$(convert_facet2label $facet).mntdev $facet)
12242                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12243                         ldproc=/sys/fs/ldiskfs
12244                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12245                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12246         done
12247 }
12248
12249 check_mds_dmesg() {
12250         local facets=$(get_facets MDS)
12251         for facet in ${facets//,/ }; do
12252                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12253         done
12254         return 1
12255 }
12256
12257 test_129() {
12258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12259         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12260                 skip "Need MDS version with at least 2.5.56"
12261         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12262                 skip_env "ldiskfs only test"
12263         fi
12264         remote_mds_nodsh && skip "remote MDS with nodsh"
12265
12266         local ENOSPC=28
12267         local has_warning=false
12268
12269         rm -rf $DIR/$tdir
12270         mkdir -p $DIR/$tdir
12271
12272         # block size of mds1
12273         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12274         set_dir_limits $maxsize $((maxsize * 6 / 8))
12275         stack_trap "set_dir_limits 0 0"
12276         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12277         local dirsize=$(stat -c%s "$DIR/$tdir")
12278         local nfiles=0
12279         while (( $dirsize <= $maxsize )); do
12280                 $MCREATE $DIR/$tdir/file_base_$nfiles
12281                 rc=$?
12282                 # check two errors:
12283                 # ENOSPC for ext4 max_dir_size, which has been used since
12284                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12285                 if (( rc == ENOSPC )); then
12286                         set_dir_limits 0 0
12287                         echo "rc=$rc returned as expected after $nfiles files"
12288
12289                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12290                                 error "create failed w/o dir size limit"
12291
12292                         # messages may be rate limited if test is run repeatedly
12293                         check_mds_dmesg '"is approaching max"' ||
12294                                 echo "warning message should be output"
12295                         check_mds_dmesg '"has reached max"' ||
12296                                 echo "reached message should be output"
12297
12298                         dirsize=$(stat -c%s "$DIR/$tdir")
12299
12300                         [[ $dirsize -ge $maxsize ]] && return 0
12301                         error "dirsize $dirsize < $maxsize after $nfiles files"
12302                 elif (( rc != 0 )); then
12303                         break
12304                 fi
12305                 nfiles=$((nfiles + 1))
12306                 dirsize=$(stat -c%s "$DIR/$tdir")
12307         done
12308
12309         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12310 }
12311 run_test 129 "test directory size limit ========================"
12312
12313 OLDIFS="$IFS"
12314 cleanup_130() {
12315         trap 0
12316         IFS="$OLDIFS"
12317 }
12318
12319 test_130a() {
12320         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12321         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12322
12323         trap cleanup_130 EXIT RETURN
12324
12325         local fm_file=$DIR/$tfile
12326         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12327         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12328                 error "dd failed for $fm_file"
12329
12330         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12331         filefrag -ves $fm_file
12332         RC=$?
12333         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12334                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12335         [ $RC != 0 ] && error "filefrag $fm_file failed"
12336
12337         filefrag_op=$(filefrag -ve -k $fm_file |
12338                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12339         lun=$($LFS getstripe -i $fm_file)
12340
12341         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12342         IFS=$'\n'
12343         tot_len=0
12344         for line in $filefrag_op
12345         do
12346                 frag_lun=`echo $line | cut -d: -f5`
12347                 ext_len=`echo $line | cut -d: -f4`
12348                 if (( $frag_lun != $lun )); then
12349                         cleanup_130
12350                         error "FIEMAP on 1-stripe file($fm_file) failed"
12351                         return
12352                 fi
12353                 (( tot_len += ext_len ))
12354         done
12355
12356         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12357                 cleanup_130
12358                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12359                 return
12360         fi
12361
12362         cleanup_130
12363
12364         echo "FIEMAP on single striped file succeeded"
12365 }
12366 run_test 130a "FIEMAP (1-stripe file)"
12367
12368 test_130b() {
12369         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12370
12371         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12372         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12373
12374         trap cleanup_130 EXIT RETURN
12375
12376         local fm_file=$DIR/$tfile
12377         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12378                         error "setstripe on $fm_file"
12379         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12380                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12381
12382         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12383                 error "dd failed on $fm_file"
12384
12385         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12386         filefrag_op=$(filefrag -ve -k $fm_file |
12387                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12388
12389         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12390                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12391
12392         IFS=$'\n'
12393         tot_len=0
12394         num_luns=1
12395         for line in $filefrag_op
12396         do
12397                 frag_lun=$(echo $line | cut -d: -f5 |
12398                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12399                 ext_len=$(echo $line | cut -d: -f4)
12400                 if (( $frag_lun != $last_lun )); then
12401                         if (( tot_len != 1024 )); then
12402                                 cleanup_130
12403                                 error "FIEMAP on $fm_file failed; returned " \
12404                                 "len $tot_len for OST $last_lun instead of 1024"
12405                                 return
12406                         else
12407                                 (( num_luns += 1 ))
12408                                 tot_len=0
12409                         fi
12410                 fi
12411                 (( tot_len += ext_len ))
12412                 last_lun=$frag_lun
12413         done
12414         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12415                 cleanup_130
12416                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12417                         "luns or wrong len for OST $last_lun"
12418                 return
12419         fi
12420
12421         cleanup_130
12422
12423         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12424 }
12425 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12426
12427 test_130c() {
12428         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12429
12430         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12431         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12432
12433         trap cleanup_130 EXIT RETURN
12434
12435         local fm_file=$DIR/$tfile
12436         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12437         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12438                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12439
12440         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12441                         error "dd failed on $fm_file"
12442
12443         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12444         filefrag_op=$(filefrag -ve -k $fm_file |
12445                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12446
12447         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12448                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12449
12450         IFS=$'\n'
12451         tot_len=0
12452         num_luns=1
12453         for line in $filefrag_op
12454         do
12455                 frag_lun=$(echo $line | cut -d: -f5 |
12456                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12457                 ext_len=$(echo $line | cut -d: -f4)
12458                 if (( $frag_lun != $last_lun )); then
12459                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12460                         if (( logical != 512 )); then
12461                                 cleanup_130
12462                                 error "FIEMAP on $fm_file failed; returned " \
12463                                 "logical start for lun $logical instead of 512"
12464                                 return
12465                         fi
12466                         if (( tot_len != 512 )); then
12467                                 cleanup_130
12468                                 error "FIEMAP on $fm_file failed; returned " \
12469                                 "len $tot_len for OST $last_lun instead of 1024"
12470                                 return
12471                         else
12472                                 (( num_luns += 1 ))
12473                                 tot_len=0
12474                         fi
12475                 fi
12476                 (( tot_len += ext_len ))
12477                 last_lun=$frag_lun
12478         done
12479         if (( num_luns != 2 || tot_len != 512 )); then
12480                 cleanup_130
12481                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12482                         "luns or wrong len for OST $last_lun"
12483                 return
12484         fi
12485
12486         cleanup_130
12487
12488         echo "FIEMAP on 2-stripe file with hole succeeded"
12489 }
12490 run_test 130c "FIEMAP (2-stripe file with hole)"
12491
12492 test_130d() {
12493         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12494
12495         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12496         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12497
12498         trap cleanup_130 EXIT RETURN
12499
12500         local fm_file=$DIR/$tfile
12501         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12502                         error "setstripe on $fm_file"
12503         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12504                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12505
12506         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12507         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12508                 error "dd failed on $fm_file"
12509
12510         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12511         filefrag_op=$(filefrag -ve -k $fm_file |
12512                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12513
12514         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12515                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12516
12517         IFS=$'\n'
12518         tot_len=0
12519         num_luns=1
12520         for line in $filefrag_op
12521         do
12522                 frag_lun=$(echo $line | cut -d: -f5 |
12523                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12524                 ext_len=$(echo $line | cut -d: -f4)
12525                 if (( $frag_lun != $last_lun )); then
12526                         if (( tot_len != 1024 )); then
12527                                 cleanup_130
12528                                 error "FIEMAP on $fm_file failed; returned " \
12529                                 "len $tot_len for OST $last_lun instead of 1024"
12530                                 return
12531                         else
12532                                 (( num_luns += 1 ))
12533                                 tot_len=0
12534                         fi
12535                 fi
12536                 (( tot_len += ext_len ))
12537                 last_lun=$frag_lun
12538         done
12539         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12540                 cleanup_130
12541                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12542                         "luns or wrong len for OST $last_lun"
12543                 return
12544         fi
12545
12546         cleanup_130
12547
12548         echo "FIEMAP on N-stripe file succeeded"
12549 }
12550 run_test 130d "FIEMAP (N-stripe file)"
12551
12552 test_130e() {
12553         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12554
12555         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12556         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12557
12558         trap cleanup_130 EXIT RETURN
12559
12560         local fm_file=$DIR/$tfile
12561         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12562         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12563                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12564
12565         NUM_BLKS=512
12566         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12567         for ((i = 0; i < $NUM_BLKS; i++))
12568         do
12569                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12570         done
12571
12572         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12573         filefrag_op=$(filefrag -ve -k $fm_file |
12574                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12575
12576         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12577                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12578
12579         IFS=$'\n'
12580         tot_len=0
12581         num_luns=1
12582         for line in $filefrag_op
12583         do
12584                 frag_lun=$(echo $line | cut -d: -f5 |
12585                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12586                 ext_len=$(echo $line | cut -d: -f4)
12587                 if (( $frag_lun != $last_lun )); then
12588                         if (( tot_len != $EXPECTED_LEN )); then
12589                                 cleanup_130
12590                                 error "FIEMAP on $fm_file failed; returned " \
12591                                 "len $tot_len for OST $last_lun instead " \
12592                                 "of $EXPECTED_LEN"
12593                                 return
12594                         else
12595                                 (( num_luns += 1 ))
12596                                 tot_len=0
12597                         fi
12598                 fi
12599                 (( tot_len += ext_len ))
12600                 last_lun=$frag_lun
12601         done
12602         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12603                 cleanup_130
12604                 error "FIEMAP on $fm_file failed; returned wrong number " \
12605                         "of luns or wrong len for OST $last_lun"
12606                 return
12607         fi
12608
12609         cleanup_130
12610
12611         echo "FIEMAP with continuation calls succeeded"
12612 }
12613 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12614
12615 test_130f() {
12616         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12617         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12618
12619         local fm_file=$DIR/$tfile
12620         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12621                 error "multiop create with lov_delay_create on $fm_file"
12622
12623         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12624         filefrag_extents=$(filefrag -vek $fm_file |
12625                            awk '/extents? found/ { print $2 }')
12626         if [[ "$filefrag_extents" != "0" ]]; then
12627                 error "FIEMAP on $fm_file failed; " \
12628                       "returned $filefrag_extents expected 0"
12629         fi
12630
12631         rm -f $fm_file
12632 }
12633 run_test 130f "FIEMAP (unstriped file)"
12634
12635 # Test for writev/readv
12636 test_131a() {
12637         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12638                 error "writev test failed"
12639         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12640                 error "readv failed"
12641         rm -f $DIR/$tfile
12642 }
12643 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12644
12645 test_131b() {
12646         local fsize=$((524288 + 1048576 + 1572864))
12647         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12648                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12649                         error "append writev test failed"
12650
12651         ((fsize += 1572864 + 1048576))
12652         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12653                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12654                         error "append writev test failed"
12655         rm -f $DIR/$tfile
12656 }
12657 run_test 131b "test append writev"
12658
12659 test_131c() {
12660         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12661         error "NOT PASS"
12662 }
12663 run_test 131c "test read/write on file w/o objects"
12664
12665 test_131d() {
12666         rwv -f $DIR/$tfile -w -n 1 1572864
12667         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12668         if [ "$NOB" != 1572864 ]; then
12669                 error "Short read filed: read $NOB bytes instead of 1572864"
12670         fi
12671         rm -f $DIR/$tfile
12672 }
12673 run_test 131d "test short read"
12674
12675 test_131e() {
12676         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12677         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12678         error "read hitting hole failed"
12679         rm -f $DIR/$tfile
12680 }
12681 run_test 131e "test read hitting hole"
12682
12683 check_stats() {
12684         local facet=$1
12685         local op=$2
12686         local want=${3:-0}
12687         local res
12688
12689         case $facet in
12690         mds*) res=$(do_facet $facet \
12691                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12692                  ;;
12693         ost*) res=$(do_facet $facet \
12694                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12695                  ;;
12696         *) error "Wrong facet '$facet'" ;;
12697         esac
12698         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12699         # if the argument $3 is zero, it means any stat increment is ok.
12700         if [[ $want -gt 0 ]]; then
12701                 local count=$(echo $res | awk '{ print $2 }')
12702                 [[ $count -ne $want ]] &&
12703                         error "The $op counter on $facet is $count, not $want"
12704         fi
12705 }
12706
12707 test_133a() {
12708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12709         remote_ost_nodsh && skip "remote OST with nodsh"
12710         remote_mds_nodsh && skip "remote MDS with nodsh"
12711         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12712                 skip_env "MDS doesn't support rename stats"
12713
12714         local testdir=$DIR/${tdir}/stats_testdir
12715
12716         mkdir -p $DIR/${tdir}
12717
12718         # clear stats.
12719         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12720         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12721
12722         # verify mdt stats first.
12723         mkdir ${testdir} || error "mkdir failed"
12724         check_stats $SINGLEMDS "mkdir" 1
12725         touch ${testdir}/${tfile} || error "touch failed"
12726         check_stats $SINGLEMDS "open" 1
12727         check_stats $SINGLEMDS "close" 1
12728         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12729                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12730                 check_stats $SINGLEMDS "mknod" 2
12731         }
12732         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12733         check_stats $SINGLEMDS "unlink" 1
12734         rm -f ${testdir}/${tfile} || error "file remove failed"
12735         check_stats $SINGLEMDS "unlink" 2
12736
12737         # remove working dir and check mdt stats again.
12738         rmdir ${testdir} || error "rmdir failed"
12739         check_stats $SINGLEMDS "rmdir" 1
12740
12741         local testdir1=$DIR/${tdir}/stats_testdir1
12742         mkdir -p ${testdir}
12743         mkdir -p ${testdir1}
12744         touch ${testdir1}/test1
12745         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12746         check_stats $SINGLEMDS "crossdir_rename" 1
12747
12748         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12749         check_stats $SINGLEMDS "samedir_rename" 1
12750
12751         rm -rf $DIR/${tdir}
12752 }
12753 run_test 133a "Verifying MDT stats ========================================"
12754
12755 test_133b() {
12756         local res
12757
12758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12759         remote_ost_nodsh && skip "remote OST with nodsh"
12760         remote_mds_nodsh && skip "remote MDS with nodsh"
12761
12762         local testdir=$DIR/${tdir}/stats_testdir
12763
12764         mkdir -p ${testdir} || error "mkdir failed"
12765         touch ${testdir}/${tfile} || error "touch failed"
12766         cancel_lru_locks mdc
12767
12768         # clear stats.
12769         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12770         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12771
12772         # extra mdt stats verification.
12773         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12774         check_stats $SINGLEMDS "setattr" 1
12775         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12776         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12777         then            # LU-1740
12778                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12779                 check_stats $SINGLEMDS "getattr" 1
12780         fi
12781         rm -rf $DIR/${tdir}
12782
12783         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12784         # so the check below is not reliable
12785         [ $MDSCOUNT -eq 1 ] || return 0
12786
12787         # Sleep to avoid a cached response.
12788         #define OBD_STATFS_CACHE_SECONDS 1
12789         sleep 2
12790         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12791         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12792         $LFS df || error "lfs failed"
12793         check_stats $SINGLEMDS "statfs" 1
12794
12795         # check aggregated statfs (LU-10018)
12796         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12797                 return 0
12798         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12799                 return 0
12800         sleep 2
12801         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12802         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12803         df $DIR
12804         check_stats $SINGLEMDS "statfs" 1
12805
12806         # We want to check that the client didn't send OST_STATFS to
12807         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12808         # extra care is needed here.
12809         if remote_mds; then
12810                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12811                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12812
12813                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12814                 [ "$res" ] && error "OST got STATFS"
12815         fi
12816
12817         return 0
12818 }
12819 run_test 133b "Verifying extra MDT stats =================================="
12820
12821 test_133c() {
12822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12823         remote_ost_nodsh && skip "remote OST with nodsh"
12824         remote_mds_nodsh && skip "remote MDS with nodsh"
12825
12826         local testdir=$DIR/$tdir/stats_testdir
12827
12828         test_mkdir -p $testdir
12829
12830         # verify obdfilter stats.
12831         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12832         sync
12833         cancel_lru_locks osc
12834         wait_delete_completed
12835
12836         # clear stats.
12837         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12838         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12839
12840         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12841                 error "dd failed"
12842         sync
12843         cancel_lru_locks osc
12844         check_stats ost1 "write" 1
12845
12846         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12847         check_stats ost1 "read" 1
12848
12849         > $testdir/$tfile || error "truncate failed"
12850         check_stats ost1 "punch" 1
12851
12852         rm -f $testdir/$tfile || error "file remove failed"
12853         wait_delete_completed
12854         check_stats ost1 "destroy" 1
12855
12856         rm -rf $DIR/$tdir
12857 }
12858 run_test 133c "Verifying OST stats ========================================"
12859
12860 order_2() {
12861         local value=$1
12862         local orig=$value
12863         local order=1
12864
12865         while [ $value -ge 2 ]; do
12866                 order=$((order*2))
12867                 value=$((value/2))
12868         done
12869
12870         if [ $orig -gt $order ]; then
12871                 order=$((order*2))
12872         fi
12873         echo $order
12874 }
12875
12876 size_in_KMGT() {
12877     local value=$1
12878     local size=('K' 'M' 'G' 'T');
12879     local i=0
12880     local size_string=$value
12881
12882     while [ $value -ge 1024 ]; do
12883         if [ $i -gt 3 ]; then
12884             #T is the biggest unit we get here, if that is bigger,
12885             #just return XXXT
12886             size_string=${value}T
12887             break
12888         fi
12889         value=$((value >> 10))
12890         if [ $value -lt 1024 ]; then
12891             size_string=${value}${size[$i]}
12892             break
12893         fi
12894         i=$((i + 1))
12895     done
12896
12897     echo $size_string
12898 }
12899
12900 get_rename_size() {
12901         local size=$1
12902         local context=${2:-.}
12903         local sample=$(do_facet $SINGLEMDS $LCTL \
12904                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12905                 grep -A1 $context |
12906                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12907         echo $sample
12908 }
12909
12910 test_133d() {
12911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12912         remote_ost_nodsh && skip "remote OST with nodsh"
12913         remote_mds_nodsh && skip "remote MDS with nodsh"
12914         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12915                 skip_env "MDS doesn't support rename stats"
12916
12917         local testdir1=$DIR/${tdir}/stats_testdir1
12918         local testdir2=$DIR/${tdir}/stats_testdir2
12919         mkdir -p $DIR/${tdir}
12920
12921         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12922
12923         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12924         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12925
12926         createmany -o $testdir1/test 512 || error "createmany failed"
12927
12928         # check samedir rename size
12929         mv ${testdir1}/test0 ${testdir1}/test_0
12930
12931         local testdir1_size=$(ls -l $DIR/${tdir} |
12932                 awk '/stats_testdir1/ {print $5}')
12933         local testdir2_size=$(ls -l $DIR/${tdir} |
12934                 awk '/stats_testdir2/ {print $5}')
12935
12936         testdir1_size=$(order_2 $testdir1_size)
12937         testdir2_size=$(order_2 $testdir2_size)
12938
12939         testdir1_size=$(size_in_KMGT $testdir1_size)
12940         testdir2_size=$(size_in_KMGT $testdir2_size)
12941
12942         echo "source rename dir size: ${testdir1_size}"
12943         echo "target rename dir size: ${testdir2_size}"
12944
12945         local cmd="do_facet $SINGLEMDS $LCTL "
12946         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12947
12948         eval $cmd || error "$cmd failed"
12949         local samedir=$($cmd | grep 'same_dir')
12950         local same_sample=$(get_rename_size $testdir1_size)
12951         [ -z "$samedir" ] && error "samedir_rename_size count error"
12952         [[ $same_sample -eq 1 ]] ||
12953                 error "samedir_rename_size error $same_sample"
12954         echo "Check same dir rename stats success"
12955
12956         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12957
12958         # check crossdir rename size
12959         mv ${testdir1}/test_0 ${testdir2}/test_0
12960
12961         testdir1_size=$(ls -l $DIR/${tdir} |
12962                 awk '/stats_testdir1/ {print $5}')
12963         testdir2_size=$(ls -l $DIR/${tdir} |
12964                 awk '/stats_testdir2/ {print $5}')
12965
12966         testdir1_size=$(order_2 $testdir1_size)
12967         testdir2_size=$(order_2 $testdir2_size)
12968
12969         testdir1_size=$(size_in_KMGT $testdir1_size)
12970         testdir2_size=$(size_in_KMGT $testdir2_size)
12971
12972         echo "source rename dir size: ${testdir1_size}"
12973         echo "target rename dir size: ${testdir2_size}"
12974
12975         eval $cmd || error "$cmd failed"
12976         local crossdir=$($cmd | grep 'crossdir')
12977         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12978         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12979         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12980         [[ $src_sample -eq 1 ]] ||
12981                 error "crossdir_rename_size error $src_sample"
12982         [[ $tgt_sample -eq 1 ]] ||
12983                 error "crossdir_rename_size error $tgt_sample"
12984         echo "Check cross dir rename stats success"
12985         rm -rf $DIR/${tdir}
12986 }
12987 run_test 133d "Verifying rename_stats ========================================"
12988
12989 test_133e() {
12990         remote_mds_nodsh && skip "remote MDS with nodsh"
12991         remote_ost_nodsh && skip "remote OST with nodsh"
12992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12993
12994         local testdir=$DIR/${tdir}/stats_testdir
12995         local ctr f0 f1 bs=32768 count=42 sum
12996
12997         mkdir -p ${testdir} || error "mkdir failed"
12998
12999         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13000
13001         for ctr in {write,read}_bytes; do
13002                 sync
13003                 cancel_lru_locks osc
13004
13005                 do_facet ost1 $LCTL set_param -n \
13006                         "obdfilter.*.exports.clear=clear"
13007
13008                 if [ $ctr = write_bytes ]; then
13009                         f0=/dev/zero
13010                         f1=${testdir}/${tfile}
13011                 else
13012                         f0=${testdir}/${tfile}
13013                         f1=/dev/null
13014                 fi
13015
13016                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13017                         error "dd failed"
13018                 sync
13019                 cancel_lru_locks osc
13020
13021                 sum=$(do_facet ost1 $LCTL get_param \
13022                         "obdfilter.*.exports.*.stats" |
13023                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13024                                 $1 == ctr { sum += $7 }
13025                                 END { printf("%0.0f", sum) }')
13026
13027                 if ((sum != bs * count)); then
13028                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13029                 fi
13030         done
13031
13032         rm -rf $DIR/${tdir}
13033 }
13034 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13035
13036 test_133f() {
13037         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13038                 skip "too old lustre for get_param -R ($facet_ver)"
13039
13040         # verifying readability.
13041         $LCTL get_param -R '*' &> /dev/null
13042
13043         # Verifing writability with badarea_io.
13044         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13045                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13046                 error "client badarea_io failed"
13047
13048         # remount the FS in case writes/reads /proc break the FS
13049         cleanup || error "failed to unmount"
13050         setup || error "failed to setup"
13051 }
13052 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13053
13054 test_133g() {
13055         remote_mds_nodsh && skip "remote MDS with nodsh"
13056         remote_ost_nodsh && skip "remote OST with nodsh"
13057
13058         local facet
13059         for facet in mds1 ost1; do
13060                 local facet_ver=$(lustre_version_code $facet)
13061                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13062                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13063                 else
13064                         log "$facet: too old lustre for get_param -R"
13065                 fi
13066                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13067                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13068                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13069                                 xargs badarea_io" ||
13070                                         error "$facet badarea_io failed"
13071                 else
13072                         skip_noexit "$facet: too old lustre for get_param -R"
13073                 fi
13074         done
13075
13076         # remount the FS in case writes/reads /proc break the FS
13077         cleanup || error "failed to unmount"
13078         setup || error "failed to setup"
13079 }
13080 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13081
13082 test_133h() {
13083         remote_mds_nodsh && skip "remote MDS with nodsh"
13084         remote_ost_nodsh && skip "remote OST with nodsh"
13085         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13086                 skip "Need MDS version at least 2.9.54"
13087
13088         local facet
13089         for facet in client mds1 ost1; do
13090                 # Get the list of files that are missing the terminating newline
13091                 local plist=$(do_facet $facet
13092                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13093                 local ent
13094                 for ent in $plist; do
13095                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13096                                 awk -v FS='\v' -v RS='\v\v' \
13097                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13098                                         print FILENAME}'" 2>/dev/null)
13099                         [ -z $missing ] || {
13100                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13101                                 error "file does not end with newline: $facet-$ent"
13102                         }
13103                 done
13104         done
13105 }
13106 run_test 133h "Proc files should end with newlines"
13107
13108 test_134a() {
13109         remote_mds_nodsh && skip "remote MDS with nodsh"
13110         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13111                 skip "Need MDS version at least 2.7.54"
13112
13113         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13114         cancel_lru_locks mdc
13115
13116         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13117         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13118         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13119
13120         local nr=1000
13121         createmany -o $DIR/$tdir/f $nr ||
13122                 error "failed to create $nr files in $DIR/$tdir"
13123         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13124
13125         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13126         do_facet mds1 $LCTL set_param fail_loc=0x327
13127         do_facet mds1 $LCTL set_param fail_val=500
13128         touch $DIR/$tdir/m
13129
13130         echo "sleep 10 seconds ..."
13131         sleep 10
13132         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13133
13134         do_facet mds1 $LCTL set_param fail_loc=0
13135         do_facet mds1 $LCTL set_param fail_val=0
13136         [ $lck_cnt -lt $unused ] ||
13137                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13138
13139         rm $DIR/$tdir/m
13140         unlinkmany $DIR/$tdir/f $nr
13141 }
13142 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13143
13144 test_134b() {
13145         remote_mds_nodsh && skip "remote MDS with nodsh"
13146         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13147                 skip "Need MDS version at least 2.7.54"
13148
13149         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13150         cancel_lru_locks mdc
13151
13152         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13153                         ldlm.lock_reclaim_threshold_mb)
13154         # disable reclaim temporarily
13155         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13156
13157         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13158         do_facet mds1 $LCTL set_param fail_loc=0x328
13159         do_facet mds1 $LCTL set_param fail_val=500
13160
13161         $LCTL set_param debug=+trace
13162
13163         local nr=600
13164         createmany -o $DIR/$tdir/f $nr &
13165         local create_pid=$!
13166
13167         echo "Sleep $TIMEOUT seconds ..."
13168         sleep $TIMEOUT
13169         if ! ps -p $create_pid  > /dev/null 2>&1; then
13170                 do_facet mds1 $LCTL set_param fail_loc=0
13171                 do_facet mds1 $LCTL set_param fail_val=0
13172                 do_facet mds1 $LCTL set_param \
13173                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13174                 error "createmany finished incorrectly!"
13175         fi
13176         do_facet mds1 $LCTL set_param fail_loc=0
13177         do_facet mds1 $LCTL set_param fail_val=0
13178         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13179         wait $create_pid || return 1
13180
13181         unlinkmany $DIR/$tdir/f $nr
13182 }
13183 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13184
13185 test_135() {
13186         remote_mds_nodsh && skip "remote MDS with nodsh"
13187         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13188                 skip "Need MDS version at least 2.13.50"
13189         local fname
13190
13191         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13192
13193 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13194         #set only one record at plain llog
13195         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13196
13197         #fill already existed plain llog each 64767
13198         #wrapping whole catalog
13199         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13200
13201         createmany -o $DIR/$tdir/$tfile_ 64700
13202         for (( i = 0; i < 64700; i = i + 2 ))
13203         do
13204                 rm $DIR/$tdir/$tfile_$i &
13205                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13206                 local pid=$!
13207                 wait $pid
13208         done
13209
13210         #waiting osp synchronization
13211         wait_delete_completed
13212 }
13213 run_test 135 "Race catalog processing"
13214
13215 test_136() {
13216         remote_mds_nodsh && skip "remote MDS with nodsh"
13217         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13218                 skip "Need MDS version at least 2.13.50"
13219         local fname
13220
13221         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13222         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13223         #set only one record at plain llog
13224 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13225         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13226
13227         #fill already existed 2 plain llogs each 64767
13228         #wrapping whole catalog
13229         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13230         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13231         wait_delete_completed
13232
13233         createmany -o $DIR/$tdir/$tfile_ 10
13234         sleep 25
13235
13236         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13237         for (( i = 0; i < 10; i = i + 3 ))
13238         do
13239                 rm $DIR/$tdir/$tfile_$i &
13240                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13241                 local pid=$!
13242                 wait $pid
13243                 sleep 7
13244                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13245         done
13246
13247         #waiting osp synchronization
13248         wait_delete_completed
13249 }
13250 run_test 136 "Race catalog processing 2"
13251
13252 test_140() { #bug-17379
13253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13254
13255         test_mkdir $DIR/$tdir
13256         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13257         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13258
13259         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13260         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13261         local i=0
13262         while i=$((i + 1)); do
13263                 test_mkdir $i
13264                 cd $i || error "Changing to $i"
13265                 ln -s ../stat stat || error "Creating stat symlink"
13266                 # Read the symlink until ELOOP present,
13267                 # not LBUGing the system is considered success,
13268                 # we didn't overrun the stack.
13269                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13270                 if [ $ret -ne 0 ]; then
13271                         if [ $ret -eq 40 ]; then
13272                                 break  # -ELOOP
13273                         else
13274                                 error "Open stat symlink"
13275                                         return
13276                         fi
13277                 fi
13278         done
13279         i=$((i - 1))
13280         echo "The symlink depth = $i"
13281         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13282                 error "Invalid symlink depth"
13283
13284         # Test recursive symlink
13285         ln -s symlink_self symlink_self
13286         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13287         echo "open symlink_self returns $ret"
13288         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13289 }
13290 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13291
13292 test_150a() {
13293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13294
13295         local TF="$TMP/$tfile"
13296
13297         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13298         cp $TF $DIR/$tfile
13299         cancel_lru_locks $OSC
13300         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13301         remount_client $MOUNT
13302         df -P $MOUNT
13303         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13304
13305         $TRUNCATE $TF 6000
13306         $TRUNCATE $DIR/$tfile 6000
13307         cancel_lru_locks $OSC
13308         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13309
13310         echo "12345" >>$TF
13311         echo "12345" >>$DIR/$tfile
13312         cancel_lru_locks $OSC
13313         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13314
13315         echo "12345" >>$TF
13316         echo "12345" >>$DIR/$tfile
13317         cancel_lru_locks $OSC
13318         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13319
13320         rm -f $TF
13321         true
13322 }
13323 run_test 150a "truncate/append tests"
13324
13325 test_150b() {
13326         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13327         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13328                 skip "Need OST version at least 2.13.53"
13329         touch $DIR/$tfile
13330         check_fallocate $DIR/$tfile || error "fallocate failed"
13331 }
13332 run_test 150b "Verify fallocate (prealloc) functionality"
13333
13334 test_150c() {
13335         local bytes
13336         local want
13337
13338         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13339         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13340                 skip "Need OST version at least 2.13.53"
13341
13342         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13343         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13344         sync; sync_all_data
13345         cancel_lru_locks $OSC
13346         sleep 5
13347         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13348         want=$((OSTCOUNT * 1048576))
13349
13350         # Must allocate all requested space, not more than 5% extra
13351         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13352                 error "bytes $bytes is not $want"
13353 }
13354 run_test 150c "Verify fallocate Size and Blocks"
13355
13356 test_150d() {
13357         local bytes
13358         local want
13359
13360         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13361         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13362                 skip "Need OST version at least 2.13.53"
13363
13364         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13365         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13366         sync; sync_all_data
13367         cancel_lru_locks $OSC
13368         sleep 5
13369         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13370         want=$((OSTCOUNT * 1048576))
13371
13372         # Must allocate all requested space, not more than 5% extra
13373         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13374                 error "bytes $bytes is not $want"
13375 }
13376 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13377
13378 #LU-2902 roc_hit was not able to read all values from lproc
13379 function roc_hit_init() {
13380         local list=$(comma_list $(osts_nodes))
13381         local dir=$DIR/$tdir-check
13382         local file=$dir/$tfile
13383         local BEFORE
13384         local AFTER
13385         local idx
13386
13387         test_mkdir $dir
13388         #use setstripe to do a write to every ost
13389         for i in $(seq 0 $((OSTCOUNT-1))); do
13390                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13391                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13392                 idx=$(printf %04x $i)
13393                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13394                         awk '$1 == "cache_access" {sum += $7}
13395                                 END { printf("%0.0f", sum) }')
13396
13397                 cancel_lru_locks osc
13398                 cat $file >/dev/null
13399
13400                 AFTER=$(get_osd_param $list *OST*$idx stats |
13401                         awk '$1 == "cache_access" {sum += $7}
13402                                 END { printf("%0.0f", sum) }')
13403
13404                 echo BEFORE:$BEFORE AFTER:$AFTER
13405                 if ! let "AFTER - BEFORE == 4"; then
13406                         rm -rf $dir
13407                         error "roc_hit is not safe to use"
13408                 fi
13409                 rm $file
13410         done
13411
13412         rm -rf $dir
13413 }
13414
13415 function roc_hit() {
13416         local list=$(comma_list $(osts_nodes))
13417         echo $(get_osd_param $list '' stats |
13418                 awk '$1 == "cache_hit" {sum += $7}
13419                         END { printf("%0.0f", sum) }')
13420 }
13421
13422 function set_cache() {
13423         local on=1
13424
13425         if [ "$2" == "off" ]; then
13426                 on=0;
13427         fi
13428         local list=$(comma_list $(osts_nodes))
13429         set_osd_param $list '' $1_cache_enable $on
13430
13431         cancel_lru_locks osc
13432 }
13433
13434 test_151() {
13435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13436         remote_ost_nodsh && skip "remote OST with nodsh"
13437
13438         local CPAGES=3
13439         local list=$(comma_list $(osts_nodes))
13440
13441         # check whether obdfilter is cache capable at all
13442         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13443                 skip "not cache-capable obdfilter"
13444         fi
13445
13446         # check cache is enabled on all obdfilters
13447         if get_osd_param $list '' read_cache_enable | grep 0; then
13448                 skip "oss cache is disabled"
13449         fi
13450
13451         set_osd_param $list '' writethrough_cache_enable 1
13452
13453         # check write cache is enabled on all obdfilters
13454         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13455                 skip "oss write cache is NOT enabled"
13456         fi
13457
13458         roc_hit_init
13459
13460         #define OBD_FAIL_OBD_NO_LRU  0x609
13461         do_nodes $list $LCTL set_param fail_loc=0x609
13462
13463         # pages should be in the case right after write
13464         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13465                 error "dd failed"
13466
13467         local BEFORE=$(roc_hit)
13468         cancel_lru_locks osc
13469         cat $DIR/$tfile >/dev/null
13470         local AFTER=$(roc_hit)
13471
13472         do_nodes $list $LCTL set_param fail_loc=0
13473
13474         if ! let "AFTER - BEFORE == CPAGES"; then
13475                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13476         fi
13477
13478         cancel_lru_locks osc
13479         # invalidates OST cache
13480         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13481         set_osd_param $list '' read_cache_enable 0
13482         cat $DIR/$tfile >/dev/null
13483
13484         # now data shouldn't be found in the cache
13485         BEFORE=$(roc_hit)
13486         cancel_lru_locks osc
13487         cat $DIR/$tfile >/dev/null
13488         AFTER=$(roc_hit)
13489         if let "AFTER - BEFORE != 0"; then
13490                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13491         fi
13492
13493         set_osd_param $list '' read_cache_enable 1
13494         rm -f $DIR/$tfile
13495 }
13496 run_test 151 "test cache on oss and controls ==============================="
13497
13498 test_152() {
13499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13500
13501         local TF="$TMP/$tfile"
13502
13503         # simulate ENOMEM during write
13504 #define OBD_FAIL_OST_NOMEM      0x226
13505         lctl set_param fail_loc=0x80000226
13506         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13507         cp $TF $DIR/$tfile
13508         sync || error "sync failed"
13509         lctl set_param fail_loc=0
13510
13511         # discard client's cache
13512         cancel_lru_locks osc
13513
13514         # simulate ENOMEM during read
13515         lctl set_param fail_loc=0x80000226
13516         cmp $TF $DIR/$tfile || error "cmp failed"
13517         lctl set_param fail_loc=0
13518
13519         rm -f $TF
13520 }
13521 run_test 152 "test read/write with enomem ============================"
13522
13523 test_153() {
13524         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13525 }
13526 run_test 153 "test if fdatasync does not crash ======================="
13527
13528 dot_lustre_fid_permission_check() {
13529         local fid=$1
13530         local ffid=$MOUNT/.lustre/fid/$fid
13531         local test_dir=$2
13532
13533         echo "stat fid $fid"
13534         stat $ffid > /dev/null || error "stat $ffid failed."
13535         echo "touch fid $fid"
13536         touch $ffid || error "touch $ffid failed."
13537         echo "write to fid $fid"
13538         cat /etc/hosts > $ffid || error "write $ffid failed."
13539         echo "read fid $fid"
13540         diff /etc/hosts $ffid || error "read $ffid failed."
13541         echo "append write to fid $fid"
13542         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13543         echo "rename fid $fid"
13544         mv $ffid $test_dir/$tfile.1 &&
13545                 error "rename $ffid to $tfile.1 should fail."
13546         touch $test_dir/$tfile.1
13547         mv $test_dir/$tfile.1 $ffid &&
13548                 error "rename $tfile.1 to $ffid should fail."
13549         rm -f $test_dir/$tfile.1
13550         echo "truncate fid $fid"
13551         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13552         echo "link fid $fid"
13553         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13554         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13555                 echo "setfacl fid $fid"
13556                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13557                 echo "getfacl fid $fid"
13558                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13559         fi
13560         echo "unlink fid $fid"
13561         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13562         echo "mknod fid $fid"
13563         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13564
13565         fid=[0xf00000400:0x1:0x0]
13566         ffid=$MOUNT/.lustre/fid/$fid
13567
13568         echo "stat non-exist fid $fid"
13569         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13570         echo "write to non-exist fid $fid"
13571         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13572         echo "link new fid $fid"
13573         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13574
13575         mkdir -p $test_dir/$tdir
13576         touch $test_dir/$tdir/$tfile
13577         fid=$($LFS path2fid $test_dir/$tdir)
13578         rc=$?
13579         [ $rc -ne 0 ] &&
13580                 error "error: could not get fid for $test_dir/$dir/$tfile."
13581
13582         ffid=$MOUNT/.lustre/fid/$fid
13583
13584         echo "ls $fid"
13585         ls $ffid > /dev/null || error "ls $ffid failed."
13586         echo "touch $fid/$tfile.1"
13587         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13588
13589         echo "touch $MOUNT/.lustre/fid/$tfile"
13590         touch $MOUNT/.lustre/fid/$tfile && \
13591                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13592
13593         echo "setxattr to $MOUNT/.lustre/fid"
13594         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13595
13596         echo "listxattr for $MOUNT/.lustre/fid"
13597         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13598
13599         echo "delxattr from $MOUNT/.lustre/fid"
13600         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13601
13602         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13603         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13604                 error "touch invalid fid should fail."
13605
13606         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13607         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13608                 error "touch non-normal fid should fail."
13609
13610         echo "rename $tdir to $MOUNT/.lustre/fid"
13611         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13612                 error "rename to $MOUNT/.lustre/fid should fail."
13613
13614         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13615         then            # LU-3547
13616                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13617                 local new_obf_mode=777
13618
13619                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13620                 chmod $new_obf_mode $DIR/.lustre/fid ||
13621                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13622
13623                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13624                 [ $obf_mode -eq $new_obf_mode ] ||
13625                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13626
13627                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13628                 chmod $old_obf_mode $DIR/.lustre/fid ||
13629                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13630         fi
13631
13632         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13633         fid=$($LFS path2fid $test_dir/$tfile-2)
13634
13635         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13636         then # LU-5424
13637                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13638                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13639                         error "create lov data thru .lustre failed"
13640         fi
13641         echo "cp /etc/passwd $test_dir/$tfile-2"
13642         cp /etc/passwd $test_dir/$tfile-2 ||
13643                 error "copy to $test_dir/$tfile-2 failed."
13644         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13645         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13646                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13647
13648         rm -rf $test_dir/tfile.lnk
13649         rm -rf $test_dir/$tfile-2
13650 }
13651
13652 test_154A() {
13653         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13654                 skip "Need MDS version at least 2.4.1"
13655
13656         local tf=$DIR/$tfile
13657         touch $tf
13658
13659         local fid=$($LFS path2fid $tf)
13660         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13661
13662         # check that we get the same pathname back
13663         local rootpath
13664         local found
13665         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13666                 echo "$rootpath $fid"
13667                 found=$($LFS fid2path $rootpath "$fid")
13668                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13669                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13670         done
13671
13672         # check wrong root path format
13673         rootpath=$MOUNT"_wrong"
13674         found=$($LFS fid2path $rootpath "$fid")
13675         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13676 }
13677 run_test 154A "lfs path2fid and fid2path basic checks"
13678
13679 test_154B() {
13680         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13681                 skip "Need MDS version at least 2.4.1"
13682
13683         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13684         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13685         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13686         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13687
13688         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13689         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13690
13691         # check that we get the same pathname
13692         echo "PFID: $PFID, name: $name"
13693         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13694         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13695         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13696                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13697
13698         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13699 }
13700 run_test 154B "verify the ll_decode_linkea tool"
13701
13702 test_154a() {
13703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13704         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13705         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13706                 skip "Need MDS version at least 2.2.51"
13707         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13708
13709         cp /etc/hosts $DIR/$tfile
13710
13711         fid=$($LFS path2fid $DIR/$tfile)
13712         rc=$?
13713         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13714
13715         dot_lustre_fid_permission_check "$fid" $DIR ||
13716                 error "dot lustre permission check $fid failed"
13717
13718         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13719
13720         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13721
13722         touch $MOUNT/.lustre/file &&
13723                 error "creation is not allowed under .lustre"
13724
13725         mkdir $MOUNT/.lustre/dir &&
13726                 error "mkdir is not allowed under .lustre"
13727
13728         rm -rf $DIR/$tfile
13729 }
13730 run_test 154a "Open-by-FID"
13731
13732 test_154b() {
13733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13734         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13735         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13736         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13737                 skip "Need MDS version at least 2.2.51"
13738
13739         local remote_dir=$DIR/$tdir/remote_dir
13740         local MDTIDX=1
13741         local rc=0
13742
13743         mkdir -p $DIR/$tdir
13744         $LFS mkdir -i $MDTIDX $remote_dir ||
13745                 error "create remote directory failed"
13746
13747         cp /etc/hosts $remote_dir/$tfile
13748
13749         fid=$($LFS path2fid $remote_dir/$tfile)
13750         rc=$?
13751         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13752
13753         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13754                 error "dot lustre permission check $fid failed"
13755         rm -rf $DIR/$tdir
13756 }
13757 run_test 154b "Open-by-FID for remote directory"
13758
13759 test_154c() {
13760         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13761                 skip "Need MDS version at least 2.4.1"
13762
13763         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13764         local FID1=$($LFS path2fid $DIR/$tfile.1)
13765         local FID2=$($LFS path2fid $DIR/$tfile.2)
13766         local FID3=$($LFS path2fid $DIR/$tfile.3)
13767
13768         local N=1
13769         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13770                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13771                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13772                 local want=FID$N
13773                 [ "$FID" = "${!want}" ] ||
13774                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13775                 N=$((N + 1))
13776         done
13777
13778         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13779         do
13780                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13781                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13782                 N=$((N + 1))
13783         done
13784 }
13785 run_test 154c "lfs path2fid and fid2path multiple arguments"
13786
13787 test_154d() {
13788         remote_mds_nodsh && skip "remote MDS with nodsh"
13789         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13790                 skip "Need MDS version at least 2.5.53"
13791
13792         if remote_mds; then
13793                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13794         else
13795                 nid="0@lo"
13796         fi
13797         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13798         local fd
13799         local cmd
13800
13801         rm -f $DIR/$tfile
13802         touch $DIR/$tfile
13803
13804         local fid=$($LFS path2fid $DIR/$tfile)
13805         # Open the file
13806         fd=$(free_fd)
13807         cmd="exec $fd<$DIR/$tfile"
13808         eval $cmd
13809         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13810         echo "$fid_list" | grep "$fid"
13811         rc=$?
13812
13813         cmd="exec $fd>/dev/null"
13814         eval $cmd
13815         if [ $rc -ne 0 ]; then
13816                 error "FID $fid not found in open files list $fid_list"
13817         fi
13818 }
13819 run_test 154d "Verify open file fid"
13820
13821 test_154e()
13822 {
13823         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13824                 skip "Need MDS version at least 2.6.50"
13825
13826         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13827                 error ".lustre returned by readdir"
13828         fi
13829 }
13830 run_test 154e ".lustre is not returned by readdir"
13831
13832 test_154f() {
13833         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13834
13835         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13836         test_mkdir -p -c1 $DIR/$tdir/d
13837         # test dirs inherit from its stripe
13838         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13839         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13840         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13841         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13842         touch $DIR/f
13843
13844         # get fid of parents
13845         local FID0=$($LFS path2fid $DIR/$tdir/d)
13846         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13847         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13848         local FID3=$($LFS path2fid $DIR)
13849
13850         # check that path2fid --parents returns expected <parent_fid>/name
13851         # 1) test for a directory (single parent)
13852         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13853         [ "$parent" == "$FID0/foo1" ] ||
13854                 error "expected parent: $FID0/foo1, got: $parent"
13855
13856         # 2) test for a file with nlink > 1 (multiple parents)
13857         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13858         echo "$parent" | grep -F "$FID1/$tfile" ||
13859                 error "$FID1/$tfile not returned in parent list"
13860         echo "$parent" | grep -F "$FID2/link" ||
13861                 error "$FID2/link not returned in parent list"
13862
13863         # 3) get parent by fid
13864         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13865         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13866         echo "$parent" | grep -F "$FID1/$tfile" ||
13867                 error "$FID1/$tfile not returned in parent list (by fid)"
13868         echo "$parent" | grep -F "$FID2/link" ||
13869                 error "$FID2/link not returned in parent list (by fid)"
13870
13871         # 4) test for entry in root directory
13872         parent=$($LFS path2fid --parents $DIR/f)
13873         echo "$parent" | grep -F "$FID3/f" ||
13874                 error "$FID3/f not returned in parent list"
13875
13876         # 5) test it on root directory
13877         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13878                 error "$MOUNT should not have parents"
13879
13880         # enable xattr caching and check that linkea is correctly updated
13881         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13882         save_lustre_params client "llite.*.xattr_cache" > $save
13883         lctl set_param llite.*.xattr_cache 1
13884
13885         # 6.1) linkea update on rename
13886         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13887
13888         # get parents by fid
13889         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13890         # foo1 should no longer be returned in parent list
13891         echo "$parent" | grep -F "$FID1" &&
13892                 error "$FID1 should no longer be in parent list"
13893         # the new path should appear
13894         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13895                 error "$FID2/$tfile.moved is not in parent list"
13896
13897         # 6.2) linkea update on unlink
13898         rm -f $DIR/$tdir/d/foo2/link
13899         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13900         # foo2/link should no longer be returned in parent list
13901         echo "$parent" | grep -F "$FID2/link" &&
13902                 error "$FID2/link should no longer be in parent list"
13903         true
13904
13905         rm -f $DIR/f
13906         restore_lustre_params < $save
13907         rm -f $save
13908 }
13909 run_test 154f "get parent fids by reading link ea"
13910
13911 test_154g()
13912 {
13913         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13914         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13915            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13916                 skip "Need MDS version at least 2.6.92"
13917
13918         mkdir -p $DIR/$tdir
13919         llapi_fid_test -d $DIR/$tdir
13920 }
13921 run_test 154g "various llapi FID tests"
13922
13923 test_155_small_load() {
13924     local temp=$TMP/$tfile
13925     local file=$DIR/$tfile
13926
13927     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13928         error "dd of=$temp bs=6096 count=1 failed"
13929     cp $temp $file
13930     cancel_lru_locks $OSC
13931     cmp $temp $file || error "$temp $file differ"
13932
13933     $TRUNCATE $temp 6000
13934     $TRUNCATE $file 6000
13935     cmp $temp $file || error "$temp $file differ (truncate1)"
13936
13937     echo "12345" >>$temp
13938     echo "12345" >>$file
13939     cmp $temp $file || error "$temp $file differ (append1)"
13940
13941     echo "12345" >>$temp
13942     echo "12345" >>$file
13943     cmp $temp $file || error "$temp $file differ (append2)"
13944
13945     rm -f $temp $file
13946     true
13947 }
13948
13949 test_155_big_load() {
13950         remote_ost_nodsh && skip "remote OST with nodsh"
13951
13952         local temp=$TMP/$tfile
13953         local file=$DIR/$tfile
13954
13955         free_min_max
13956         local cache_size=$(do_facet ost$((MAXI+1)) \
13957                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13958         local large_file_size=$((cache_size * 2))
13959
13960         echo "OSS cache size: $cache_size KB"
13961         echo "Large file size: $large_file_size KB"
13962
13963         [ $MAXV -le $large_file_size ] &&
13964                 skip_env "max available OST size needs > $large_file_size KB"
13965
13966         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13967
13968         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13969                 error "dd of=$temp bs=$large_file_size count=1k failed"
13970         cp $temp $file
13971         ls -lh $temp $file
13972         cancel_lru_locks osc
13973         cmp $temp $file || error "$temp $file differ"
13974
13975         rm -f $temp $file
13976         true
13977 }
13978
13979 save_writethrough() {
13980         local facets=$(get_facets OST)
13981
13982         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13983 }
13984
13985 test_155a() {
13986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13987
13988         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13989
13990         save_writethrough $p
13991
13992         set_cache read on
13993         set_cache writethrough on
13994         test_155_small_load
13995         restore_lustre_params < $p
13996         rm -f $p
13997 }
13998 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13999
14000 test_155b() {
14001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14002
14003         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14004
14005         save_writethrough $p
14006
14007         set_cache read on
14008         set_cache writethrough off
14009         test_155_small_load
14010         restore_lustre_params < $p
14011         rm -f $p
14012 }
14013 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14014
14015 test_155c() {
14016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14017
14018         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14019
14020         save_writethrough $p
14021
14022         set_cache read off
14023         set_cache writethrough on
14024         test_155_small_load
14025         restore_lustre_params < $p
14026         rm -f $p
14027 }
14028 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14029
14030 test_155d() {
14031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14032
14033         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14034
14035         save_writethrough $p
14036
14037         set_cache read off
14038         set_cache writethrough off
14039         test_155_small_load
14040         restore_lustre_params < $p
14041         rm -f $p
14042 }
14043 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14044
14045 test_155e() {
14046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14047
14048         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14049
14050         save_writethrough $p
14051
14052         set_cache read on
14053         set_cache writethrough on
14054         test_155_big_load
14055         restore_lustre_params < $p
14056         rm -f $p
14057 }
14058 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14059
14060 test_155f() {
14061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14062
14063         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14064
14065         save_writethrough $p
14066
14067         set_cache read on
14068         set_cache writethrough off
14069         test_155_big_load
14070         restore_lustre_params < $p
14071         rm -f $p
14072 }
14073 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14074
14075 test_155g() {
14076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14077
14078         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14079
14080         save_writethrough $p
14081
14082         set_cache read off
14083         set_cache writethrough on
14084         test_155_big_load
14085         restore_lustre_params < $p
14086         rm -f $p
14087 }
14088 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14089
14090 test_155h() {
14091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14092
14093         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14094
14095         save_writethrough $p
14096
14097         set_cache read off
14098         set_cache writethrough off
14099         test_155_big_load
14100         restore_lustre_params < $p
14101         rm -f $p
14102 }
14103 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14104
14105 test_156() {
14106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14107         remote_ost_nodsh && skip "remote OST with nodsh"
14108         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14109                 skip "stats not implemented on old servers"
14110         [ "$ost1_FSTYPE" = "zfs" ] &&
14111                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14112
14113         local CPAGES=3
14114         local BEFORE
14115         local AFTER
14116         local file="$DIR/$tfile"
14117         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14118
14119         save_writethrough $p
14120         roc_hit_init
14121
14122         log "Turn on read and write cache"
14123         set_cache read on
14124         set_cache writethrough on
14125
14126         log "Write data and read it back."
14127         log "Read should be satisfied from the cache."
14128         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14129         BEFORE=$(roc_hit)
14130         cancel_lru_locks osc
14131         cat $file >/dev/null
14132         AFTER=$(roc_hit)
14133         if ! let "AFTER - BEFORE == CPAGES"; then
14134                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14135         else
14136                 log "cache hits: before: $BEFORE, after: $AFTER"
14137         fi
14138
14139         log "Read again; it should be satisfied from the cache."
14140         BEFORE=$AFTER
14141         cancel_lru_locks osc
14142         cat $file >/dev/null
14143         AFTER=$(roc_hit)
14144         if ! let "AFTER - BEFORE == CPAGES"; then
14145                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14146         else
14147                 log "cache hits:: before: $BEFORE, after: $AFTER"
14148         fi
14149
14150         log "Turn off the read cache and turn on the write cache"
14151         set_cache read off
14152         set_cache writethrough on
14153
14154         log "Read again; it should be satisfied from the cache."
14155         BEFORE=$(roc_hit)
14156         cancel_lru_locks osc
14157         cat $file >/dev/null
14158         AFTER=$(roc_hit)
14159         if ! let "AFTER - BEFORE == CPAGES"; then
14160                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14161         else
14162                 log "cache hits:: before: $BEFORE, after: $AFTER"
14163         fi
14164
14165         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14166                 # > 2.12.56 uses pagecache if cached
14167                 log "Read again; it should not be satisfied from the cache."
14168                 BEFORE=$AFTER
14169                 cancel_lru_locks osc
14170                 cat $file >/dev/null
14171                 AFTER=$(roc_hit)
14172                 if ! let "AFTER - BEFORE == 0"; then
14173                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14174                 else
14175                         log "cache hits:: before: $BEFORE, after: $AFTER"
14176                 fi
14177         fi
14178
14179         log "Write data and read it back."
14180         log "Read should be satisfied from the cache."
14181         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14182         BEFORE=$(roc_hit)
14183         cancel_lru_locks osc
14184         cat $file >/dev/null
14185         AFTER=$(roc_hit)
14186         if ! let "AFTER - BEFORE == CPAGES"; then
14187                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14188         else
14189                 log "cache hits:: before: $BEFORE, after: $AFTER"
14190         fi
14191
14192         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14193                 # > 2.12.56 uses pagecache if cached
14194                 log "Read again; it should not be satisfied from the cache."
14195                 BEFORE=$AFTER
14196                 cancel_lru_locks osc
14197                 cat $file >/dev/null
14198                 AFTER=$(roc_hit)
14199                 if ! let "AFTER - BEFORE == 0"; then
14200                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14201                 else
14202                         log "cache hits:: before: $BEFORE, after: $AFTER"
14203                 fi
14204         fi
14205
14206         log "Turn off read and write cache"
14207         set_cache read off
14208         set_cache writethrough off
14209
14210         log "Write data and read it back"
14211         log "It should not be satisfied from the cache."
14212         rm -f $file
14213         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14214         cancel_lru_locks osc
14215         BEFORE=$(roc_hit)
14216         cat $file >/dev/null
14217         AFTER=$(roc_hit)
14218         if ! let "AFTER - BEFORE == 0"; then
14219                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14220         else
14221                 log "cache hits:: before: $BEFORE, after: $AFTER"
14222         fi
14223
14224         log "Turn on the read cache and turn off the write cache"
14225         set_cache read on
14226         set_cache writethrough off
14227
14228         log "Write data and read it back"
14229         log "It should not be satisfied from the cache."
14230         rm -f $file
14231         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14232         BEFORE=$(roc_hit)
14233         cancel_lru_locks osc
14234         cat $file >/dev/null
14235         AFTER=$(roc_hit)
14236         if ! let "AFTER - BEFORE == 0"; then
14237                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14238         else
14239                 log "cache hits:: before: $BEFORE, after: $AFTER"
14240         fi
14241
14242         log "Read again; it should be satisfied from the cache."
14243         BEFORE=$(roc_hit)
14244         cancel_lru_locks osc
14245         cat $file >/dev/null
14246         AFTER=$(roc_hit)
14247         if ! let "AFTER - BEFORE == CPAGES"; then
14248                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14249         else
14250                 log "cache hits:: before: $BEFORE, after: $AFTER"
14251         fi
14252
14253         restore_lustre_params < $p
14254         rm -f $p $file
14255 }
14256 run_test 156 "Verification of tunables"
14257
14258 test_160a() {
14259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14260         remote_mds_nodsh && skip "remote MDS with nodsh"
14261         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14262                 skip "Need MDS version at least 2.2.0"
14263
14264         changelog_register || error "changelog_register failed"
14265         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14266         changelog_users $SINGLEMDS | grep -q $cl_user ||
14267                 error "User $cl_user not found in changelog_users"
14268
14269         # change something
14270         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14271         changelog_clear 0 || error "changelog_clear failed"
14272         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14273         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14274         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14275         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14276         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14277         rm $DIR/$tdir/pics/desktop.jpg
14278
14279         changelog_dump | tail -10
14280
14281         echo "verifying changelog mask"
14282         changelog_chmask "-MKDIR"
14283         changelog_chmask "-CLOSE"
14284
14285         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14286         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14287
14288         changelog_chmask "+MKDIR"
14289         changelog_chmask "+CLOSE"
14290
14291         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14292         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14293
14294         changelog_dump | tail -10
14295         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14296         CLOSES=$(changelog_dump | grep -c "CLOSE")
14297         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14298         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14299
14300         # verify contents
14301         echo "verifying target fid"
14302         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14303         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14304         [ "$fidc" == "$fidf" ] ||
14305                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14306         echo "verifying parent fid"
14307         # The FID returned from the Changelog may be the directory shard on
14308         # a different MDT, and not the FID returned by path2fid on the parent.
14309         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14310         # since this is what will matter when recreating this file in the tree.
14311         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14312         local pathp=$($LFS fid2path $MOUNT "$fidp")
14313         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14314                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14315
14316         echo "getting records for $cl_user"
14317         changelog_users $SINGLEMDS
14318         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14319         local nclr=3
14320         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14321                 error "changelog_clear failed"
14322         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14323         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14324         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14325                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14326
14327         local min0_rec=$(changelog_users $SINGLEMDS |
14328                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14329         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14330                           awk '{ print $1; exit; }')
14331
14332         changelog_dump | tail -n 5
14333         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14334         [ $first_rec == $((min0_rec + 1)) ] ||
14335                 error "first index should be $min0_rec + 1 not $first_rec"
14336
14337         # LU-3446 changelog index reset on MDT restart
14338         local cur_rec1=$(changelog_users $SINGLEMDS |
14339                          awk '/^current.index:/ { print $NF }')
14340         changelog_clear 0 ||
14341                 error "clear all changelog records for $cl_user failed"
14342         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14343         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14344                 error "Fail to start $SINGLEMDS"
14345         local cur_rec2=$(changelog_users $SINGLEMDS |
14346                          awk '/^current.index:/ { print $NF }')
14347         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14348         [ $cur_rec1 == $cur_rec2 ] ||
14349                 error "current index should be $cur_rec1 not $cur_rec2"
14350
14351         echo "verifying users from this test are deregistered"
14352         changelog_deregister || error "changelog_deregister failed"
14353         changelog_users $SINGLEMDS | grep -q $cl_user &&
14354                 error "User '$cl_user' still in changelog_users"
14355
14356         # lctl get_param -n mdd.*.changelog_users
14357         # current index: 144
14358         # ID    index (idle seconds)
14359         # cl3   144 (2)
14360         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14361                 # this is the normal case where all users were deregistered
14362                 # make sure no new records are added when no users are present
14363                 local last_rec1=$(changelog_users $SINGLEMDS |
14364                                   awk '/^current.index:/ { print $NF }')
14365                 touch $DIR/$tdir/chloe
14366                 local last_rec2=$(changelog_users $SINGLEMDS |
14367                                   awk '/^current.index:/ { print $NF }')
14368                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14369                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14370         else
14371                 # any changelog users must be leftovers from a previous test
14372                 changelog_users $SINGLEMDS
14373                 echo "other changelog users; can't verify off"
14374         fi
14375 }
14376 run_test 160a "changelog sanity"
14377
14378 test_160b() { # LU-3587
14379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14380         remote_mds_nodsh && skip "remote MDS with nodsh"
14381         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14382                 skip "Need MDS version at least 2.2.0"
14383
14384         changelog_register || error "changelog_register failed"
14385         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14386         changelog_users $SINGLEMDS | grep -q $cl_user ||
14387                 error "User '$cl_user' not found in changelog_users"
14388
14389         local longname1=$(str_repeat a 255)
14390         local longname2=$(str_repeat b 255)
14391
14392         cd $DIR
14393         echo "creating very long named file"
14394         touch $longname1 || error "create of '$longname1' failed"
14395         echo "renaming very long named file"
14396         mv $longname1 $longname2
14397
14398         changelog_dump | grep RENME | tail -n 5
14399         rm -f $longname2
14400 }
14401 run_test 160b "Verify that very long rename doesn't crash in changelog"
14402
14403 test_160c() {
14404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14405         remote_mds_nodsh && skip "remote MDS with nodsh"
14406
14407         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14408                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14409                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14410                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14411
14412         local rc=0
14413
14414         # Registration step
14415         changelog_register || error "changelog_register failed"
14416
14417         rm -rf $DIR/$tdir
14418         mkdir -p $DIR/$tdir
14419         $MCREATE $DIR/$tdir/foo_160c
14420         changelog_chmask "-TRUNC"
14421         $TRUNCATE $DIR/$tdir/foo_160c 200
14422         changelog_chmask "+TRUNC"
14423         $TRUNCATE $DIR/$tdir/foo_160c 199
14424         changelog_dump | tail -n 5
14425         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14426         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14427 }
14428 run_test 160c "verify that changelog log catch the truncate event"
14429
14430 test_160d() {
14431         remote_mds_nodsh && skip "remote MDS with nodsh"
14432         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14434         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14435                 skip "Need MDS version at least 2.7.60"
14436
14437         # Registration step
14438         changelog_register || error "changelog_register failed"
14439
14440         mkdir -p $DIR/$tdir/migrate_dir
14441         changelog_clear 0 || error "changelog_clear failed"
14442
14443         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14444         changelog_dump | tail -n 5
14445         local migrates=$(changelog_dump | grep -c "MIGRT")
14446         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14447 }
14448 run_test 160d "verify that changelog log catch the migrate event"
14449
14450 test_160e() {
14451         remote_mds_nodsh && skip "remote MDS with nodsh"
14452
14453         # Create a user
14454         changelog_register || error "changelog_register failed"
14455
14456         # Delete a future user (expect fail)
14457         local MDT0=$(facet_svc $SINGLEMDS)
14458         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14459         local rc=$?
14460
14461         if [ $rc -eq 0 ]; then
14462                 error "Deleted non-existant user cl77"
14463         elif [ $rc -ne 2 ]; then
14464                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14465         fi
14466
14467         # Clear to a bad index (1 billion should be safe)
14468         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14469         rc=$?
14470
14471         if [ $rc -eq 0 ]; then
14472                 error "Successfully cleared to invalid CL index"
14473         elif [ $rc -ne 22 ]; then
14474                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14475         fi
14476 }
14477 run_test 160e "changelog negative testing (should return errors)"
14478
14479 test_160f() {
14480         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14481         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14482                 skip "Need MDS version at least 2.10.56"
14483
14484         local mdts=$(comma_list $(mdts_nodes))
14485
14486         # Create a user
14487         changelog_register || error "first changelog_register failed"
14488         changelog_register || error "second changelog_register failed"
14489         local cl_users
14490         declare -A cl_user1
14491         declare -A cl_user2
14492         local user_rec1
14493         local user_rec2
14494         local i
14495
14496         # generate some changelog records to accumulate on each MDT
14497         # use fnv1a because created files should be evenly distributed
14498         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14499                 error "test_mkdir $tdir failed"
14500         log "$(date +%s): creating first files"
14501         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14502                 error "create $DIR/$tdir/$tfile failed"
14503
14504         # check changelogs have been generated
14505         local start=$SECONDS
14506         local idle_time=$((MDSCOUNT * 5 + 5))
14507         local nbcl=$(changelog_dump | wc -l)
14508         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14509
14510         for param in "changelog_max_idle_time=$idle_time" \
14511                      "changelog_gc=1" \
14512                      "changelog_min_gc_interval=2" \
14513                      "changelog_min_free_cat_entries=3"; do
14514                 local MDT0=$(facet_svc $SINGLEMDS)
14515                 local var="${param%=*}"
14516                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14517
14518                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14519                 do_nodes $mdts $LCTL set_param mdd.*.$param
14520         done
14521
14522         # force cl_user2 to be idle (1st part), but also cancel the
14523         # cl_user1 records so that it is not evicted later in the test.
14524         local sleep1=$((idle_time / 2))
14525         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14526         sleep $sleep1
14527
14528         # simulate changelog catalog almost full
14529         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14530         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14531
14532         for i in $(seq $MDSCOUNT); do
14533                 cl_users=(${CL_USERS[mds$i]})
14534                 cl_user1[mds$i]="${cl_users[0]}"
14535                 cl_user2[mds$i]="${cl_users[1]}"
14536
14537                 [ -n "${cl_user1[mds$i]}" ] ||
14538                         error "mds$i: no user registered"
14539                 [ -n "${cl_user2[mds$i]}" ] ||
14540                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14541
14542                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14543                 [ -n "$user_rec1" ] ||
14544                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14545                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14546                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14547                 [ -n "$user_rec2" ] ||
14548                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14549                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14550                      "$user_rec1 + 2 == $user_rec2"
14551                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14552                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14553                               "$user_rec1 + 2, but is $user_rec2"
14554                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14555                 [ -n "$user_rec2" ] ||
14556                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14557                 [ $user_rec1 == $user_rec2 ] ||
14558                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14559                               "$user_rec1, but is $user_rec2"
14560         done
14561
14562         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14563         local sleep2=$((idle_time - (SECONDS - start) + 1))
14564         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14565         sleep $sleep2
14566
14567         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14568         # cl_user1 should be OK because it recently processed records.
14569         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14570         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14571                 error "create $DIR/$tdir/${tfile}b failed"
14572
14573         # ensure gc thread is done
14574         for i in $(mdts_nodes); do
14575                 wait_update $i \
14576                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14577                         error "$i: GC-thread not done"
14578         done
14579
14580         local first_rec
14581         for i in $(seq $MDSCOUNT); do
14582                 # check cl_user1 still registered
14583                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14584                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14585                 # check cl_user2 unregistered
14586                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14587                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14588
14589                 # check changelogs are present and starting at $user_rec1 + 1
14590                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14591                 [ -n "$user_rec1" ] ||
14592                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14593                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14594                             awk '{ print $1; exit; }')
14595
14596                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14597                 [ $((user_rec1 + 1)) == $first_rec ] ||
14598                         error "mds$i: first index should be $user_rec1 + 1, " \
14599                               "but is $first_rec"
14600         done
14601 }
14602 run_test 160f "changelog garbage collect (timestamped users)"
14603
14604 test_160g() {
14605         remote_mds_nodsh && skip "remote MDS with nodsh"
14606         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14607                 skip "Need MDS version at least 2.10.56"
14608
14609         local mdts=$(comma_list $(mdts_nodes))
14610
14611         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14612         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14613
14614         # Create a user
14615         changelog_register || error "first changelog_register failed"
14616         changelog_register || error "second changelog_register failed"
14617         local cl_users
14618         declare -A cl_user1
14619         declare -A cl_user2
14620         local user_rec1
14621         local user_rec2
14622         local i
14623
14624         # generate some changelog records to accumulate on each MDT
14625         # use fnv1a because created files should be evenly distributed
14626         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14627                 error "mkdir $tdir failed"
14628         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14629                 error "create $DIR/$tdir/$tfile failed"
14630
14631         # check changelogs have been generated
14632         local nbcl=$(changelog_dump | wc -l)
14633         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14634
14635         # reduce the max_idle_indexes value to make sure we exceed it
14636         max_ndx=$((nbcl / 2 - 1))
14637
14638         for param in "changelog_max_idle_indexes=$max_ndx" \
14639                      "changelog_gc=1" \
14640                      "changelog_min_gc_interval=2" \
14641                      "changelog_min_free_cat_entries=3"; do
14642                 local MDT0=$(facet_svc $SINGLEMDS)
14643                 local var="${param%=*}"
14644                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14645
14646                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14647                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14648                         error "unable to set mdd.*.$param"
14649         done
14650
14651         # simulate changelog catalog almost full
14652         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14653         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14654
14655         for i in $(seq $MDSCOUNT); do
14656                 cl_users=(${CL_USERS[mds$i]})
14657                 cl_user1[mds$i]="${cl_users[0]}"
14658                 cl_user2[mds$i]="${cl_users[1]}"
14659
14660                 [ -n "${cl_user1[mds$i]}" ] ||
14661                         error "mds$i: no user registered"
14662                 [ -n "${cl_user2[mds$i]}" ] ||
14663                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14664
14665                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14666                 [ -n "$user_rec1" ] ||
14667                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14668                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14669                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14670                 [ -n "$user_rec2" ] ||
14671                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14672                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14673                      "$user_rec1 + 2 == $user_rec2"
14674                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14675                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14676                               "$user_rec1 + 2, but is $user_rec2"
14677                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14678                 [ -n "$user_rec2" ] ||
14679                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14680                 [ $user_rec1 == $user_rec2 ] ||
14681                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14682                               "$user_rec1, but is $user_rec2"
14683         done
14684
14685         # ensure we are past the previous changelog_min_gc_interval set above
14686         sleep 2
14687
14688         # generate one more changelog to trigger fail_loc
14689         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14690                 error "create $DIR/$tdir/${tfile}bis failed"
14691
14692         # ensure gc thread is done
14693         for i in $(mdts_nodes); do
14694                 wait_update $i \
14695                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14696                         error "$i: GC-thread not done"
14697         done
14698
14699         local first_rec
14700         for i in $(seq $MDSCOUNT); do
14701                 # check cl_user1 still registered
14702                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14703                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14704                 # check cl_user2 unregistered
14705                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14706                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14707
14708                 # check changelogs are present and starting at $user_rec1 + 1
14709                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14710                 [ -n "$user_rec1" ] ||
14711                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14712                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14713                             awk '{ print $1; exit; }')
14714
14715                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14716                 [ $((user_rec1 + 1)) == $first_rec ] ||
14717                         error "mds$i: first index should be $user_rec1 + 1, " \
14718                               "but is $first_rec"
14719         done
14720 }
14721 run_test 160g "changelog garbage collect (old users)"
14722
14723 test_160h() {
14724         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14725         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14726                 skip "Need MDS version at least 2.10.56"
14727
14728         local mdts=$(comma_list $(mdts_nodes))
14729
14730         # Create a user
14731         changelog_register || error "first changelog_register failed"
14732         changelog_register || error "second changelog_register failed"
14733         local cl_users
14734         declare -A cl_user1
14735         declare -A cl_user2
14736         local user_rec1
14737         local user_rec2
14738         local i
14739
14740         # generate some changelog records to accumulate on each MDT
14741         # use fnv1a because created files should be evenly distributed
14742         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14743                 error "test_mkdir $tdir failed"
14744         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14745                 error "create $DIR/$tdir/$tfile failed"
14746
14747         # check changelogs have been generated
14748         local nbcl=$(changelog_dump | wc -l)
14749         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14750
14751         for param in "changelog_max_idle_time=10" \
14752                      "changelog_gc=1" \
14753                      "changelog_min_gc_interval=2"; do
14754                 local MDT0=$(facet_svc $SINGLEMDS)
14755                 local var="${param%=*}"
14756                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14757
14758                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14759                 do_nodes $mdts $LCTL set_param mdd.*.$param
14760         done
14761
14762         # force cl_user2 to be idle (1st part)
14763         sleep 9
14764
14765         for i in $(seq $MDSCOUNT); do
14766                 cl_users=(${CL_USERS[mds$i]})
14767                 cl_user1[mds$i]="${cl_users[0]}"
14768                 cl_user2[mds$i]="${cl_users[1]}"
14769
14770                 [ -n "${cl_user1[mds$i]}" ] ||
14771                         error "mds$i: no user registered"
14772                 [ -n "${cl_user2[mds$i]}" ] ||
14773                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14774
14775                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14776                 [ -n "$user_rec1" ] ||
14777                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14778                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14779                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14780                 [ -n "$user_rec2" ] ||
14781                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14782                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14783                      "$user_rec1 + 2 == $user_rec2"
14784                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14785                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14786                               "$user_rec1 + 2, but is $user_rec2"
14787                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14788                 [ -n "$user_rec2" ] ||
14789                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14790                 [ $user_rec1 == $user_rec2 ] ||
14791                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14792                               "$user_rec1, but is $user_rec2"
14793         done
14794
14795         # force cl_user2 to be idle (2nd part) and to reach
14796         # changelog_max_idle_time
14797         sleep 2
14798
14799         # force each GC-thread start and block then
14800         # one per MDT/MDD, set fail_val accordingly
14801         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14802         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14803
14804         # generate more changelogs to trigger fail_loc
14805         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14806                 error "create $DIR/$tdir/${tfile}bis failed"
14807
14808         # stop MDT to stop GC-thread, should be done in back-ground as it will
14809         # block waiting for the thread to be released and exit
14810         declare -A stop_pids
14811         for i in $(seq $MDSCOUNT); do
14812                 stop mds$i &
14813                 stop_pids[mds$i]=$!
14814         done
14815
14816         for i in $(mdts_nodes); do
14817                 local facet
14818                 local nb=0
14819                 local facets=$(facets_up_on_host $i)
14820
14821                 for facet in ${facets//,/ }; do
14822                         if [[ $facet == mds* ]]; then
14823                                 nb=$((nb + 1))
14824                         fi
14825                 done
14826                 # ensure each MDS's gc threads are still present and all in "R"
14827                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14828                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14829                         error "$i: expected $nb GC-thread"
14830                 wait_update $i \
14831                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14832                         "R" 20 ||
14833                         error "$i: GC-thread not found in R-state"
14834                 # check umounts of each MDT on MDS have reached kthread_stop()
14835                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14836                         error "$i: expected $nb umount"
14837                 wait_update $i \
14838                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14839                         error "$i: umount not found in D-state"
14840         done
14841
14842         # release all GC-threads
14843         do_nodes $mdts $LCTL set_param fail_loc=0
14844
14845         # wait for MDT stop to complete
14846         for i in $(seq $MDSCOUNT); do
14847                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14848         done
14849
14850         # XXX
14851         # may try to check if any orphan changelog records are present
14852         # via ldiskfs/zfs and llog_reader...
14853
14854         # re-start/mount MDTs
14855         for i in $(seq $MDSCOUNT); do
14856                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14857                         error "Fail to start mds$i"
14858         done
14859
14860         local first_rec
14861         for i in $(seq $MDSCOUNT); do
14862                 # check cl_user1 still registered
14863                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14864                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14865                 # check cl_user2 unregistered
14866                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14867                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14868
14869                 # check changelogs are present and starting at $user_rec1 + 1
14870                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14871                 [ -n "$user_rec1" ] ||
14872                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14873                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14874                             awk '{ print $1; exit; }')
14875
14876                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14877                 [ $((user_rec1 + 1)) == $first_rec ] ||
14878                         error "mds$i: first index should be $user_rec1 + 1, " \
14879                               "but is $first_rec"
14880         done
14881 }
14882 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14883               "during mount"
14884
14885 test_160i() {
14886
14887         local mdts=$(comma_list $(mdts_nodes))
14888
14889         changelog_register || error "first changelog_register failed"
14890
14891         # generate some changelog records to accumulate on each MDT
14892         # use fnv1a because created files should be evenly distributed
14893         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14894                 error "mkdir $tdir failed"
14895         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14896                 error "create $DIR/$tdir/$tfile failed"
14897
14898         # check changelogs have been generated
14899         local nbcl=$(changelog_dump | wc -l)
14900         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14901
14902         # simulate race between register and unregister
14903         # XXX as fail_loc is set per-MDS, with DNE configs the race
14904         # simulation will only occur for one MDT per MDS and for the
14905         # others the normal race scenario will take place
14906         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14907         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14908         do_nodes $mdts $LCTL set_param fail_val=1
14909
14910         # unregister 1st user
14911         changelog_deregister &
14912         local pid1=$!
14913         # wait some time for deregister work to reach race rdv
14914         sleep 2
14915         # register 2nd user
14916         changelog_register || error "2nd user register failed"
14917
14918         wait $pid1 || error "1st user deregister failed"
14919
14920         local i
14921         local last_rec
14922         declare -A LAST_REC
14923         for i in $(seq $MDSCOUNT); do
14924                 if changelog_users mds$i | grep "^cl"; then
14925                         # make sure new records are added with one user present
14926                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14927                                           awk '/^current.index:/ { print $NF }')
14928                 else
14929                         error "mds$i has no user registered"
14930                 fi
14931         done
14932
14933         # generate more changelog records to accumulate on each MDT
14934         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14935                 error "create $DIR/$tdir/${tfile}bis failed"
14936
14937         for i in $(seq $MDSCOUNT); do
14938                 last_rec=$(changelog_users $SINGLEMDS |
14939                            awk '/^current.index:/ { print $NF }')
14940                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14941                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14942                         error "changelogs are off on mds$i"
14943         done
14944 }
14945 run_test 160i "changelog user register/unregister race"
14946
14947 test_160j() {
14948         remote_mds_nodsh && skip "remote MDS with nodsh"
14949         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14950                 skip "Need MDS version at least 2.12.56"
14951
14952         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14953         stack_trap "umount $MOUNT2" EXIT
14954
14955         changelog_register || error "first changelog_register failed"
14956         stack_trap "changelog_deregister" EXIT
14957
14958         # generate some changelog
14959         # use fnv1a because created files should be evenly distributed
14960         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14961                 error "mkdir $tdir failed"
14962         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14963                 error "create $DIR/$tdir/${tfile}bis failed"
14964
14965         # open the changelog device
14966         exec 3>/dev/changelog-$FSNAME-MDT0000
14967         stack_trap "exec 3>&-" EXIT
14968         exec 4</dev/changelog-$FSNAME-MDT0000
14969         stack_trap "exec 4<&-" EXIT
14970
14971         # umount the first lustre mount
14972         umount $MOUNT
14973         stack_trap "mount_client $MOUNT" EXIT
14974
14975         # read changelog
14976         cat <&4 >/dev/null || error "read changelog failed"
14977
14978         # clear changelog
14979         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14980         changelog_users $SINGLEMDS | grep -q $cl_user ||
14981                 error "User $cl_user not found in changelog_users"
14982
14983         printf 'clear:'$cl_user':0' >&3
14984 }
14985 run_test 160j "client can be umounted  while its chanangelog is being used"
14986
14987 test_160k() {
14988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14989         remote_mds_nodsh && skip "remote MDS with nodsh"
14990
14991         mkdir -p $DIR/$tdir/1/1
14992
14993         changelog_register || error "changelog_register failed"
14994         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14995
14996         changelog_users $SINGLEMDS | grep -q $cl_user ||
14997                 error "User '$cl_user' not found in changelog_users"
14998 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14999         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15000         rmdir $DIR/$tdir/1/1 & sleep 1
15001         mkdir $DIR/$tdir/2
15002         touch $DIR/$tdir/2/2
15003         rm -rf $DIR/$tdir/2
15004
15005         wait
15006         sleep 4
15007
15008         changelog_dump | grep rmdir || error "rmdir not recorded"
15009
15010         rm -rf $DIR/$tdir
15011         changelog_deregister
15012 }
15013 run_test 160k "Verify that changelog records are not lost"
15014
15015 # Verifies that a file passed as a parameter has recently had an operation
15016 # performed on it that has generated an MTIME changelog which contains the
15017 # correct parent FID. As files might reside on a different MDT from the
15018 # parent directory in DNE configurations, the FIDs are translated to paths
15019 # before being compared, which should be identical
15020 compare_mtime_changelog() {
15021         local file="${1}"
15022         local mdtidx
15023         local mtime
15024         local cl_fid
15025         local pdir
15026         local dir
15027
15028         mdtidx=$($LFS getstripe --mdt-index $file)
15029         mdtidx=$(printf "%04x" $mdtidx)
15030
15031         # Obtain the parent FID from the MTIME changelog
15032         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15033         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15034
15035         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15036         [ -z "$cl_fid" ] && error "parent FID not present"
15037
15038         # Verify that the path for the parent FID is the same as the path for
15039         # the test directory
15040         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15041
15042         dir=$(dirname $1)
15043
15044         [[ "${pdir%/}" == "$dir" ]] ||
15045                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15046 }
15047
15048 test_160l() {
15049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15050
15051         remote_mds_nodsh && skip "remote MDS with nodsh"
15052         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15053                 skip "Need MDS version at least 2.13.55"
15054
15055         local cl_user
15056
15057         changelog_register || error "changelog_register failed"
15058         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15059
15060         changelog_users $SINGLEMDS | grep -q $cl_user ||
15061                 error "User '$cl_user' not found in changelog_users"
15062
15063         # Clear some types so that MTIME changelogs are generated
15064         changelog_chmask "-CREAT"
15065         changelog_chmask "-CLOSE"
15066
15067         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15068
15069         # Test CL_MTIME during setattr
15070         touch $DIR/$tdir/$tfile
15071         compare_mtime_changelog $DIR/$tdir/$tfile
15072
15073         # Test CL_MTIME during close
15074         dd if=/dev/urandom of=$DIR/$tdir/${tfile}_2 bs=1M count=64 ||
15075                 error "cannot create file $DIR/$tdir/${tfile}_2"
15076         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15077 }
15078 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15079
15080 test_161a() {
15081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15082
15083         test_mkdir -c1 $DIR/$tdir
15084         cp /etc/hosts $DIR/$tdir/$tfile
15085         test_mkdir -c1 $DIR/$tdir/foo1
15086         test_mkdir -c1 $DIR/$tdir/foo2
15087         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15088         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15089         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15090         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15091         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15092         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15093                 $LFS fid2path $DIR $FID
15094                 error "bad link ea"
15095         fi
15096         # middle
15097         rm $DIR/$tdir/foo2/zachary
15098         # last
15099         rm $DIR/$tdir/foo2/thor
15100         # first
15101         rm $DIR/$tdir/$tfile
15102         # rename
15103         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15104         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15105                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15106         rm $DIR/$tdir/foo2/maggie
15107
15108         # overflow the EA
15109         local longname=$tfile.avg_len_is_thirty_two_
15110         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15111                 error_noexit 'failed to unlink many hardlinks'" EXIT
15112         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15113                 error "failed to hardlink many files"
15114         links=$($LFS fid2path $DIR $FID | wc -l)
15115         echo -n "${links}/1000 links in link EA"
15116         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15117 }
15118 run_test 161a "link ea sanity"
15119
15120 test_161b() {
15121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15122         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15123
15124         local MDTIDX=1
15125         local remote_dir=$DIR/$tdir/remote_dir
15126
15127         mkdir -p $DIR/$tdir
15128         $LFS mkdir -i $MDTIDX $remote_dir ||
15129                 error "create remote directory failed"
15130
15131         cp /etc/hosts $remote_dir/$tfile
15132         mkdir -p $remote_dir/foo1
15133         mkdir -p $remote_dir/foo2
15134         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15135         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15136         ln $remote_dir/$tfile $remote_dir/foo1/luna
15137         ln $remote_dir/$tfile $remote_dir/foo2/thor
15138
15139         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15140                      tr -d ']')
15141         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15142                 $LFS fid2path $DIR $FID
15143                 error "bad link ea"
15144         fi
15145         # middle
15146         rm $remote_dir/foo2/zachary
15147         # last
15148         rm $remote_dir/foo2/thor
15149         # first
15150         rm $remote_dir/$tfile
15151         # rename
15152         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15153         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15154         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15155                 $LFS fid2path $DIR $FID
15156                 error "bad link rename"
15157         fi
15158         rm $remote_dir/foo2/maggie
15159
15160         # overflow the EA
15161         local longname=filename_avg_len_is_thirty_two_
15162         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15163                 error "failed to hardlink many files"
15164         links=$($LFS fid2path $DIR $FID | wc -l)
15165         echo -n "${links}/1000 links in link EA"
15166         [[ ${links} -gt 60 ]] ||
15167                 error "expected at least 60 links in link EA"
15168         unlinkmany $remote_dir/foo2/$longname 1000 ||
15169         error "failed to unlink many hardlinks"
15170 }
15171 run_test 161b "link ea sanity under remote directory"
15172
15173 test_161c() {
15174         remote_mds_nodsh && skip "remote MDS with nodsh"
15175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15176         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15177                 skip "Need MDS version at least 2.1.5"
15178
15179         # define CLF_RENAME_LAST 0x0001
15180         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15181         changelog_register || error "changelog_register failed"
15182
15183         rm -rf $DIR/$tdir
15184         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15185         touch $DIR/$tdir/foo_161c
15186         touch $DIR/$tdir/bar_161c
15187         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15188         changelog_dump | grep RENME | tail -n 5
15189         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15190         changelog_clear 0 || error "changelog_clear failed"
15191         if [ x$flags != "x0x1" ]; then
15192                 error "flag $flags is not 0x1"
15193         fi
15194
15195         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15196         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15197         touch $DIR/$tdir/foo_161c
15198         touch $DIR/$tdir/bar_161c
15199         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15200         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15201         changelog_dump | grep RENME | tail -n 5
15202         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15203         changelog_clear 0 || error "changelog_clear failed"
15204         if [ x$flags != "x0x0" ]; then
15205                 error "flag $flags is not 0x0"
15206         fi
15207         echo "rename overwrite a target having nlink > 1," \
15208                 "changelog record has flags of $flags"
15209
15210         # rename doesn't overwrite a target (changelog flag 0x0)
15211         touch $DIR/$tdir/foo_161c
15212         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15213         changelog_dump | grep RENME | tail -n 5
15214         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15215         changelog_clear 0 || error "changelog_clear failed"
15216         if [ x$flags != "x0x0" ]; then
15217                 error "flag $flags is not 0x0"
15218         fi
15219         echo "rename doesn't overwrite a target," \
15220                 "changelog record has flags of $flags"
15221
15222         # define CLF_UNLINK_LAST 0x0001
15223         # unlink a file having nlink = 1 (changelog flag 0x1)
15224         rm -f $DIR/$tdir/foo2_161c
15225         changelog_dump | grep UNLNK | tail -n 5
15226         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15227         changelog_clear 0 || error "changelog_clear failed"
15228         if [ x$flags != "x0x1" ]; then
15229                 error "flag $flags is not 0x1"
15230         fi
15231         echo "unlink a file having nlink = 1," \
15232                 "changelog record has flags of $flags"
15233
15234         # unlink a file having nlink > 1 (changelog flag 0x0)
15235         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15236         rm -f $DIR/$tdir/foobar_161c
15237         changelog_dump | grep UNLNK | tail -n 5
15238         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15239         changelog_clear 0 || error "changelog_clear failed"
15240         if [ x$flags != "x0x0" ]; then
15241                 error "flag $flags is not 0x0"
15242         fi
15243         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15244 }
15245 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15246
15247 test_161d() {
15248         remote_mds_nodsh && skip "remote MDS with nodsh"
15249         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15250
15251         local pid
15252         local fid
15253
15254         changelog_register || error "changelog_register failed"
15255
15256         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15257         # interfer with $MOUNT/.lustre/fid/ access
15258         mkdir $DIR/$tdir
15259         [[ $? -eq 0 ]] || error "mkdir failed"
15260
15261         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15262         $LCTL set_param fail_loc=0x8000140c
15263         # 5s pause
15264         $LCTL set_param fail_val=5
15265
15266         # create file
15267         echo foofoo > $DIR/$tdir/$tfile &
15268         pid=$!
15269
15270         # wait for create to be delayed
15271         sleep 2
15272
15273         ps -p $pid
15274         [[ $? -eq 0 ]] || error "create should be blocked"
15275
15276         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15277         stack_trap "rm -f $tempfile"
15278         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15279         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15280         # some delay may occur during ChangeLog publishing and file read just
15281         # above, that could allow file write to happen finally
15282         [[ -s $tempfile ]] && echo "file should be empty"
15283
15284         $LCTL set_param fail_loc=0
15285
15286         wait $pid
15287         [[ $? -eq 0 ]] || error "create failed"
15288 }
15289 run_test 161d "create with concurrent .lustre/fid access"
15290
15291 check_path() {
15292         local expected="$1"
15293         shift
15294         local fid="$2"
15295
15296         local path
15297         path=$($LFS fid2path "$@")
15298         local rc=$?
15299
15300         if [ $rc -ne 0 ]; then
15301                 error "path looked up of '$expected' failed: rc=$rc"
15302         elif [ "$path" != "$expected" ]; then
15303                 error "path looked up '$path' instead of '$expected'"
15304         else
15305                 echo "FID '$fid' resolves to path '$path' as expected"
15306         fi
15307 }
15308
15309 test_162a() { # was test_162
15310         test_mkdir -p -c1 $DIR/$tdir/d2
15311         touch $DIR/$tdir/d2/$tfile
15312         touch $DIR/$tdir/d2/x1
15313         touch $DIR/$tdir/d2/x2
15314         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15315         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15316         # regular file
15317         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15318         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15319
15320         # softlink
15321         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15322         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15323         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15324
15325         # softlink to wrong file
15326         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15327         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15328         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15329
15330         # hardlink
15331         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15332         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15333         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15334         # fid2path dir/fsname should both work
15335         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15336         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15337
15338         # hardlink count: check that there are 2 links
15339         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15340         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15341
15342         # hardlink indexing: remove the first link
15343         rm $DIR/$tdir/d2/p/q/r/hlink
15344         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15345 }
15346 run_test 162a "path lookup sanity"
15347
15348 test_162b() {
15349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15350         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15351
15352         mkdir $DIR/$tdir
15353         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15354                                 error "create striped dir failed"
15355
15356         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15357                                         tail -n 1 | awk '{print $2}')
15358         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15359
15360         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15361         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15362
15363         # regular file
15364         for ((i=0;i<5;i++)); do
15365                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15366                         error "get fid for f$i failed"
15367                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15368
15369                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15370                         error "get fid for d$i failed"
15371                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15372         done
15373
15374         return 0
15375 }
15376 run_test 162b "striped directory path lookup sanity"
15377
15378 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15379 test_162c() {
15380         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15381                 skip "Need MDS version at least 2.7.51"
15382
15383         local lpath=$tdir.local
15384         local rpath=$tdir.remote
15385
15386         test_mkdir $DIR/$lpath
15387         test_mkdir $DIR/$rpath
15388
15389         for ((i = 0; i <= 101; i++)); do
15390                 lpath="$lpath/$i"
15391                 mkdir $DIR/$lpath
15392                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15393                         error "get fid for local directory $DIR/$lpath failed"
15394                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15395
15396                 rpath="$rpath/$i"
15397                 test_mkdir $DIR/$rpath
15398                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15399                         error "get fid for remote directory $DIR/$rpath failed"
15400                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15401         done
15402
15403         return 0
15404 }
15405 run_test 162c "fid2path works with paths 100 or more directories deep"
15406
15407 oalr_event_count() {
15408         local event="${1}"
15409         local trace="${2}"
15410
15411         awk -v name="${FSNAME}-OST0000" \
15412             -v event="${event}" \
15413             '$1 == "TRACE" && $2 == event && $3 == name' \
15414             "${trace}" |
15415         wc -l
15416 }
15417
15418 oalr_expect_event_count() {
15419         local event="${1}"
15420         local trace="${2}"
15421         local expect="${3}"
15422         local count
15423
15424         count=$(oalr_event_count "${event}" "${trace}")
15425         if ((count == expect)); then
15426                 return 0
15427         fi
15428
15429         error_noexit "${event} event count was '${count}', expected ${expect}"
15430         cat "${trace}" >&2
15431         exit 1
15432 }
15433
15434 cleanup_165() {
15435         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15436         stop ost1
15437         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15438 }
15439
15440 setup_165() {
15441         sync # Flush previous IOs so we can count log entries.
15442         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15443         stack_trap cleanup_165 EXIT
15444 }
15445
15446 test_165a() {
15447         local trace="/tmp/${tfile}.trace"
15448         local rc
15449         local count
15450
15451         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15452         setup_165
15453         sleep 5
15454
15455         do_facet ost1 ofd_access_log_reader --list
15456         stop ost1
15457
15458         do_facet ost1 killall -TERM ofd_access_log_reader
15459         wait
15460         rc=$?
15461
15462         if ((rc != 0)); then
15463                 error "ofd_access_log_reader exited with rc = '${rc}'"
15464         fi
15465
15466         # Parse trace file for discovery events:
15467         oalr_expect_event_count alr_log_add "${trace}" 1
15468         oalr_expect_event_count alr_log_eof "${trace}" 1
15469         oalr_expect_event_count alr_log_free "${trace}" 1
15470 }
15471 run_test 165a "ofd access log discovery"
15472
15473 test_165b() {
15474         local trace="/tmp/${tfile}.trace"
15475         local file="${DIR}/${tfile}"
15476         local pfid1
15477         local pfid2
15478         local -a entry
15479         local rc
15480         local count
15481         local size
15482         local flags
15483
15484         setup_165
15485
15486         lfs setstripe -c 1 -i 0 "${file}"
15487         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15488         do_facet ost1 ofd_access_log_reader --list
15489
15490         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15491         sleep 5
15492         do_facet ost1 killall -TERM ofd_access_log_reader
15493         wait
15494         rc=$?
15495
15496         if ((rc != 0)); then
15497                 error "ofd_access_log_reader exited with rc = '${rc}'"
15498         fi
15499
15500         oalr_expect_event_count alr_log_entry "${trace}" 1
15501
15502         pfid1=$($LFS path2fid "${file}")
15503
15504         # 1     2             3   4    5     6   7    8    9     10
15505         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15506         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15507
15508         echo "entry = '${entry[*]}'" >&2
15509
15510         pfid2=${entry[4]}
15511         if [[ "${pfid1}" != "${pfid2}" ]]; then
15512                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15513         fi
15514
15515         size=${entry[8]}
15516         if ((size != 1048576)); then
15517                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15518         fi
15519
15520         flags=${entry[10]}
15521         if [[ "${flags}" != "w" ]]; then
15522                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15523         fi
15524
15525         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15526         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c || error "cannot read '${file}'"
15527         sleep 5
15528         do_facet ost1 killall -TERM ofd_access_log_reader
15529         wait
15530         rc=$?
15531
15532         if ((rc != 0)); then
15533                 error "ofd_access_log_reader exited with rc = '${rc}'"
15534         fi
15535
15536         oalr_expect_event_count alr_log_entry "${trace}" 1
15537
15538         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15539         echo "entry = '${entry[*]}'" >&2
15540
15541         pfid2=${entry[4]}
15542         if [[ "${pfid1}" != "${pfid2}" ]]; then
15543                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15544         fi
15545
15546         size=${entry[8]}
15547         if ((size != 524288)); then
15548                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15549         fi
15550
15551         flags=${entry[10]}
15552         if [[ "${flags}" != "r" ]]; then
15553                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15554         fi
15555 }
15556 run_test 165b "ofd access log entries are produced and consumed"
15557
15558 test_165c() {
15559         local file="${DIR}/${tdir}/${tfile}"
15560         test_mkdir "${DIR}/${tdir}"
15561
15562         setup_165
15563
15564         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15565
15566         # 4096 / 64 = 64. Create twice as many entries.
15567         for ((i = 0; i < 128; i++)); do
15568                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c || error "cannot create file"
15569         done
15570
15571         sync
15572         do_facet ost1 ofd_access_log_reader --list
15573         unlinkmany  "${file}-%d" 128
15574 }
15575 run_test 165c "full ofd access logs do not block IOs"
15576
15577 oal_peek_entry_count() {
15578         do_facet ost1 ofd_access_log_reader --list | awk '$1 == "_entry_count:" { print $2; }'
15579 }
15580
15581 oal_expect_entry_count() {
15582         local entry_count=$(oal_peek_entry_count)
15583         local expect="$1"
15584
15585         if ((entry_count == expect)); then
15586                 return 0
15587         fi
15588
15589         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15590         do_facet ost1 ofd_access_log_reader --list >&2
15591         exit 1
15592 }
15593
15594 test_165d() {
15595         local trace="/tmp/${tfile}.trace"
15596         local file="${DIR}/${tdir}/${tfile}"
15597         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15598         local entry_count
15599         test_mkdir "${DIR}/${tdir}"
15600
15601         setup_165
15602         lfs setstripe -c 1 -i 0 "${file}"
15603
15604         do_facet ost1 lctl set_param "${param}=rw"
15605         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15606         oal_expect_entry_count 1
15607
15608         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15609         oal_expect_entry_count 2
15610
15611         do_facet ost1 lctl set_param "${param}=r"
15612         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15613         oal_expect_entry_count 2
15614
15615         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15616         oal_expect_entry_count 3
15617
15618         do_facet ost1 lctl set_param "${param}=w"
15619         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15620         oal_expect_entry_count 4
15621
15622         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15623         oal_expect_entry_count 4
15624
15625         do_facet ost1 lctl set_param "${param}=0"
15626         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15627         oal_expect_entry_count 4
15628
15629         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15630         oal_expect_entry_count 4
15631 }
15632 run_test 165d "ofd_access_log mask works"
15633
15634 test_169() {
15635         # do directio so as not to populate the page cache
15636         log "creating a 10 Mb file"
15637         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15638         log "starting reads"
15639         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15640         log "truncating the file"
15641         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15642         log "killing dd"
15643         kill %+ || true # reads might have finished
15644         echo "wait until dd is finished"
15645         wait
15646         log "removing the temporary file"
15647         rm -rf $DIR/$tfile || error "tmp file removal failed"
15648 }
15649 run_test 169 "parallel read and truncate should not deadlock"
15650
15651 test_170() {
15652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15653
15654         $LCTL clear     # bug 18514
15655         $LCTL debug_daemon start $TMP/${tfile}_log_good
15656         touch $DIR/$tfile
15657         $LCTL debug_daemon stop
15658         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15659                 error "sed failed to read log_good"
15660
15661         $LCTL debug_daemon start $TMP/${tfile}_log_good
15662         rm -rf $DIR/$tfile
15663         $LCTL debug_daemon stop
15664
15665         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15666                error "lctl df log_bad failed"
15667
15668         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15669         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15670
15671         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15672         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15673
15674         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15675                 error "bad_line good_line1 good_line2 are empty"
15676
15677         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15678         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15679         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15680
15681         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15682         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15683         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15684
15685         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15686                 error "bad_line_new good_line_new are empty"
15687
15688         local expected_good=$((good_line1 + good_line2*2))
15689
15690         rm -f $TMP/${tfile}*
15691         # LU-231, short malformed line may not be counted into bad lines
15692         if [ $bad_line -ne $bad_line_new ] &&
15693                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15694                 error "expected $bad_line bad lines, but got $bad_line_new"
15695                 return 1
15696         fi
15697
15698         if [ $expected_good -ne $good_line_new ]; then
15699                 error "expected $expected_good good lines, but got $good_line_new"
15700                 return 2
15701         fi
15702         true
15703 }
15704 run_test 170 "test lctl df to handle corrupted log ====================="
15705
15706 test_171() { # bug20592
15707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15708
15709         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15710         $LCTL set_param fail_loc=0x50e
15711         $LCTL set_param fail_val=3000
15712         multiop_bg_pause $DIR/$tfile O_s || true
15713         local MULTIPID=$!
15714         kill -USR1 $MULTIPID
15715         # cause log dump
15716         sleep 3
15717         wait $MULTIPID
15718         if dmesg | grep "recursive fault"; then
15719                 error "caught a recursive fault"
15720         fi
15721         $LCTL set_param fail_loc=0
15722         true
15723 }
15724 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15725
15726 # it would be good to share it with obdfilter-survey/iokit-libecho code
15727 setup_obdecho_osc () {
15728         local rc=0
15729         local ost_nid=$1
15730         local obdfilter_name=$2
15731         echo "Creating new osc for $obdfilter_name on $ost_nid"
15732         # make sure we can find loopback nid
15733         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15734
15735         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15736                            ${obdfilter_name}_osc_UUID || rc=2; }
15737         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15738                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15739         return $rc
15740 }
15741
15742 cleanup_obdecho_osc () {
15743         local obdfilter_name=$1
15744         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15745         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15746         return 0
15747 }
15748
15749 obdecho_test() {
15750         local OBD=$1
15751         local node=$2
15752         local pages=${3:-64}
15753         local rc=0
15754         local id
15755
15756         local count=10
15757         local obd_size=$(get_obd_size $node $OBD)
15758         local page_size=$(get_page_size $node)
15759         if [[ -n "$obd_size" ]]; then
15760                 local new_count=$((obd_size / (pages * page_size / 1024)))
15761                 [[ $new_count -ge $count ]] || count=$new_count
15762         fi
15763
15764         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15765         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15766                            rc=2; }
15767         if [ $rc -eq 0 ]; then
15768             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15769             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15770         fi
15771         echo "New object id is $id"
15772         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15773                            rc=4; }
15774         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15775                            "test_brw $count w v $pages $id" || rc=4; }
15776         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15777                            rc=4; }
15778         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15779                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15780         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15781                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15782         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15783         return $rc
15784 }
15785
15786 test_180a() {
15787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15788
15789         if ! [ -d /sys/fs/lustre/echo_client ] &&
15790            ! module_loaded obdecho; then
15791                 load_module obdecho/obdecho &&
15792                         stack_trap "rmmod obdecho" EXIT ||
15793                         error "unable to load obdecho on client"
15794         fi
15795
15796         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15797         local host=$($LCTL get_param -n osc.$osc.import |
15798                      awk '/current_connection:/ { print $2 }' )
15799         local target=$($LCTL get_param -n osc.$osc.import |
15800                        awk '/target:/ { print $2 }' )
15801         target=${target%_UUID}
15802
15803         if [ -n "$target" ]; then
15804                 setup_obdecho_osc $host $target &&
15805                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15806                         { error "obdecho setup failed with $?"; return; }
15807
15808                 obdecho_test ${target}_osc client ||
15809                         error "obdecho_test failed on ${target}_osc"
15810         else
15811                 $LCTL get_param osc.$osc.import
15812                 error "there is no osc.$osc.import target"
15813         fi
15814 }
15815 run_test 180a "test obdecho on osc"
15816
15817 test_180b() {
15818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15819         remote_ost_nodsh && skip "remote OST with nodsh"
15820
15821         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15822                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15823                 error "failed to load module obdecho"
15824
15825         local target=$(do_facet ost1 $LCTL dl |
15826                        awk '/obdfilter/ { print $4; exit; }')
15827
15828         if [ -n "$target" ]; then
15829                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15830         else
15831                 do_facet ost1 $LCTL dl
15832                 error "there is no obdfilter target on ost1"
15833         fi
15834 }
15835 run_test 180b "test obdecho directly on obdfilter"
15836
15837 test_180c() { # LU-2598
15838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15839         remote_ost_nodsh && skip "remote OST with nodsh"
15840         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15841                 skip "Need MDS version at least 2.4.0"
15842
15843         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15844                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15845                 error "failed to load module obdecho"
15846
15847         local target=$(do_facet ost1 $LCTL dl |
15848                        awk '/obdfilter/ { print $4; exit; }')
15849
15850         if [ -n "$target" ]; then
15851                 local pages=16384 # 64MB bulk I/O RPC size
15852
15853                 obdecho_test "$target" ost1 "$pages" ||
15854                         error "obdecho_test with pages=$pages failed with $?"
15855         else
15856                 do_facet ost1 $LCTL dl
15857                 error "there is no obdfilter target on ost1"
15858         fi
15859 }
15860 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15861
15862 test_181() { # bug 22177
15863         test_mkdir $DIR/$tdir
15864         # create enough files to index the directory
15865         createmany -o $DIR/$tdir/foobar 4000
15866         # print attributes for debug purpose
15867         lsattr -d .
15868         # open dir
15869         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15870         MULTIPID=$!
15871         # remove the files & current working dir
15872         unlinkmany $DIR/$tdir/foobar 4000
15873         rmdir $DIR/$tdir
15874         kill -USR1 $MULTIPID
15875         wait $MULTIPID
15876         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15877         return 0
15878 }
15879 run_test 181 "Test open-unlinked dir ========================"
15880
15881 test_182() {
15882         local fcount=1000
15883         local tcount=10
15884
15885         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15886
15887         $LCTL set_param mdc.*.rpc_stats=clear
15888
15889         for (( i = 0; i < $tcount; i++ )) ; do
15890                 mkdir $DIR/$tdir/$i
15891         done
15892
15893         for (( i = 0; i < $tcount; i++ )) ; do
15894                 createmany -o $DIR/$tdir/$i/f- $fcount &
15895         done
15896         wait
15897
15898         for (( i = 0; i < $tcount; i++ )) ; do
15899                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15900         done
15901         wait
15902
15903         $LCTL get_param mdc.*.rpc_stats
15904
15905         rm -rf $DIR/$tdir
15906 }
15907 run_test 182 "Test parallel modify metadata operations ================"
15908
15909 test_183() { # LU-2275
15910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15911         remote_mds_nodsh && skip "remote MDS with nodsh"
15912         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15913                 skip "Need MDS version at least 2.3.56"
15914
15915         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15916         echo aaa > $DIR/$tdir/$tfile
15917
15918 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
15919         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
15920
15921         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
15922         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
15923
15924         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15925
15926         # Flush negative dentry cache
15927         touch $DIR/$tdir/$tfile
15928
15929         # We are not checking for any leaked references here, they'll
15930         # become evident next time we do cleanup with module unload.
15931         rm -rf $DIR/$tdir
15932 }
15933 run_test 183 "No crash or request leak in case of strange dispositions ========"
15934
15935 # test suite 184 is for LU-2016, LU-2017
15936 test_184a() {
15937         check_swap_layouts_support
15938
15939         dir0=$DIR/$tdir/$testnum
15940         test_mkdir -p -c1 $dir0
15941         ref1=/etc/passwd
15942         ref2=/etc/group
15943         file1=$dir0/f1
15944         file2=$dir0/f2
15945         $LFS setstripe -c1 $file1
15946         cp $ref1 $file1
15947         $LFS setstripe -c2 $file2
15948         cp $ref2 $file2
15949         gen1=$($LFS getstripe -g $file1)
15950         gen2=$($LFS getstripe -g $file2)
15951
15952         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
15953         gen=$($LFS getstripe -g $file1)
15954         [[ $gen1 != $gen ]] ||
15955                 "Layout generation on $file1 does not change"
15956         gen=$($LFS getstripe -g $file2)
15957         [[ $gen2 != $gen ]] ||
15958                 "Layout generation on $file2 does not change"
15959
15960         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
15961         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15962
15963         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
15964 }
15965 run_test 184a "Basic layout swap"
15966
15967 test_184b() {
15968         check_swap_layouts_support
15969
15970         dir0=$DIR/$tdir/$testnum
15971         mkdir -p $dir0 || error "creating dir $dir0"
15972         file1=$dir0/f1
15973         file2=$dir0/f2
15974         file3=$dir0/f3
15975         dir1=$dir0/d1
15976         dir2=$dir0/d2
15977         mkdir $dir1 $dir2
15978         $LFS setstripe -c1 $file1
15979         $LFS setstripe -c2 $file2
15980         $LFS setstripe -c1 $file3
15981         chown $RUNAS_ID $file3
15982         gen1=$($LFS getstripe -g $file1)
15983         gen2=$($LFS getstripe -g $file2)
15984
15985         $LFS swap_layouts $dir1 $dir2 &&
15986                 error "swap of directories layouts should fail"
15987         $LFS swap_layouts $dir1 $file1 &&
15988                 error "swap of directory and file layouts should fail"
15989         $RUNAS $LFS swap_layouts $file1 $file2 &&
15990                 error "swap of file we cannot write should fail"
15991         $LFS swap_layouts $file1 $file3 &&
15992                 error "swap of file with different owner should fail"
15993         /bin/true # to clear error code
15994 }
15995 run_test 184b "Forbidden layout swap (will generate errors)"
15996
15997 test_184c() {
15998         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
15999         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16000         check_swap_layouts_support
16001         check_swap_layout_no_dom $DIR
16002
16003         local dir0=$DIR/$tdir/$testnum
16004         mkdir -p $dir0 || error "creating dir $dir0"
16005
16006         local ref1=$dir0/ref1
16007         local ref2=$dir0/ref2
16008         local file1=$dir0/file1
16009         local file2=$dir0/file2
16010         # create a file large enough for the concurrent test
16011         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16012         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16013         echo "ref file size: ref1($(stat -c %s $ref1))," \
16014              "ref2($(stat -c %s $ref2))"
16015
16016         cp $ref2 $file2
16017         dd if=$ref1 of=$file1 bs=16k &
16018         local DD_PID=$!
16019
16020         # Make sure dd starts to copy file
16021         while [ ! -f $file1 ]; do sleep 0.1; done
16022
16023         $LFS swap_layouts $file1 $file2
16024         local rc=$?
16025         wait $DD_PID
16026         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16027         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16028
16029         # how many bytes copied before swapping layout
16030         local copied=$(stat -c %s $file2)
16031         local remaining=$(stat -c %s $ref1)
16032         remaining=$((remaining - copied))
16033         echo "Copied $copied bytes before swapping layout..."
16034
16035         cmp -n $copied $file1 $ref2 | grep differ &&
16036                 error "Content mismatch [0, $copied) of ref2 and file1"
16037         cmp -n $copied $file2 $ref1 ||
16038                 error "Content mismatch [0, $copied) of ref1 and file2"
16039         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16040                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16041
16042         # clean up
16043         rm -f $ref1 $ref2 $file1 $file2
16044 }
16045 run_test 184c "Concurrent write and layout swap"
16046
16047 test_184d() {
16048         check_swap_layouts_support
16049         check_swap_layout_no_dom $DIR
16050         [ -z "$(which getfattr 2>/dev/null)" ] &&
16051                 skip_env "no getfattr command"
16052
16053         local file1=$DIR/$tdir/$tfile-1
16054         local file2=$DIR/$tdir/$tfile-2
16055         local file3=$DIR/$tdir/$tfile-3
16056         local lovea1
16057         local lovea2
16058
16059         mkdir -p $DIR/$tdir
16060         touch $file1 || error "create $file1 failed"
16061         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16062                 error "create $file2 failed"
16063         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16064                 error "create $file3 failed"
16065         lovea1=$(get_layout_param $file1)
16066
16067         $LFS swap_layouts $file2 $file3 ||
16068                 error "swap $file2 $file3 layouts failed"
16069         $LFS swap_layouts $file1 $file2 ||
16070                 error "swap $file1 $file2 layouts failed"
16071
16072         lovea2=$(get_layout_param $file2)
16073         echo "$lovea1"
16074         echo "$lovea2"
16075         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16076
16077         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16078         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16079 }
16080 run_test 184d "allow stripeless layouts swap"
16081
16082 test_184e() {
16083         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16084                 skip "Need MDS version at least 2.6.94"
16085         check_swap_layouts_support
16086         check_swap_layout_no_dom $DIR
16087         [ -z "$(which getfattr 2>/dev/null)" ] &&
16088                 skip_env "no getfattr command"
16089
16090         local file1=$DIR/$tdir/$tfile-1
16091         local file2=$DIR/$tdir/$tfile-2
16092         local file3=$DIR/$tdir/$tfile-3
16093         local lovea
16094
16095         mkdir -p $DIR/$tdir
16096         touch $file1 || error "create $file1 failed"
16097         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16098                 error "create $file2 failed"
16099         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16100                 error "create $file3 failed"
16101
16102         $LFS swap_layouts $file1 $file2 ||
16103                 error "swap $file1 $file2 layouts failed"
16104
16105         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16106         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16107
16108         echo 123 > $file1 || error "Should be able to write into $file1"
16109
16110         $LFS swap_layouts $file1 $file3 ||
16111                 error "swap $file1 $file3 layouts failed"
16112
16113         echo 123 > $file1 || error "Should be able to write into $file1"
16114
16115         rm -rf $file1 $file2 $file3
16116 }
16117 run_test 184e "Recreate layout after stripeless layout swaps"
16118
16119 test_184f() {
16120         # Create a file with name longer than sizeof(struct stat) ==
16121         # 144 to see if we can get chars from the file name to appear
16122         # in the returned striping. Note that 'f' == 0x66.
16123         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16124
16125         mkdir -p $DIR/$tdir
16126         mcreate $DIR/$tdir/$file
16127         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16128                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16129         fi
16130 }
16131 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16132
16133 test_185() { # LU-2441
16134         # LU-3553 - no volatile file support in old servers
16135         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16136                 skip "Need MDS version at least 2.3.60"
16137
16138         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16139         touch $DIR/$tdir/spoo
16140         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16141         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16142                 error "cannot create/write a volatile file"
16143         [ "$FILESET" == "" ] &&
16144         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16145                 error "FID is still valid after close"
16146
16147         multiop_bg_pause $DIR/$tdir vVw4096_c
16148         local multi_pid=$!
16149
16150         local OLD_IFS=$IFS
16151         IFS=":"
16152         local fidv=($fid)
16153         IFS=$OLD_IFS
16154         # assume that the next FID for this client is sequential, since stdout
16155         # is unfortunately eaten by multiop_bg_pause
16156         local n=$((${fidv[1]} + 1))
16157         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16158         if [ "$FILESET" == "" ]; then
16159                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16160                         error "FID is missing before close"
16161         fi
16162         kill -USR1 $multi_pid
16163         # 1 second delay, so if mtime change we will see it
16164         sleep 1
16165         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16166         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16167 }
16168 run_test 185 "Volatile file support"
16169
16170 function create_check_volatile() {
16171         local idx=$1
16172         local tgt
16173
16174         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16175         local PID=$!
16176         sleep 1
16177         local FID=$(cat /tmp/${tfile}.fid)
16178         [ "$FID" == "" ] && error "can't get FID for volatile"
16179         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16180         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16181         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16182         kill -USR1 $PID
16183         wait
16184         sleep 1
16185         cancel_lru_locks mdc # flush opencache
16186         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16187         return 0
16188 }
16189
16190 test_185a(){
16191         # LU-12516 - volatile creation via .lustre
16192         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16193                 skip "Need MDS version at least 2.3.55"
16194
16195         create_check_volatile 0
16196         [ $MDSCOUNT -lt 2 ] && return 0
16197
16198         # DNE case
16199         create_check_volatile 1
16200
16201         return 0
16202 }
16203 run_test 185a "Volatile file creation in .lustre/fid/"
16204
16205 test_187a() {
16206         remote_mds_nodsh && skip "remote MDS with nodsh"
16207         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16208                 skip "Need MDS version at least 2.3.0"
16209
16210         local dir0=$DIR/$tdir/$testnum
16211         mkdir -p $dir0 || error "creating dir $dir0"
16212
16213         local file=$dir0/file1
16214         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16215         local dv1=$($LFS data_version $file)
16216         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16217         local dv2=$($LFS data_version $file)
16218         [[ $dv1 != $dv2 ]] ||
16219                 error "data version did not change on write $dv1 == $dv2"
16220
16221         # clean up
16222         rm -f $file1
16223 }
16224 run_test 187a "Test data version change"
16225
16226 test_187b() {
16227         remote_mds_nodsh && skip "remote MDS with nodsh"
16228         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16229                 skip "Need MDS version at least 2.3.0"
16230
16231         local dir0=$DIR/$tdir/$testnum
16232         mkdir -p $dir0 || error "creating dir $dir0"
16233
16234         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16235         [[ ${DV[0]} != ${DV[1]} ]] ||
16236                 error "data version did not change on write"\
16237                       " ${DV[0]} == ${DV[1]}"
16238
16239         # clean up
16240         rm -f $file1
16241 }
16242 run_test 187b "Test data version change on volatile file"
16243
16244 test_200() {
16245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16246         remote_mgs_nodsh && skip "remote MGS with nodsh"
16247         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16248
16249         local POOL=${POOL:-cea1}
16250         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16251         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16252         # Pool OST targets
16253         local first_ost=0
16254         local last_ost=$(($OSTCOUNT - 1))
16255         local ost_step=2
16256         local ost_list=$(seq $first_ost $ost_step $last_ost)
16257         local ost_range="$first_ost $last_ost $ost_step"
16258         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16259         local file_dir=$POOL_ROOT/file_tst
16260         local subdir=$test_path/subdir
16261         local rc=0
16262
16263         while : ; do
16264                 # former test_200a test_200b
16265                 pool_add $POOL                          || { rc=$? ; break; }
16266                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16267                 # former test_200c test_200d
16268                 mkdir -p $test_path
16269                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16270                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16271                 mkdir -p $subdir
16272                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16273                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16274                                                         || { rc=$? ; break; }
16275                 # former test_200e test_200f
16276                 local files=$((OSTCOUNT*3))
16277                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16278                                                         || { rc=$? ; break; }
16279                 pool_create_files $POOL $file_dir $files "$ost_list" \
16280                                                         || { rc=$? ; break; }
16281                 # former test_200g test_200h
16282                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16283                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16284
16285                 # former test_201a test_201b test_201c
16286                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16287
16288                 local f=$test_path/$tfile
16289                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16290                 pool_remove $POOL $f                    || { rc=$? ; break; }
16291                 break
16292         done
16293
16294         destroy_test_pools
16295
16296         return $rc
16297 }
16298 run_test 200 "OST pools"
16299
16300 # usage: default_attr <count | size | offset>
16301 default_attr() {
16302         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16303 }
16304
16305 # usage: check_default_stripe_attr
16306 check_default_stripe_attr() {
16307         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16308         case $1 in
16309         --stripe-count|-c)
16310                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16311         --stripe-size|-S)
16312                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16313         --stripe-index|-i)
16314                 EXPECTED=-1;;
16315         *)
16316                 error "unknown getstripe attr '$1'"
16317         esac
16318
16319         [ $ACTUAL == $EXPECTED ] ||
16320                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16321 }
16322
16323 test_204a() {
16324         test_mkdir $DIR/$tdir
16325         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16326
16327         check_default_stripe_attr --stripe-count
16328         check_default_stripe_attr --stripe-size
16329         check_default_stripe_attr --stripe-index
16330 }
16331 run_test 204a "Print default stripe attributes"
16332
16333 test_204b() {
16334         test_mkdir $DIR/$tdir
16335         $LFS setstripe --stripe-count 1 $DIR/$tdir
16336
16337         check_default_stripe_attr --stripe-size
16338         check_default_stripe_attr --stripe-index
16339 }
16340 run_test 204b "Print default stripe size and offset"
16341
16342 test_204c() {
16343         test_mkdir $DIR/$tdir
16344         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16345
16346         check_default_stripe_attr --stripe-count
16347         check_default_stripe_attr --stripe-index
16348 }
16349 run_test 204c "Print default stripe count and offset"
16350
16351 test_204d() {
16352         test_mkdir $DIR/$tdir
16353         $LFS setstripe --stripe-index 0 $DIR/$tdir
16354
16355         check_default_stripe_attr --stripe-count
16356         check_default_stripe_attr --stripe-size
16357 }
16358 run_test 204d "Print default stripe count and size"
16359
16360 test_204e() {
16361         test_mkdir $DIR/$tdir
16362         $LFS setstripe -d $DIR/$tdir
16363
16364         check_default_stripe_attr --stripe-count --raw
16365         check_default_stripe_attr --stripe-size --raw
16366         check_default_stripe_attr --stripe-index --raw
16367 }
16368 run_test 204e "Print raw stripe attributes"
16369
16370 test_204f() {
16371         test_mkdir $DIR/$tdir
16372         $LFS setstripe --stripe-count 1 $DIR/$tdir
16373
16374         check_default_stripe_attr --stripe-size --raw
16375         check_default_stripe_attr --stripe-index --raw
16376 }
16377 run_test 204f "Print raw stripe size and offset"
16378
16379 test_204g() {
16380         test_mkdir $DIR/$tdir
16381         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16382
16383         check_default_stripe_attr --stripe-count --raw
16384         check_default_stripe_attr --stripe-index --raw
16385 }
16386 run_test 204g "Print raw stripe count and offset"
16387
16388 test_204h() {
16389         test_mkdir $DIR/$tdir
16390         $LFS setstripe --stripe-index 0 $DIR/$tdir
16391
16392         check_default_stripe_attr --stripe-count --raw
16393         check_default_stripe_attr --stripe-size --raw
16394 }
16395 run_test 204h "Print raw stripe count and size"
16396
16397 # Figure out which job scheduler is being used, if any,
16398 # or use a fake one
16399 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16400         JOBENV=SLURM_JOB_ID
16401 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16402         JOBENV=LSB_JOBID
16403 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16404         JOBENV=PBS_JOBID
16405 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16406         JOBENV=LOADL_STEP_ID
16407 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16408         JOBENV=JOB_ID
16409 else
16410         $LCTL list_param jobid_name > /dev/null 2>&1
16411         if [ $? -eq 0 ]; then
16412                 JOBENV=nodelocal
16413         else
16414                 JOBENV=FAKE_JOBID
16415         fi
16416 fi
16417 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16418
16419 verify_jobstats() {
16420         local cmd=($1)
16421         shift
16422         local facets="$@"
16423
16424 # we don't really need to clear the stats for this test to work, since each
16425 # command has a unique jobid, but it makes debugging easier if needed.
16426 #       for facet in $facets; do
16427 #               local dev=$(convert_facet2label $facet)
16428 #               # clear old jobstats
16429 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16430 #       done
16431
16432         # use a new JobID for each test, or we might see an old one
16433         [ "$JOBENV" = "FAKE_JOBID" ] &&
16434                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16435
16436         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16437
16438         [ "$JOBENV" = "nodelocal" ] && {
16439                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16440                 $LCTL set_param jobid_name=$FAKE_JOBID
16441                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16442         }
16443
16444         log "Test: ${cmd[*]}"
16445         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16446
16447         if [ $JOBENV = "FAKE_JOBID" ]; then
16448                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16449         else
16450                 ${cmd[*]}
16451         fi
16452
16453         # all files are created on OST0000
16454         for facet in $facets; do
16455                 local stats="*.$(convert_facet2label $facet).job_stats"
16456
16457                 # strip out libtool wrappers for in-tree executables
16458                 if [ $(do_facet $facet lctl get_param $stats |
16459                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16460                         do_facet $facet lctl get_param $stats
16461                         error "No jobstats for $JOBVAL found on $facet::$stats"
16462                 fi
16463         done
16464 }
16465
16466 jobstats_set() {
16467         local new_jobenv=$1
16468
16469         set_persistent_param_and_check client "jobid_var" \
16470                 "$FSNAME.sys.jobid_var" $new_jobenv
16471 }
16472
16473 test_205a() { # Job stats
16474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16475         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16476                 skip "Need MDS version with at least 2.7.1"
16477         remote_mgs_nodsh && skip "remote MGS with nodsh"
16478         remote_mds_nodsh && skip "remote MDS with nodsh"
16479         remote_ost_nodsh && skip "remote OST with nodsh"
16480         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16481                 skip "Server doesn't support jobstats"
16482         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16483
16484         local old_jobenv=$($LCTL get_param -n jobid_var)
16485         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16486
16487         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16488                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16489         else
16490                 stack_trap "do_facet mgs $PERM_CMD \
16491                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16492         fi
16493         changelog_register
16494
16495         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16496                                 mdt.*.job_cleanup_interval | head -n 1)
16497         local new_interval=5
16498         do_facet $SINGLEMDS \
16499                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16500         stack_trap "do_facet $SINGLEMDS \
16501                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16502         local start=$SECONDS
16503
16504         local cmd
16505         # mkdir
16506         cmd="mkdir $DIR/$tdir"
16507         verify_jobstats "$cmd" "$SINGLEMDS"
16508         # rmdir
16509         cmd="rmdir $DIR/$tdir"
16510         verify_jobstats "$cmd" "$SINGLEMDS"
16511         # mkdir on secondary MDT
16512         if [ $MDSCOUNT -gt 1 ]; then
16513                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16514                 verify_jobstats "$cmd" "mds2"
16515         fi
16516         # mknod
16517         cmd="mknod $DIR/$tfile c 1 3"
16518         verify_jobstats "$cmd" "$SINGLEMDS"
16519         # unlink
16520         cmd="rm -f $DIR/$tfile"
16521         verify_jobstats "$cmd" "$SINGLEMDS"
16522         # create all files on OST0000 so verify_jobstats can find OST stats
16523         # open & close
16524         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16525         verify_jobstats "$cmd" "$SINGLEMDS"
16526         # setattr
16527         cmd="touch $DIR/$tfile"
16528         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16529         # write
16530         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16531         verify_jobstats "$cmd" "ost1"
16532         # read
16533         cancel_lru_locks osc
16534         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16535         verify_jobstats "$cmd" "ost1"
16536         # truncate
16537         cmd="$TRUNCATE $DIR/$tfile 0"
16538         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16539         # rename
16540         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16541         verify_jobstats "$cmd" "$SINGLEMDS"
16542         # jobstats expiry - sleep until old stats should be expired
16543         local left=$((new_interval + 5 - (SECONDS - start)))
16544         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16545                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16546                         "0" $left
16547         cmd="mkdir $DIR/$tdir.expire"
16548         verify_jobstats "$cmd" "$SINGLEMDS"
16549         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16550             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16551
16552         # Ensure that jobid are present in changelog (if supported by MDS)
16553         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16554                 changelog_dump | tail -10
16555                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16556                 [ $jobids -eq 9 ] ||
16557                         error "Wrong changelog jobid count $jobids != 9"
16558
16559                 # LU-5862
16560                 JOBENV="disable"
16561                 jobstats_set $JOBENV
16562                 touch $DIR/$tfile
16563                 changelog_dump | grep $tfile
16564                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16565                 [ $jobids -eq 0 ] ||
16566                         error "Unexpected jobids when jobid_var=$JOBENV"
16567         fi
16568
16569         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
16570         JOBENV="JOBCOMPLEX"
16571         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16572
16573         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16574 }
16575 run_test 205a "Verify job stats"
16576
16577 # LU-13117, LU-13597
16578 test_205b() {
16579         job_stats="mdt.*.job_stats"
16580         $LCTL set_param $job_stats=clear
16581         $LCTL set_param jobid_var=USER jobid_name="%e.%u"
16582         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16583         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16584                 grep "job_id:.*foolish" &&
16585                         error "Unexpected jobid found"
16586         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16587                 grep "open:.*min.*max.*sum" ||
16588                         error "wrong job_stats format found"
16589 }
16590 run_test 205b "Verify job stats jobid and output format"
16591
16592 # LU-13733
16593 test_205c() {
16594         $LCTL set_param llite.*.stats=0
16595         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16596         $LCTL get_param llite.*.stats
16597         $LCTL get_param llite.*.stats | grep \
16598                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16599                         error "wrong client stats format found"
16600 }
16601 run_test 205c "Verify client stats format"
16602
16603 # LU-1480, LU-1773 and LU-1657
16604 test_206() {
16605         mkdir -p $DIR/$tdir
16606         $LFS setstripe -c -1 $DIR/$tdir
16607 #define OBD_FAIL_LOV_INIT 0x1403
16608         $LCTL set_param fail_loc=0xa0001403
16609         $LCTL set_param fail_val=1
16610         touch $DIR/$tdir/$tfile || true
16611 }
16612 run_test 206 "fail lov_init_raid0() doesn't lbug"
16613
16614 test_207a() {
16615         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16616         local fsz=`stat -c %s $DIR/$tfile`
16617         cancel_lru_locks mdc
16618
16619         # do not return layout in getattr intent
16620 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16621         $LCTL set_param fail_loc=0x170
16622         local sz=`stat -c %s $DIR/$tfile`
16623
16624         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16625
16626         rm -rf $DIR/$tfile
16627 }
16628 run_test 207a "can refresh layout at glimpse"
16629
16630 test_207b() {
16631         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16632         local cksum=`md5sum $DIR/$tfile`
16633         local fsz=`stat -c %s $DIR/$tfile`
16634         cancel_lru_locks mdc
16635         cancel_lru_locks osc
16636
16637         # do not return layout in getattr intent
16638 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16639         $LCTL set_param fail_loc=0x171
16640
16641         # it will refresh layout after the file is opened but before read issues
16642         echo checksum is "$cksum"
16643         echo "$cksum" |md5sum -c --quiet || error "file differs"
16644
16645         rm -rf $DIR/$tfile
16646 }
16647 run_test 207b "can refresh layout at open"
16648
16649 test_208() {
16650         # FIXME: in this test suite, only RD lease is used. This is okay
16651         # for now as only exclusive open is supported. After generic lease
16652         # is done, this test suite should be revised. - Jinshan
16653
16654         remote_mds_nodsh && skip "remote MDS with nodsh"
16655         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16656                 skip "Need MDS version at least 2.4.52"
16657
16658         echo "==== test 1: verify get lease work"
16659         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16660
16661         echo "==== test 2: verify lease can be broken by upcoming open"
16662         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16663         local PID=$!
16664         sleep 1
16665
16666         $MULTIOP $DIR/$tfile oO_RDONLY:c
16667         kill -USR1 $PID && wait $PID || error "break lease error"
16668
16669         echo "==== test 3: verify lease can't be granted if an open already exists"
16670         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16671         local PID=$!
16672         sleep 1
16673
16674         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16675         kill -USR1 $PID && wait $PID || error "open file error"
16676
16677         echo "==== test 4: lease can sustain over recovery"
16678         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16679         PID=$!
16680         sleep 1
16681
16682         fail mds1
16683
16684         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16685
16686         echo "==== test 5: lease broken can't be regained by replay"
16687         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16688         PID=$!
16689         sleep 1
16690
16691         # open file to break lease and then recovery
16692         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16693         fail mds1
16694
16695         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16696
16697         rm -f $DIR/$tfile
16698 }
16699 run_test 208 "Exclusive open"
16700
16701 test_209() {
16702         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16703                 skip_env "must have disp_stripe"
16704
16705         touch $DIR/$tfile
16706         sync; sleep 5; sync;
16707
16708         echo 3 > /proc/sys/vm/drop_caches
16709         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16710                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16711         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16712
16713         # open/close 500 times
16714         for i in $(seq 500); do
16715                 cat $DIR/$tfile
16716         done
16717
16718         echo 3 > /proc/sys/vm/drop_caches
16719         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16720                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16721         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16722
16723         echo "before: $req_before, after: $req_after"
16724         [ $((req_after - req_before)) -ge 300 ] &&
16725                 error "open/close requests are not freed"
16726         return 0
16727 }
16728 run_test 209 "read-only open/close requests should be freed promptly"
16729
16730 test_210() {
16731         local pid
16732
16733         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16734         pid=$!
16735         sleep 1
16736
16737         $LFS getstripe $DIR/$tfile
16738         kill -USR1 $pid
16739         wait $pid || error "multiop failed"
16740
16741         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16742         pid=$!
16743         sleep 1
16744
16745         $LFS getstripe $DIR/$tfile
16746         kill -USR1 $pid
16747         wait $pid || error "multiop failed"
16748 }
16749 run_test 210 "lfs getstripe does not break leases"
16750
16751 test_212() {
16752         size=`date +%s`
16753         size=$((size % 8192 + 1))
16754         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16755         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16756         rm -f $DIR/f212 $DIR/f212.xyz
16757 }
16758 run_test 212 "Sendfile test ============================================"
16759
16760 test_213() {
16761         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16762         cancel_lru_locks osc
16763         lctl set_param fail_loc=0x8000040f
16764         # generate a read lock
16765         cat $DIR/$tfile > /dev/null
16766         # write to the file, it will try to cancel the above read lock.
16767         cat /etc/hosts >> $DIR/$tfile
16768 }
16769 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16770
16771 test_214() { # for bug 20133
16772         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16773         for (( i=0; i < 340; i++ )) ; do
16774                 touch $DIR/$tdir/d214c/a$i
16775         done
16776
16777         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16778         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16779         ls $DIR/d214c || error "ls $DIR/d214c failed"
16780         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16781         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16782 }
16783 run_test 214 "hash-indexed directory test - bug 20133"
16784
16785 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16786 create_lnet_proc_files() {
16787         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16788 }
16789
16790 # counterpart of create_lnet_proc_files
16791 remove_lnet_proc_files() {
16792         rm -f $TMP/lnet_$1.sys
16793 }
16794
16795 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16796 # 3rd arg as regexp for body
16797 check_lnet_proc_stats() {
16798         local l=$(cat "$TMP/lnet_$1" |wc -l)
16799         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16800
16801         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16802 }
16803
16804 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16805 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16806 # optional and can be regexp for 2nd line (lnet.routes case)
16807 check_lnet_proc_entry() {
16808         local blp=2          # blp stands for 'position of 1st line of body'
16809         [ -z "$5" ] || blp=3 # lnet.routes case
16810
16811         local l=$(cat "$TMP/lnet_$1" |wc -l)
16812         # subtracting one from $blp because the body can be empty
16813         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16814
16815         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16816                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16817
16818         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16819                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16820
16821         # bail out if any unexpected line happened
16822         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16823         [ "$?" != 0 ] || error "$2 misformatted"
16824 }
16825
16826 test_215() { # for bugs 18102, 21079, 21517
16827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16828
16829         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16830         local P='[1-9][0-9]*'           # positive numeric
16831         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16832         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16833         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16834         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16835
16836         local L1 # regexp for 1st line
16837         local L2 # regexp for 2nd line (optional)
16838         local BR # regexp for the rest (body)
16839
16840         # lnet.stats should look as 11 space-separated non-negative numerics
16841         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16842         create_lnet_proc_files "stats"
16843         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16844         remove_lnet_proc_files "stats"
16845
16846         # lnet.routes should look like this:
16847         # Routing disabled/enabled
16848         # net hops priority state router
16849         # where net is a string like tcp0, hops > 0, priority >= 0,
16850         # state is up/down,
16851         # router is a string like 192.168.1.1@tcp2
16852         L1="^Routing (disabled|enabled)$"
16853         L2="^net +hops +priority +state +router$"
16854         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16855         create_lnet_proc_files "routes"
16856         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16857         remove_lnet_proc_files "routes"
16858
16859         # lnet.routers should look like this:
16860         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16861         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16862         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16863         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16864         L1="^ref +rtr_ref +alive +router$"
16865         BR="^$P +$P +(up|down) +$NID$"
16866         create_lnet_proc_files "routers"
16867         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16868         remove_lnet_proc_files "routers"
16869
16870         # lnet.peers should look like this:
16871         # nid refs state last max rtr min tx min queue
16872         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16873         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16874         # numeric (0 or >0 or <0), queue >= 0.
16875         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16876         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16877         create_lnet_proc_files "peers"
16878         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16879         remove_lnet_proc_files "peers"
16880
16881         # lnet.buffers  should look like this:
16882         # pages count credits min
16883         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16884         L1="^pages +count +credits +min$"
16885         BR="^ +$N +$N +$I +$I$"
16886         create_lnet_proc_files "buffers"
16887         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16888         remove_lnet_proc_files "buffers"
16889
16890         # lnet.nis should look like this:
16891         # nid status alive refs peer rtr max tx min
16892         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16893         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16894         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16895         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16896         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16897         create_lnet_proc_files "nis"
16898         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16899         remove_lnet_proc_files "nis"
16900
16901         # can we successfully write to lnet.stats?
16902         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
16903 }
16904 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
16905
16906 test_216() { # bug 20317
16907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16908         remote_ost_nodsh && skip "remote OST with nodsh"
16909
16910         local node
16911         local facets=$(get_facets OST)
16912         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16913
16914         save_lustre_params client "osc.*.contention_seconds" > $p
16915         save_lustre_params $facets \
16916                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
16917         save_lustre_params $facets \
16918                 "ldlm.namespaces.filter-*.contended_locks" >> $p
16919         save_lustre_params $facets \
16920                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
16921         clear_stats osc.*.osc_stats
16922
16923         # agressive lockless i/o settings
16924         do_nodes $(comma_list $(osts_nodes)) \
16925                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
16926                         ldlm.namespaces.filter-*.contended_locks=0 \
16927                         ldlm.namespaces.filter-*.contention_seconds=60"
16928         lctl set_param -n osc.*.contention_seconds=60
16929
16930         $DIRECTIO write $DIR/$tfile 0 10 4096
16931         $CHECKSTAT -s 40960 $DIR/$tfile
16932
16933         # disable lockless i/o
16934         do_nodes $(comma_list $(osts_nodes)) \
16935                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
16936                         ldlm.namespaces.filter-*.contended_locks=32 \
16937                         ldlm.namespaces.filter-*.contention_seconds=0"
16938         lctl set_param -n osc.*.contention_seconds=0
16939         clear_stats osc.*.osc_stats
16940
16941         dd if=/dev/zero of=$DIR/$tfile count=0
16942         $CHECKSTAT -s 0 $DIR/$tfile
16943
16944         restore_lustre_params <$p
16945         rm -f $p
16946         rm $DIR/$tfile
16947 }
16948 run_test 216 "check lockless direct write updates file size and kms correctly"
16949
16950 test_217() { # bug 22430
16951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16952
16953         local node
16954         local nid
16955
16956         for node in $(nodes_list); do
16957                 nid=$(host_nids_address $node $NETTYPE)
16958                 if [[ $nid = *-* ]] ; then
16959                         echo "lctl ping $(h2nettype $nid)"
16960                         lctl ping $(h2nettype $nid)
16961                 else
16962                         echo "skipping $node (no hyphen detected)"
16963                 fi
16964         done
16965 }
16966 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
16967
16968 test_218() {
16969        # do directio so as not to populate the page cache
16970        log "creating a 10 Mb file"
16971        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
16972        log "starting reads"
16973        dd if=$DIR/$tfile of=/dev/null bs=4096 &
16974        log "truncating the file"
16975        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
16976        log "killing dd"
16977        kill %+ || true # reads might have finished
16978        echo "wait until dd is finished"
16979        wait
16980        log "removing the temporary file"
16981        rm -rf $DIR/$tfile || error "tmp file removal failed"
16982 }
16983 run_test 218 "parallel read and truncate should not deadlock"
16984
16985 test_219() {
16986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16987
16988         # write one partial page
16989         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
16990         # set no grant so vvp_io_commit_write will do sync write
16991         $LCTL set_param fail_loc=0x411
16992         # write a full page at the end of file
16993         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
16994
16995         $LCTL set_param fail_loc=0
16996         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
16997         $LCTL set_param fail_loc=0x411
16998         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
16999
17000         # LU-4201
17001         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17002         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17003 }
17004 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17005
17006 test_220() { #LU-325
17007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17008         remote_ost_nodsh && skip "remote OST with nodsh"
17009         remote_mds_nodsh && skip "remote MDS with nodsh"
17010         remote_mgs_nodsh && skip "remote MGS with nodsh"
17011
17012         local OSTIDX=0
17013
17014         # create on MDT0000 so the last_id and next_id are correct
17015         mkdir $DIR/$tdir
17016         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17017         OST=${OST%_UUID}
17018
17019         # on the mdt's osc
17020         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17021         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17022                         osp.$mdtosc_proc1.prealloc_last_id)
17023         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17024                         osp.$mdtosc_proc1.prealloc_next_id)
17025
17026         $LFS df -i
17027
17028         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17029         #define OBD_FAIL_OST_ENOINO              0x229
17030         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17031         create_pool $FSNAME.$TESTNAME || return 1
17032         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17033
17034         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17035
17036         MDSOBJS=$((last_id - next_id))
17037         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17038
17039         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17040         echo "OST still has $count kbytes free"
17041
17042         echo "create $MDSOBJS files @next_id..."
17043         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17044
17045         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17046                         osp.$mdtosc_proc1.prealloc_last_id)
17047         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17048                         osp.$mdtosc_proc1.prealloc_next_id)
17049
17050         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17051         $LFS df -i
17052
17053         echo "cleanup..."
17054
17055         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17056         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17057
17058         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17059                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17060         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17061                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17062         echo "unlink $MDSOBJS files @$next_id..."
17063         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17064 }
17065 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17066
17067 test_221() {
17068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17069
17070         dd if=`which date` of=$MOUNT/date oflag=sync
17071         chmod +x $MOUNT/date
17072
17073         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17074         $LCTL set_param fail_loc=0x80001401
17075
17076         $MOUNT/date > /dev/null
17077         rm -f $MOUNT/date
17078 }
17079 run_test 221 "make sure fault and truncate race to not cause OOM"
17080
17081 test_222a () {
17082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17083
17084         rm -rf $DIR/$tdir
17085         test_mkdir $DIR/$tdir
17086         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17087         createmany -o $DIR/$tdir/$tfile 10
17088         cancel_lru_locks mdc
17089         cancel_lru_locks osc
17090         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17091         $LCTL set_param fail_loc=0x31a
17092         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17093         $LCTL set_param fail_loc=0
17094         rm -r $DIR/$tdir
17095 }
17096 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17097
17098 test_222b () {
17099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17100
17101         rm -rf $DIR/$tdir
17102         test_mkdir $DIR/$tdir
17103         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17104         createmany -o $DIR/$tdir/$tfile 10
17105         cancel_lru_locks mdc
17106         cancel_lru_locks osc
17107         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17108         $LCTL set_param fail_loc=0x31a
17109         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17110         $LCTL set_param fail_loc=0
17111 }
17112 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17113
17114 test_223 () {
17115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17116
17117         rm -rf $DIR/$tdir
17118         test_mkdir $DIR/$tdir
17119         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17120         createmany -o $DIR/$tdir/$tfile 10
17121         cancel_lru_locks mdc
17122         cancel_lru_locks osc
17123         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17124         $LCTL set_param fail_loc=0x31b
17125         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17126         $LCTL set_param fail_loc=0
17127         rm -r $DIR/$tdir
17128 }
17129 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17130
17131 test_224a() { # LU-1039, MRP-303
17132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17133
17134         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17135         $LCTL set_param fail_loc=0x508
17136         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17137         $LCTL set_param fail_loc=0
17138         df $DIR
17139 }
17140 run_test 224a "Don't panic on bulk IO failure"
17141
17142 test_224b() { # LU-1039, MRP-303
17143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17144
17145         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17146         cancel_lru_locks osc
17147         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17148         $LCTL set_param fail_loc=0x515
17149         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17150         $LCTL set_param fail_loc=0
17151         df $DIR
17152 }
17153 run_test 224b "Don't panic on bulk IO failure"
17154
17155 test_224c() { # LU-6441
17156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17157         remote_mds_nodsh && skip "remote MDS with nodsh"
17158
17159         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17160         save_writethrough $p
17161         set_cache writethrough on
17162
17163         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17164         local at_max=$($LCTL get_param -n at_max)
17165         local timeout=$($LCTL get_param -n timeout)
17166         local test_at="at_max"
17167         local param_at="$FSNAME.sys.at_max"
17168         local test_timeout="timeout"
17169         local param_timeout="$FSNAME.sys.timeout"
17170
17171         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17172
17173         set_persistent_param_and_check client "$test_at" "$param_at" 0
17174         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17175
17176         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17177         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17178         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17179         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17180         sync
17181         do_facet ost1 "$LCTL set_param fail_loc=0"
17182
17183         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17184         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17185                 $timeout
17186
17187         $LCTL set_param -n $pages_per_rpc
17188         restore_lustre_params < $p
17189         rm -f $p
17190 }
17191 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17192
17193 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17194 test_225a () {
17195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17196         if [ -z ${MDSSURVEY} ]; then
17197                 skip_env "mds-survey not found"
17198         fi
17199         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17200                 skip "Need MDS version at least 2.2.51"
17201
17202         local mds=$(facet_host $SINGLEMDS)
17203         local target=$(do_nodes $mds 'lctl dl' |
17204                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17205
17206         local cmd1="file_count=1000 thrhi=4"
17207         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17208         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17209         local cmd="$cmd1 $cmd2 $cmd3"
17210
17211         rm -f ${TMP}/mds_survey*
17212         echo + $cmd
17213         eval $cmd || error "mds-survey with zero-stripe failed"
17214         cat ${TMP}/mds_survey*
17215         rm -f ${TMP}/mds_survey*
17216 }
17217 run_test 225a "Metadata survey sanity with zero-stripe"
17218
17219 test_225b () {
17220         if [ -z ${MDSSURVEY} ]; then
17221                 skip_env "mds-survey not found"
17222         fi
17223         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17224                 skip "Need MDS version at least 2.2.51"
17225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17226         remote_mds_nodsh && skip "remote MDS with nodsh"
17227         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17228                 skip_env "Need to mount OST to test"
17229         fi
17230
17231         local mds=$(facet_host $SINGLEMDS)
17232         local target=$(do_nodes $mds 'lctl dl' |
17233                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17234
17235         local cmd1="file_count=1000 thrhi=4"
17236         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17237         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17238         local cmd="$cmd1 $cmd2 $cmd3"
17239
17240         rm -f ${TMP}/mds_survey*
17241         echo + $cmd
17242         eval $cmd || error "mds-survey with stripe_count failed"
17243         cat ${TMP}/mds_survey*
17244         rm -f ${TMP}/mds_survey*
17245 }
17246 run_test 225b "Metadata survey sanity with stripe_count = 1"
17247
17248 mcreate_path2fid () {
17249         local mode=$1
17250         local major=$2
17251         local minor=$3
17252         local name=$4
17253         local desc=$5
17254         local path=$DIR/$tdir/$name
17255         local fid
17256         local rc
17257         local fid_path
17258
17259         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17260                 error "cannot create $desc"
17261
17262         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17263         rc=$?
17264         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17265
17266         fid_path=$($LFS fid2path $MOUNT $fid)
17267         rc=$?
17268         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17269
17270         [ "$path" == "$fid_path" ] ||
17271                 error "fid2path returned $fid_path, expected $path"
17272
17273         echo "pass with $path and $fid"
17274 }
17275
17276 test_226a () {
17277         rm -rf $DIR/$tdir
17278         mkdir -p $DIR/$tdir
17279
17280         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17281         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17282         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17283         mcreate_path2fid 0040666 0 0 dir "directory"
17284         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17285         mcreate_path2fid 0100666 0 0 file "regular file"
17286         mcreate_path2fid 0120666 0 0 link "symbolic link"
17287         mcreate_path2fid 0140666 0 0 sock "socket"
17288 }
17289 run_test 226a "call path2fid and fid2path on files of all type"
17290
17291 test_226b () {
17292         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17293
17294         local MDTIDX=1
17295
17296         rm -rf $DIR/$tdir
17297         mkdir -p $DIR/$tdir
17298         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17299                 error "create remote directory failed"
17300         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17301         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17302                                 "character special file (null)"
17303         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17304                                 "character special file (no device)"
17305         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17306         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17307                                 "block special file (loop)"
17308         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17309         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17310         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17311 }
17312 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17313
17314 test_226c () {
17315         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17316         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17317                 skip "Need MDS version at least 2.13.55"
17318
17319         local submnt=/mnt/submnt
17320         local srcfile=/etc/passwd
17321         local dstfile=$submnt/passwd
17322         local path
17323         local fid
17324
17325         rm -rf $DIR/$tdir
17326         rm -rf $submnt
17327         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17328                 error "create remote directory failed"
17329         mkdir -p $submnt || error "create $submnt failed"
17330         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17331                 error "mount $submnt failed"
17332         stack_trap "umount $submnt" EXIT
17333
17334         cp $srcfile $dstfile
17335         fid=$($LFS path2fid $dstfile)
17336         path=$($LFS fid2path $submnt "$fid")
17337         [ "$path" = "$dstfile" ] ||
17338                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17339 }
17340 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17341
17342 # LU-1299 Executing or running ldd on a truncated executable does not
17343 # cause an out-of-memory condition.
17344 test_227() {
17345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17346         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17347
17348         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17349         chmod +x $MOUNT/date
17350
17351         $MOUNT/date > /dev/null
17352         ldd $MOUNT/date > /dev/null
17353         rm -f $MOUNT/date
17354 }
17355 run_test 227 "running truncated executable does not cause OOM"
17356
17357 # LU-1512 try to reuse idle OI blocks
17358 test_228a() {
17359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17360         remote_mds_nodsh && skip "remote MDS with nodsh"
17361         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17362
17363         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17364         local myDIR=$DIR/$tdir
17365
17366         mkdir -p $myDIR
17367         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17368         $LCTL set_param fail_loc=0x80001002
17369         createmany -o $myDIR/t- 10000
17370         $LCTL set_param fail_loc=0
17371         # The guard is current the largest FID holder
17372         touch $myDIR/guard
17373         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17374                     tr -d '[')
17375         local IDX=$(($SEQ % 64))
17376
17377         do_facet $SINGLEMDS sync
17378         # Make sure journal flushed.
17379         sleep 6
17380         local blk1=$(do_facet $SINGLEMDS \
17381                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17382                      grep Blockcount | awk '{print $4}')
17383
17384         # Remove old files, some OI blocks will become idle.
17385         unlinkmany $myDIR/t- 10000
17386         # Create new files, idle OI blocks should be reused.
17387         createmany -o $myDIR/t- 2000
17388         do_facet $SINGLEMDS sync
17389         # Make sure journal flushed.
17390         sleep 6
17391         local blk2=$(do_facet $SINGLEMDS \
17392                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17393                      grep Blockcount | awk '{print $4}')
17394
17395         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17396 }
17397 run_test 228a "try to reuse idle OI blocks"
17398
17399 test_228b() {
17400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17401         remote_mds_nodsh && skip "remote MDS with nodsh"
17402         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17403
17404         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17405         local myDIR=$DIR/$tdir
17406
17407         mkdir -p $myDIR
17408         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17409         $LCTL set_param fail_loc=0x80001002
17410         createmany -o $myDIR/t- 10000
17411         $LCTL set_param fail_loc=0
17412         # The guard is current the largest FID holder
17413         touch $myDIR/guard
17414         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17415                     tr -d '[')
17416         local IDX=$(($SEQ % 64))
17417
17418         do_facet $SINGLEMDS sync
17419         # Make sure journal flushed.
17420         sleep 6
17421         local blk1=$(do_facet $SINGLEMDS \
17422                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17423                      grep Blockcount | awk '{print $4}')
17424
17425         # Remove old files, some OI blocks will become idle.
17426         unlinkmany $myDIR/t- 10000
17427
17428         # stop the MDT
17429         stop $SINGLEMDS || error "Fail to stop MDT."
17430         # remount the MDT
17431         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17432
17433         df $MOUNT || error "Fail to df."
17434         # Create new files, idle OI blocks should be reused.
17435         createmany -o $myDIR/t- 2000
17436         do_facet $SINGLEMDS sync
17437         # Make sure journal flushed.
17438         sleep 6
17439         local blk2=$(do_facet $SINGLEMDS \
17440                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17441                      grep Blockcount | awk '{print $4}')
17442
17443         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17444 }
17445 run_test 228b "idle OI blocks can be reused after MDT restart"
17446
17447 #LU-1881
17448 test_228c() {
17449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17450         remote_mds_nodsh && skip "remote MDS with nodsh"
17451         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17452
17453         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17454         local myDIR=$DIR/$tdir
17455
17456         mkdir -p $myDIR
17457         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17458         $LCTL set_param fail_loc=0x80001002
17459         # 20000 files can guarantee there are index nodes in the OI file
17460         createmany -o $myDIR/t- 20000
17461         $LCTL set_param fail_loc=0
17462         # The guard is current the largest FID holder
17463         touch $myDIR/guard
17464         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17465                     tr -d '[')
17466         local IDX=$(($SEQ % 64))
17467
17468         do_facet $SINGLEMDS sync
17469         # Make sure journal flushed.
17470         sleep 6
17471         local blk1=$(do_facet $SINGLEMDS \
17472                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17473                      grep Blockcount | awk '{print $4}')
17474
17475         # Remove old files, some OI blocks will become idle.
17476         unlinkmany $myDIR/t- 20000
17477         rm -f $myDIR/guard
17478         # The OI file should become empty now
17479
17480         # Create new files, idle OI blocks should be reused.
17481         createmany -o $myDIR/t- 2000
17482         do_facet $SINGLEMDS sync
17483         # Make sure journal flushed.
17484         sleep 6
17485         local blk2=$(do_facet $SINGLEMDS \
17486                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17487                      grep Blockcount | awk '{print $4}')
17488
17489         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17490 }
17491 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17492
17493 test_229() { # LU-2482, LU-3448
17494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17495         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17496         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17497                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17498
17499         rm -f $DIR/$tfile
17500
17501         # Create a file with a released layout and stripe count 2.
17502         $MULTIOP $DIR/$tfile H2c ||
17503                 error "failed to create file with released layout"
17504
17505         $LFS getstripe -v $DIR/$tfile
17506
17507         local pattern=$($LFS getstripe -L $DIR/$tfile)
17508         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17509
17510         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17511                 error "getstripe"
17512         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17513         stat $DIR/$tfile || error "failed to stat released file"
17514
17515         chown $RUNAS_ID $DIR/$tfile ||
17516                 error "chown $RUNAS_ID $DIR/$tfile failed"
17517
17518         chgrp $RUNAS_ID $DIR/$tfile ||
17519                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17520
17521         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17522         rm $DIR/$tfile || error "failed to remove released file"
17523 }
17524 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17525
17526 test_230a() {
17527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17528         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17529         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17530                 skip "Need MDS version at least 2.11.52"
17531
17532         local MDTIDX=1
17533
17534         test_mkdir $DIR/$tdir
17535         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17536         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17537         [ $mdt_idx -ne 0 ] &&
17538                 error "create local directory on wrong MDT $mdt_idx"
17539
17540         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17541                         error "create remote directory failed"
17542         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17543         [ $mdt_idx -ne $MDTIDX ] &&
17544                 error "create remote directory on wrong MDT $mdt_idx"
17545
17546         createmany -o $DIR/$tdir/test_230/t- 10 ||
17547                 error "create files on remote directory failed"
17548         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17549         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17550         rm -r $DIR/$tdir || error "unlink remote directory failed"
17551 }
17552 run_test 230a "Create remote directory and files under the remote directory"
17553
17554 test_230b() {
17555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17556         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17557         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17558                 skip "Need MDS version at least 2.11.52"
17559
17560         local MDTIDX=1
17561         local mdt_index
17562         local i
17563         local file
17564         local pid
17565         local stripe_count
17566         local migrate_dir=$DIR/$tdir/migrate_dir
17567         local other_dir=$DIR/$tdir/other_dir
17568
17569         test_mkdir $DIR/$tdir
17570         test_mkdir -i0 -c1 $migrate_dir
17571         test_mkdir -i0 -c1 $other_dir
17572         for ((i=0; i<10; i++)); do
17573                 mkdir -p $migrate_dir/dir_${i}
17574                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17575                         error "create files under remote dir failed $i"
17576         done
17577
17578         cp /etc/passwd $migrate_dir/$tfile
17579         cp /etc/passwd $other_dir/$tfile
17580         chattr +SAD $migrate_dir
17581         chattr +SAD $migrate_dir/$tfile
17582
17583         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17584         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17585         local old_dir_mode=$(stat -c%f $migrate_dir)
17586         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17587
17588         mkdir -p $migrate_dir/dir_default_stripe2
17589         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17590         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17591
17592         mkdir -p $other_dir
17593         ln $migrate_dir/$tfile $other_dir/luna
17594         ln $migrate_dir/$tfile $migrate_dir/sofia
17595         ln $other_dir/$tfile $migrate_dir/david
17596         ln -s $migrate_dir/$tfile $other_dir/zachary
17597         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17598         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17599
17600         local len
17601         local lnktgt
17602
17603         # inline symlink
17604         for len in 58 59 60; do
17605                 lnktgt=$(str_repeat 'l' $len)
17606                 touch $migrate_dir/$lnktgt
17607                 ln -s $lnktgt $migrate_dir/${len}char_ln
17608         done
17609
17610         # PATH_MAX
17611         for len in 4094 4095; do
17612                 lnktgt=$(str_repeat 'l' $len)
17613                 ln -s $lnktgt $migrate_dir/${len}char_ln
17614         done
17615
17616         # NAME_MAX
17617         for len in 254 255; do
17618                 touch $migrate_dir/$(str_repeat 'l' $len)
17619         done
17620
17621         $LFS migrate -m $MDTIDX $migrate_dir ||
17622                 error "fails on migrating remote dir to MDT1"
17623
17624         echo "migratate to MDT1, then checking.."
17625         for ((i = 0; i < 10; i++)); do
17626                 for file in $(find $migrate_dir/dir_${i}); do
17627                         mdt_index=$($LFS getstripe -m $file)
17628                         # broken symlink getstripe will fail
17629                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17630                                 error "$file is not on MDT${MDTIDX}"
17631                 done
17632         done
17633
17634         # the multiple link file should still in MDT0
17635         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17636         [ $mdt_index == 0 ] ||
17637                 error "$file is not on MDT${MDTIDX}"
17638
17639         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17640         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17641                 error " expect $old_dir_flag get $new_dir_flag"
17642
17643         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17644         [ "$old_file_flag" = "$new_file_flag" ] ||
17645                 error " expect $old_file_flag get $new_file_flag"
17646
17647         local new_dir_mode=$(stat -c%f $migrate_dir)
17648         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17649                 error "expect mode $old_dir_mode get $new_dir_mode"
17650
17651         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17652         [ "$old_file_mode" = "$new_file_mode" ] ||
17653                 error "expect mode $old_file_mode get $new_file_mode"
17654
17655         diff /etc/passwd $migrate_dir/$tfile ||
17656                 error "$tfile different after migration"
17657
17658         diff /etc/passwd $other_dir/luna ||
17659                 error "luna different after migration"
17660
17661         diff /etc/passwd $migrate_dir/sofia ||
17662                 error "sofia different after migration"
17663
17664         diff /etc/passwd $migrate_dir/david ||
17665                 error "david different after migration"
17666
17667         diff /etc/passwd $other_dir/zachary ||
17668                 error "zachary different after migration"
17669
17670         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17671                 error "${tfile}_ln different after migration"
17672
17673         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17674                 error "${tfile}_ln_other different after migration"
17675
17676         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17677         [ $stripe_count = 2 ] ||
17678                 error "dir strpe_count $d != 2 after migration."
17679
17680         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17681         [ $stripe_count = 2 ] ||
17682                 error "file strpe_count $d != 2 after migration."
17683
17684         #migrate back to MDT0
17685         MDTIDX=0
17686
17687         $LFS migrate -m $MDTIDX $migrate_dir ||
17688                 error "fails on migrating remote dir to MDT0"
17689
17690         echo "migrate back to MDT0, checking.."
17691         for file in $(find $migrate_dir); do
17692                 mdt_index=$($LFS getstripe -m $file)
17693                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17694                         error "$file is not on MDT${MDTIDX}"
17695         done
17696
17697         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17698         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17699                 error " expect $old_dir_flag get $new_dir_flag"
17700
17701         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17702         [ "$old_file_flag" = "$new_file_flag" ] ||
17703                 error " expect $old_file_flag get $new_file_flag"
17704
17705         local new_dir_mode=$(stat -c%f $migrate_dir)
17706         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17707                 error "expect mode $old_dir_mode get $new_dir_mode"
17708
17709         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17710         [ "$old_file_mode" = "$new_file_mode" ] ||
17711                 error "expect mode $old_file_mode get $new_file_mode"
17712
17713         diff /etc/passwd ${migrate_dir}/$tfile ||
17714                 error "$tfile different after migration"
17715
17716         diff /etc/passwd ${other_dir}/luna ||
17717                 error "luna different after migration"
17718
17719         diff /etc/passwd ${migrate_dir}/sofia ||
17720                 error "sofia different after migration"
17721
17722         diff /etc/passwd ${other_dir}/zachary ||
17723                 error "zachary different after migration"
17724
17725         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17726                 error "${tfile}_ln different after migration"
17727
17728         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17729                 error "${tfile}_ln_other different after migration"
17730
17731         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17732         [ $stripe_count = 2 ] ||
17733                 error "dir strpe_count $d != 2 after migration."
17734
17735         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17736         [ $stripe_count = 2 ] ||
17737                 error "file strpe_count $d != 2 after migration."
17738
17739         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17740 }
17741 run_test 230b "migrate directory"
17742
17743 test_230c() {
17744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17745         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17746         remote_mds_nodsh && skip "remote MDS with nodsh"
17747         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17748                 skip "Need MDS version at least 2.11.52"
17749
17750         local MDTIDX=1
17751         local total=3
17752         local mdt_index
17753         local file
17754         local migrate_dir=$DIR/$tdir/migrate_dir
17755
17756         #If migrating directory fails in the middle, all entries of
17757         #the directory is still accessiable.
17758         test_mkdir $DIR/$tdir
17759         test_mkdir -i0 -c1 $migrate_dir
17760         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17761         stat $migrate_dir
17762         createmany -o $migrate_dir/f $total ||
17763                 error "create files under ${migrate_dir} failed"
17764
17765         # fail after migrating top dir, and this will fail only once, so the
17766         # first sub file migration will fail (currently f3), others succeed.
17767         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17768         do_facet mds1 lctl set_param fail_loc=0x1801
17769         local t=$(ls $migrate_dir | wc -l)
17770         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17771                 error "migrate should fail"
17772         local u=$(ls $migrate_dir | wc -l)
17773         [ "$u" == "$t" ] || error "$u != $t during migration"
17774
17775         # add new dir/file should succeed
17776         mkdir $migrate_dir/dir ||
17777                 error "mkdir failed under migrating directory"
17778         touch $migrate_dir/file ||
17779                 error "create file failed under migrating directory"
17780
17781         # add file with existing name should fail
17782         for file in $migrate_dir/f*; do
17783                 stat $file > /dev/null || error "stat $file failed"
17784                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17785                         error "open(O_CREAT|O_EXCL) $file should fail"
17786                 $MULTIOP $file m && error "create $file should fail"
17787                 touch $DIR/$tdir/remote_dir/$tfile ||
17788                         error "touch $tfile failed"
17789                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17790                         error "link $file should fail"
17791                 mdt_index=$($LFS getstripe -m $file)
17792                 if [ $mdt_index == 0 ]; then
17793                         # file failed to migrate is not allowed to rename to
17794                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17795                                 error "rename to $file should fail"
17796                 else
17797                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17798                                 error "rename to $file failed"
17799                 fi
17800                 echo hello >> $file || error "write $file failed"
17801         done
17802
17803         # resume migration with different options should fail
17804         $LFS migrate -m 0 $migrate_dir &&
17805                 error "migrate -m 0 $migrate_dir should fail"
17806
17807         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17808                 error "migrate -c 2 $migrate_dir should fail"
17809
17810         # resume migration should succeed
17811         $LFS migrate -m $MDTIDX $migrate_dir ||
17812                 error "migrate $migrate_dir failed"
17813
17814         echo "Finish migration, then checking.."
17815         for file in $(find $migrate_dir); do
17816                 mdt_index=$($LFS getstripe -m $file)
17817                 [ $mdt_index == $MDTIDX ] ||
17818                         error "$file is not on MDT${MDTIDX}"
17819         done
17820
17821         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17822 }
17823 run_test 230c "check directory accessiblity if migration failed"
17824
17825 test_230d() {
17826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17827         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17828         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17829                 skip "Need MDS version at least 2.11.52"
17830         # LU-11235
17831         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17832
17833         local migrate_dir=$DIR/$tdir/migrate_dir
17834         local old_index
17835         local new_index
17836         local old_count
17837         local new_count
17838         local new_hash
17839         local mdt_index
17840         local i
17841         local j
17842
17843         old_index=$((RANDOM % MDSCOUNT))
17844         old_count=$((MDSCOUNT - old_index))
17845         new_index=$((RANDOM % MDSCOUNT))
17846         new_count=$((MDSCOUNT - new_index))
17847         new_hash=1 # for all_char
17848
17849         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17850         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17851
17852         test_mkdir $DIR/$tdir
17853         test_mkdir -i $old_index -c $old_count $migrate_dir
17854
17855         for ((i=0; i<100; i++)); do
17856                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17857                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17858                         error "create files under remote dir failed $i"
17859         done
17860
17861         echo -n "Migrate from MDT$old_index "
17862         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17863         echo -n "to MDT$new_index"
17864         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17865         echo
17866
17867         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17868         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17869                 error "migrate remote dir error"
17870
17871         echo "Finish migration, then checking.."
17872         for file in $(find $migrate_dir); do
17873                 mdt_index=$($LFS getstripe -m $file)
17874                 if [ $mdt_index -lt $new_index ] ||
17875                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17876                         error "$file is on MDT$mdt_index"
17877                 fi
17878         done
17879
17880         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17881 }
17882 run_test 230d "check migrate big directory"
17883
17884 test_230e() {
17885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17886         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17887         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17888                 skip "Need MDS version at least 2.11.52"
17889
17890         local i
17891         local j
17892         local a_fid
17893         local b_fid
17894
17895         mkdir -p $DIR/$tdir
17896         mkdir $DIR/$tdir/migrate_dir
17897         mkdir $DIR/$tdir/other_dir
17898         touch $DIR/$tdir/migrate_dir/a
17899         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17900         ls $DIR/$tdir/other_dir
17901
17902         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17903                 error "migrate dir fails"
17904
17905         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17906         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17907
17908         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17909         [ $mdt_index == 0 ] || error "a is not on MDT0"
17910
17911         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
17912                 error "migrate dir fails"
17913
17914         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
17915         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
17916
17917         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17918         [ $mdt_index == 1 ] || error "a is not on MDT1"
17919
17920         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
17921         [ $mdt_index == 1 ] || error "b is not on MDT1"
17922
17923         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17924         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
17925
17926         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
17927
17928         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17929 }
17930 run_test 230e "migrate mulitple local link files"
17931
17932 test_230f() {
17933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17934         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17935         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17936                 skip "Need MDS version at least 2.11.52"
17937
17938         local a_fid
17939         local ln_fid
17940
17941         mkdir -p $DIR/$tdir
17942         mkdir $DIR/$tdir/migrate_dir
17943         $LFS mkdir -i1 $DIR/$tdir/other_dir
17944         touch $DIR/$tdir/migrate_dir/a
17945         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
17946         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
17947         ls $DIR/$tdir/other_dir
17948
17949         # a should be migrated to MDT1, since no other links on MDT0
17950         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17951                 error "#1 migrate dir fails"
17952         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17953         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17954         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17955         [ $mdt_index == 1 ] || error "a is not on MDT1"
17956
17957         # a should stay on MDT1, because it is a mulitple link file
17958         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17959                 error "#2 migrate dir fails"
17960         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17961         [ $mdt_index == 1 ] || error "a is not on MDT1"
17962
17963         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17964                 error "#3 migrate dir fails"
17965
17966         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17967         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
17968         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
17969
17970         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
17971         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
17972
17973         # a should be migrated to MDT0, since no other links on MDT1
17974         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17975                 error "#4 migrate dir fails"
17976         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17977         [ $mdt_index == 0 ] || error "a is not on MDT0"
17978
17979         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17980 }
17981 run_test 230f "migrate mulitple remote link files"
17982
17983 test_230g() {
17984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17985         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17986         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17987                 skip "Need MDS version at least 2.11.52"
17988
17989         mkdir -p $DIR/$tdir/migrate_dir
17990
17991         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
17992                 error "migrating dir to non-exist MDT succeeds"
17993         true
17994 }
17995 run_test 230g "migrate dir to non-exist MDT"
17996
17997 test_230h() {
17998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17999         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18000         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18001                 skip "Need MDS version at least 2.11.52"
18002
18003         local mdt_index
18004
18005         mkdir -p $DIR/$tdir/migrate_dir
18006
18007         $LFS migrate -m1 $DIR &&
18008                 error "migrating mountpoint1 should fail"
18009
18010         $LFS migrate -m1 $DIR/$tdir/.. &&
18011                 error "migrating mountpoint2 should fail"
18012
18013         # same as mv
18014         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18015                 error "migrating $tdir/migrate_dir/.. should fail"
18016
18017         true
18018 }
18019 run_test 230h "migrate .. and root"
18020
18021 test_230i() {
18022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18023         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18024         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18025                 skip "Need MDS version at least 2.11.52"
18026
18027         mkdir -p $DIR/$tdir/migrate_dir
18028
18029         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18030                 error "migration fails with a tailing slash"
18031
18032         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18033                 error "migration fails with two tailing slashes"
18034 }
18035 run_test 230i "lfs migrate -m tolerates trailing slashes"
18036
18037 test_230j() {
18038         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18039         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18040                 skip "Need MDS version at least 2.11.52"
18041
18042         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18043         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18044                 error "create $tfile failed"
18045         cat /etc/passwd > $DIR/$tdir/$tfile
18046
18047         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18048
18049         cmp /etc/passwd $DIR/$tdir/$tfile ||
18050                 error "DoM file mismatch after migration"
18051 }
18052 run_test 230j "DoM file data not changed after dir migration"
18053
18054 test_230k() {
18055         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18056         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18057                 skip "Need MDS version at least 2.11.56"
18058
18059         local total=20
18060         local files_on_starting_mdt=0
18061
18062         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18063         $LFS getdirstripe $DIR/$tdir
18064         for i in $(seq $total); do
18065                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18066                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18067                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18068         done
18069
18070         echo "$files_on_starting_mdt files on MDT0"
18071
18072         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18073         $LFS getdirstripe $DIR/$tdir
18074
18075         files_on_starting_mdt=0
18076         for i in $(seq $total); do
18077                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18078                         error "file $tfile.$i mismatch after migration"
18079                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18080                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18081         done
18082
18083         echo "$files_on_starting_mdt files on MDT1 after migration"
18084         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18085
18086         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18087         $LFS getdirstripe $DIR/$tdir
18088
18089         files_on_starting_mdt=0
18090         for i in $(seq $total); do
18091                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18092                         error "file $tfile.$i mismatch after 2nd migration"
18093                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18094                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18095         done
18096
18097         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18098         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18099
18100         true
18101 }
18102 run_test 230k "file data not changed after dir migration"
18103
18104 test_230l() {
18105         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18106         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18107                 skip "Need MDS version at least 2.11.56"
18108
18109         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18110         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18111                 error "create files under remote dir failed $i"
18112         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18113 }
18114 run_test 230l "readdir between MDTs won't crash"
18115
18116 test_230m() {
18117         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18118         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18119                 skip "Need MDS version at least 2.11.56"
18120
18121         local MDTIDX=1
18122         local mig_dir=$DIR/$tdir/migrate_dir
18123         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18124         local shortstr="b"
18125         local val
18126
18127         echo "Creating files and dirs with xattrs"
18128         test_mkdir $DIR/$tdir
18129         test_mkdir -i0 -c1 $mig_dir
18130         mkdir $mig_dir/dir
18131         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18132                 error "cannot set xattr attr1 on dir"
18133         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18134                 error "cannot set xattr attr2 on dir"
18135         touch $mig_dir/dir/f0
18136         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18137                 error "cannot set xattr attr1 on file"
18138         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18139                 error "cannot set xattr attr2 on file"
18140         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18141         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18142         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18143         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18144         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18145         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18146         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18147         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18148         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18149
18150         echo "Migrating to MDT1"
18151         $LFS migrate -m $MDTIDX $mig_dir ||
18152                 error "fails on migrating dir to MDT1"
18153
18154         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18155         echo "Checking xattrs"
18156         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18157         [ "$val" = $longstr ] ||
18158                 error "expecting xattr1 $longstr on dir, found $val"
18159         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18160         [ "$val" = $shortstr ] ||
18161                 error "expecting xattr2 $shortstr on dir, found $val"
18162         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18163         [ "$val" = $longstr ] ||
18164                 error "expecting xattr1 $longstr on file, found $val"
18165         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18166         [ "$val" = $shortstr ] ||
18167                 error "expecting xattr2 $shortstr on file, found $val"
18168 }
18169 run_test 230m "xattrs not changed after dir migration"
18170
18171 test_230n() {
18172         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18173         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18174                 skip "Need MDS version at least 2.13.53"
18175
18176         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18177         cat /etc/hosts > $DIR/$tdir/$tfile
18178         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18179         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18180
18181         cmp /etc/hosts $DIR/$tdir/$tfile ||
18182                 error "File data mismatch after migration"
18183 }
18184 run_test 230n "Dir migration with mirrored file"
18185
18186 test_230o() {
18187         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18188         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18189                 skip "Need MDS version at least 2.13.52"
18190
18191         local mdts=$(comma_list $(mdts_nodes))
18192         local timeout=100
18193
18194         local restripe_status
18195         local delta
18196         local i
18197         local j
18198
18199         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18200
18201         # in case "crush" hash type is not set
18202         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18203
18204         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18205                            mdt.*MDT0000.enable_dir_restripe)
18206         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18207         stack_trap "do_nodes $mdts $LCTL set_param \
18208                     mdt.*.enable_dir_restripe=$restripe_status"
18209
18210         mkdir $DIR/$tdir
18211         createmany -m $DIR/$tdir/f 100 ||
18212                 error "create files under remote dir failed $i"
18213         createmany -d $DIR/$tdir/d 100 ||
18214                 error "create dirs under remote dir failed $i"
18215
18216         for i in $(seq 2 $MDSCOUNT); do
18217                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18218                 $LFS setdirstripe -c $i $DIR/$tdir ||
18219                         error "split -c $i $tdir failed"
18220                 wait_update $HOSTNAME \
18221                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18222                         error "dir split not finished"
18223                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18224                         awk '/migrate/ {sum += $2} END { print sum }')
18225                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18226                 # delta is around total_files/stripe_count
18227                 [ $delta -lt $((200 /(i - 1))) ] ||
18228                         error "$delta files migrated"
18229         done
18230 }
18231 run_test 230o "dir split"
18232
18233 test_230p() {
18234         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18235         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18236                 skip "Need MDS version at least 2.13.52"
18237
18238         local mdts=$(comma_list $(mdts_nodes))
18239         local timeout=100
18240
18241         local restripe_status
18242         local delta
18243         local i
18244         local j
18245
18246         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18247
18248         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18249
18250         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18251                            mdt.*MDT0000.enable_dir_restripe)
18252         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18253         stack_trap "do_nodes $mdts $LCTL set_param \
18254                     mdt.*.enable_dir_restripe=$restripe_status"
18255
18256         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18257         createmany -m $DIR/$tdir/f 100 ||
18258                 error "create files under remote dir failed $i"
18259         createmany -d $DIR/$tdir/d 100 ||
18260                 error "create dirs under remote dir failed $i"
18261
18262         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18263                 local mdt_hash="crush"
18264
18265                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18266                 $LFS setdirstripe -c $i $DIR/$tdir ||
18267                         error "split -c $i $tdir failed"
18268                 [ $i -eq 1 ] && mdt_hash="none"
18269                 wait_update $HOSTNAME \
18270                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18271                         error "dir merge not finished"
18272                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18273                         awk '/migrate/ {sum += $2} END { print sum }')
18274                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18275                 # delta is around total_files/stripe_count
18276                 [ $delta -lt $((200 / i)) ] ||
18277                         error "$delta files migrated"
18278         done
18279 }
18280 run_test 230p "dir merge"
18281
18282 test_230q() {
18283         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18284         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18285                 skip "Need MDS version at least 2.13.52"
18286
18287         local mdts=$(comma_list $(mdts_nodes))
18288         local saved_threshold=$(do_facet mds1 \
18289                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18290         local saved_delta=$(do_facet mds1 \
18291                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18292         local threshold=100
18293         local delta=2
18294         local total=0
18295         local stripe_count=0
18296         local stripe_index
18297         local nr_files
18298
18299         stack_trap "do_nodes $mdts $LCTL set_param \
18300                     mdt.*.dir_split_count=$saved_threshold"
18301         stack_trap "do_nodes $mdts $LCTL set_param \
18302                     mdt.*.dir_split_delta=$saved_delta"
18303         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18304         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18305         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18306         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18307         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18308         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18309
18310         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18311         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18312
18313         while [ $stripe_count -lt $MDSCOUNT ]; do
18314                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18315                         error "create sub files failed"
18316                 stat $DIR/$tdir > /dev/null
18317                 total=$((total + threshold * 3 / 2))
18318                 stripe_count=$((stripe_count + delta))
18319                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18320
18321                 wait_update $HOSTNAME \
18322                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18323                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18324
18325                 wait_update $HOSTNAME \
18326                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18327                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18328
18329                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18330                            grep -w $stripe_index | wc -l)
18331                 echo "$nr_files files on MDT$stripe_index after split"
18332                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18333                         error "$nr_files files on MDT$stripe_index after split"
18334
18335                 nr_files=$(ls $DIR/$tdir | wc -w)
18336                 [ $nr_files -eq $total ] ||
18337                         error "total sub files $nr_files != $total"
18338         done
18339 }
18340 run_test 230q "dir auto split"
18341
18342 test_230r() {
18343         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18344         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18345         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18346                 skip "Need MDS version at least 2.13.54"
18347
18348         # maximum amount of local locks:
18349         # parent striped dir - 2 locks
18350         # new stripe in parent to migrate to - 1 lock
18351         # source and target - 2 locks
18352         # Total 5 locks for regular file
18353         mkdir -p $DIR/$tdir
18354         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18355         touch $DIR/$tdir/dir1/eee
18356
18357         # create 4 hardlink for 4 more locks
18358         # Total: 9 locks > RS_MAX_LOCKS (8)
18359         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18360         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18361         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18362         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18363         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18364         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18365         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18366         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18367
18368         cancel_lru_locks mdc
18369
18370         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18371                 error "migrate dir fails"
18372
18373         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18374 }
18375 run_test 230r "migrate with too many local locks"
18376
18377 test_231a()
18378 {
18379         # For simplicity this test assumes that max_pages_per_rpc
18380         # is the same across all OSCs
18381         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18382         local bulk_size=$((max_pages * PAGE_SIZE))
18383         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18384                                        head -n 1)
18385
18386         mkdir -p $DIR/$tdir
18387         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18388                 error "failed to set stripe with -S ${brw_size}M option"
18389
18390         # clear the OSC stats
18391         $LCTL set_param osc.*.stats=0 &>/dev/null
18392         stop_writeback
18393
18394         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18395         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18396                 oflag=direct &>/dev/null || error "dd failed"
18397
18398         sync; sleep 1; sync # just to be safe
18399         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18400         if [ x$nrpcs != "x1" ]; then
18401                 $LCTL get_param osc.*.stats
18402                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18403         fi
18404
18405         start_writeback
18406         # Drop the OSC cache, otherwise we will read from it
18407         cancel_lru_locks osc
18408
18409         # clear the OSC stats
18410         $LCTL set_param osc.*.stats=0 &>/dev/null
18411
18412         # Client reads $bulk_size.
18413         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18414                 iflag=direct &>/dev/null || error "dd failed"
18415
18416         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18417         if [ x$nrpcs != "x1" ]; then
18418                 $LCTL get_param osc.*.stats
18419                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18420         fi
18421 }
18422 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18423
18424 test_231b() {
18425         mkdir -p $DIR/$tdir
18426         local i
18427         for i in {0..1023}; do
18428                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18429                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18430                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18431         done
18432         sync
18433 }
18434 run_test 231b "must not assert on fully utilized OST request buffer"
18435
18436 test_232a() {
18437         mkdir -p $DIR/$tdir
18438         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18439
18440         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18441         do_facet ost1 $LCTL set_param fail_loc=0x31c
18442
18443         # ignore dd failure
18444         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18445
18446         do_facet ost1 $LCTL set_param fail_loc=0
18447         umount_client $MOUNT || error "umount failed"
18448         mount_client $MOUNT || error "mount failed"
18449         stop ost1 || error "cannot stop ost1"
18450         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18451 }
18452 run_test 232a "failed lock should not block umount"
18453
18454 test_232b() {
18455         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18456                 skip "Need MDS version at least 2.10.58"
18457
18458         mkdir -p $DIR/$tdir
18459         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18460         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18461         sync
18462         cancel_lru_locks osc
18463
18464         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18465         do_facet ost1 $LCTL set_param fail_loc=0x31c
18466
18467         # ignore failure
18468         $LFS data_version $DIR/$tdir/$tfile || true
18469
18470         do_facet ost1 $LCTL set_param fail_loc=0
18471         umount_client $MOUNT || error "umount failed"
18472         mount_client $MOUNT || error "mount failed"
18473         stop ost1 || error "cannot stop ost1"
18474         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18475 }
18476 run_test 232b "failed data version lock should not block umount"
18477
18478 test_233a() {
18479         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18480                 skip "Need MDS version at least 2.3.64"
18481         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18482
18483         local fid=$($LFS path2fid $MOUNT)
18484
18485         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18486                 error "cannot access $MOUNT using its FID '$fid'"
18487 }
18488 run_test 233a "checking that OBF of the FS root succeeds"
18489
18490 test_233b() {
18491         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18492                 skip "Need MDS version at least 2.5.90"
18493         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18494
18495         local fid=$($LFS path2fid $MOUNT/.lustre)
18496
18497         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18498                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18499
18500         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18501         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18502                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18503 }
18504 run_test 233b "checking that OBF of the FS .lustre succeeds"
18505
18506 test_234() {
18507         local p="$TMP/sanityN-$TESTNAME.parameters"
18508         save_lustre_params client "llite.*.xattr_cache" > $p
18509         lctl set_param llite.*.xattr_cache 1 ||
18510                 skip_env "xattr cache is not supported"
18511
18512         mkdir -p $DIR/$tdir || error "mkdir failed"
18513         touch $DIR/$tdir/$tfile || error "touch failed"
18514         # OBD_FAIL_LLITE_XATTR_ENOMEM
18515         $LCTL set_param fail_loc=0x1405
18516         getfattr -n user.attr $DIR/$tdir/$tfile &&
18517                 error "getfattr should have failed with ENOMEM"
18518         $LCTL set_param fail_loc=0x0
18519         rm -rf $DIR/$tdir
18520
18521         restore_lustre_params < $p
18522         rm -f $p
18523 }
18524 run_test 234 "xattr cache should not crash on ENOMEM"
18525
18526 test_235() {
18527         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18528                 skip "Need MDS version at least 2.4.52"
18529
18530         flock_deadlock $DIR/$tfile
18531         local RC=$?
18532         case $RC in
18533                 0)
18534                 ;;
18535                 124) error "process hangs on a deadlock"
18536                 ;;
18537                 *) error "error executing flock_deadlock $DIR/$tfile"
18538                 ;;
18539         esac
18540 }
18541 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18542
18543 #LU-2935
18544 test_236() {
18545         check_swap_layouts_support
18546
18547         local ref1=/etc/passwd
18548         local ref2=/etc/group
18549         local file1=$DIR/$tdir/f1
18550         local file2=$DIR/$tdir/f2
18551
18552         test_mkdir -c1 $DIR/$tdir
18553         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18554         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18555         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18556         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18557         local fd=$(free_fd)
18558         local cmd="exec $fd<>$file2"
18559         eval $cmd
18560         rm $file2
18561         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18562                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18563         cmd="exec $fd>&-"
18564         eval $cmd
18565         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18566
18567         #cleanup
18568         rm -rf $DIR/$tdir
18569 }
18570 run_test 236 "Layout swap on open unlinked file"
18571
18572 # LU-4659 linkea consistency
18573 test_238() {
18574         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18575                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18576                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18577                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18578
18579         touch $DIR/$tfile
18580         ln $DIR/$tfile $DIR/$tfile.lnk
18581         touch $DIR/$tfile.new
18582         mv $DIR/$tfile.new $DIR/$tfile
18583         local fid1=$($LFS path2fid $DIR/$tfile)
18584         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18585         local path1=$($LFS fid2path $FSNAME "$fid1")
18586         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18587         local path2=$($LFS fid2path $FSNAME "$fid2")
18588         [ $tfile.lnk == $path2 ] ||
18589                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18590         rm -f $DIR/$tfile*
18591 }
18592 run_test 238 "Verify linkea consistency"
18593
18594 test_239A() { # was test_239
18595         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18596                 skip "Need MDS version at least 2.5.60"
18597
18598         local list=$(comma_list $(mdts_nodes))
18599
18600         mkdir -p $DIR/$tdir
18601         createmany -o $DIR/$tdir/f- 5000
18602         unlinkmany $DIR/$tdir/f- 5000
18603         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18604                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18605         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18606                         osp.*MDT*.sync_in_flight" | calc_sum)
18607         [ "$changes" -eq 0 ] || error "$changes not synced"
18608 }
18609 run_test 239A "osp_sync test"
18610
18611 test_239a() { #LU-5297
18612         remote_mds_nodsh && skip "remote MDS with nodsh"
18613
18614         touch $DIR/$tfile
18615         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18616         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18617         chgrp $RUNAS_GID $DIR/$tfile
18618         wait_delete_completed
18619 }
18620 run_test 239a "process invalid osp sync record correctly"
18621
18622 test_239b() { #LU-5297
18623         remote_mds_nodsh && skip "remote MDS with nodsh"
18624
18625         touch $DIR/$tfile1
18626         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18627         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18628         chgrp $RUNAS_GID $DIR/$tfile1
18629         wait_delete_completed
18630         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18631         touch $DIR/$tfile2
18632         chgrp $RUNAS_GID $DIR/$tfile2
18633         wait_delete_completed
18634 }
18635 run_test 239b "process osp sync record with ENOMEM error correctly"
18636
18637 test_240() {
18638         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18639         remote_mds_nodsh && skip "remote MDS with nodsh"
18640
18641         mkdir -p $DIR/$tdir
18642
18643         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18644                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18645         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18646                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18647
18648         umount_client $MOUNT || error "umount failed"
18649         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18650         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18651         mount_client $MOUNT || error "failed to mount client"
18652
18653         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18654         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18655 }
18656 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18657
18658 test_241_bio() {
18659         local count=$1
18660         local bsize=$2
18661
18662         for LOOP in $(seq $count); do
18663                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18664                 cancel_lru_locks $OSC || true
18665         done
18666 }
18667
18668 test_241_dio() {
18669         local count=$1
18670         local bsize=$2
18671
18672         for LOOP in $(seq $1); do
18673                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18674                         2>/dev/null
18675         done
18676 }
18677
18678 test_241a() { # was test_241
18679         local bsize=$PAGE_SIZE
18680
18681         (( bsize < 40960 )) && bsize=40960
18682         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18683         ls -la $DIR/$tfile
18684         cancel_lru_locks $OSC
18685         test_241_bio 1000 $bsize &
18686         PID=$!
18687         test_241_dio 1000 $bsize
18688         wait $PID
18689 }
18690 run_test 241a "bio vs dio"
18691
18692 test_241b() {
18693         local bsize=$PAGE_SIZE
18694
18695         (( bsize < 40960 )) && bsize=40960
18696         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18697         ls -la $DIR/$tfile
18698         test_241_dio 1000 $bsize &
18699         PID=$!
18700         test_241_dio 1000 $bsize
18701         wait $PID
18702 }
18703 run_test 241b "dio vs dio"
18704
18705 test_242() {
18706         remote_mds_nodsh && skip "remote MDS with nodsh"
18707
18708         mkdir -p $DIR/$tdir
18709         touch $DIR/$tdir/$tfile
18710
18711         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18712         do_facet mds1 lctl set_param fail_loc=0x105
18713         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18714
18715         do_facet mds1 lctl set_param fail_loc=0
18716         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18717 }
18718 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18719
18720 test_243()
18721 {
18722         test_mkdir $DIR/$tdir
18723         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18724 }
18725 run_test 243 "various group lock tests"
18726
18727 test_244a()
18728 {
18729         test_mkdir $DIR/$tdir
18730         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18731         sendfile_grouplock $DIR/$tdir/$tfile || \
18732                 error "sendfile+grouplock failed"
18733         rm -rf $DIR/$tdir
18734 }
18735 run_test 244a "sendfile with group lock tests"
18736
18737 test_244b()
18738 {
18739         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18740
18741         local threads=50
18742         local size=$((1024*1024))
18743
18744         test_mkdir $DIR/$tdir
18745         for i in $(seq 1 $threads); do
18746                 local file=$DIR/$tdir/file_$((i / 10))
18747                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18748                 local pids[$i]=$!
18749         done
18750         for i in $(seq 1 $threads); do
18751                 wait ${pids[$i]}
18752         done
18753 }
18754 run_test 244b "multi-threaded write with group lock"
18755
18756 test_245() {
18757         local flagname="multi_mod_rpcs"
18758         local connect_data_name="max_mod_rpcs"
18759         local out
18760
18761         # check if multiple modify RPCs flag is set
18762         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18763                 grep "connect_flags:")
18764         echo "$out"
18765
18766         echo "$out" | grep -qw $flagname
18767         if [ $? -ne 0 ]; then
18768                 echo "connect flag $flagname is not set"
18769                 return
18770         fi
18771
18772         # check if multiple modify RPCs data is set
18773         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18774         echo "$out"
18775
18776         echo "$out" | grep -qw $connect_data_name ||
18777                 error "import should have connect data $connect_data_name"
18778 }
18779 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18780
18781 cleanup_247() {
18782         local submount=$1
18783
18784         trap 0
18785         umount_client $submount
18786         rmdir $submount
18787 }
18788
18789 test_247a() {
18790         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18791                 grep -q subtree ||
18792                 skip_env "Fileset feature is not supported"
18793
18794         local submount=${MOUNT}_$tdir
18795
18796         mkdir $MOUNT/$tdir
18797         mkdir -p $submount || error "mkdir $submount failed"
18798         FILESET="$FILESET/$tdir" mount_client $submount ||
18799                 error "mount $submount failed"
18800         trap "cleanup_247 $submount" EXIT
18801         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18802         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18803                 error "read $MOUNT/$tdir/$tfile failed"
18804         cleanup_247 $submount
18805 }
18806 run_test 247a "mount subdir as fileset"
18807
18808 test_247b() {
18809         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18810                 skip_env "Fileset feature is not supported"
18811
18812         local submount=${MOUNT}_$tdir
18813
18814         rm -rf $MOUNT/$tdir
18815         mkdir -p $submount || error "mkdir $submount failed"
18816         SKIP_FILESET=1
18817         FILESET="$FILESET/$tdir" mount_client $submount &&
18818                 error "mount $submount should fail"
18819         rmdir $submount
18820 }
18821 run_test 247b "mount subdir that dose not exist"
18822
18823 test_247c() {
18824         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18825                 skip_env "Fileset feature is not supported"
18826
18827         local submount=${MOUNT}_$tdir
18828
18829         mkdir -p $MOUNT/$tdir/dir1
18830         mkdir -p $submount || error "mkdir $submount failed"
18831         trap "cleanup_247 $submount" EXIT
18832         FILESET="$FILESET/$tdir" mount_client $submount ||
18833                 error "mount $submount failed"
18834         local fid=$($LFS path2fid $MOUNT/)
18835         $LFS fid2path $submount $fid && error "fid2path should fail"
18836         cleanup_247 $submount
18837 }
18838 run_test 247c "running fid2path outside subdirectory root"
18839
18840 test_247d() {
18841         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18842                 skip "Fileset feature is not supported"
18843
18844         local submount=${MOUNT}_$tdir
18845
18846         mkdir -p $MOUNT/$tdir/dir1
18847         mkdir -p $submount || error "mkdir $submount failed"
18848         FILESET="$FILESET/$tdir" mount_client $submount ||
18849                 error "mount $submount failed"
18850         trap "cleanup_247 $submount" EXIT
18851
18852         local td=$submount/dir1
18853         local fid=$($LFS path2fid $td)
18854         [ -z "$fid" ] && error "path2fid unable to get $td FID"
18855
18856         # check that we get the same pathname back
18857         local rootpath
18858         local found
18859         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
18860                 echo "$rootpath $fid"
18861                 found=$($LFS fid2path $rootpath "$fid")
18862                 [ -n "found" ] || error "fid2path should succeed"
18863                 [ "$found" == "$td" ] || error "fid2path $found != $td"
18864         done
18865         # check wrong root path format
18866         rootpath=$submount"_wrong"
18867         found=$($LFS fid2path $rootpath "$fid")
18868         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
18869
18870         cleanup_247 $submount
18871 }
18872 run_test 247d "running fid2path inside subdirectory root"
18873
18874 # LU-8037
18875 test_247e() {
18876         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18877                 grep -q subtree ||
18878                 skip "Fileset feature is not supported"
18879
18880         local submount=${MOUNT}_$tdir
18881
18882         mkdir $MOUNT/$tdir
18883         mkdir -p $submount || error "mkdir $submount failed"
18884         FILESET="$FILESET/.." mount_client $submount &&
18885                 error "mount $submount should fail"
18886         rmdir $submount
18887 }
18888 run_test 247e "mount .. as fileset"
18889
18890 test_247f() {
18891         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18892         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18893                 skip "Need at least version 2.13.52"
18894         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18895                 grep -q subtree ||
18896                 skip "Fileset feature is not supported"
18897
18898         mkdir $DIR/$tdir || error "mkdir $tdir failed"
18899         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
18900                 error "mkdir remote failed"
18901         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
18902         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
18903                 error "mkdir striped failed"
18904         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
18905
18906         local submount=${MOUNT}_$tdir
18907
18908         mkdir -p $submount || error "mkdir $submount failed"
18909
18910         local dir
18911         local fileset=$FILESET
18912
18913         for dir in $tdir/remote $tdir/remote/subdir \
18914                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
18915                 FILESET="$fileset/$dir" mount_client $submount ||
18916                         error "mount $dir failed"
18917                 umount_client $submount
18918         done
18919 }
18920 run_test 247f "mount striped or remote directory as fileset"
18921
18922 test_248a() {
18923         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
18924         [ -z "$fast_read_sav" ] && skip "no fast read support"
18925
18926         # create a large file for fast read verification
18927         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
18928
18929         # make sure the file is created correctly
18930         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
18931                 { rm -f $DIR/$tfile; skip "file creation error"; }
18932
18933         echo "Test 1: verify that fast read is 4 times faster on cache read"
18934
18935         # small read with fast read enabled
18936         $LCTL set_param -n llite.*.fast_read=1
18937         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18938                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18939                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18940         # small read with fast read disabled
18941         $LCTL set_param -n llite.*.fast_read=0
18942         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18943                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18944                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18945
18946         # verify that fast read is 4 times faster for cache read
18947         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
18948                 error_not_in_vm "fast read was not 4 times faster: " \
18949                            "$t_fast vs $t_slow"
18950
18951         echo "Test 2: verify the performance between big and small read"
18952         $LCTL set_param -n llite.*.fast_read=1
18953
18954         # 1k non-cache read
18955         cancel_lru_locks osc
18956         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18957                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18958                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18959
18960         # 1M non-cache read
18961         cancel_lru_locks osc
18962         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18963                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18964                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18965
18966         # verify that big IO is not 4 times faster than small IO
18967         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
18968                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
18969
18970         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
18971         rm -f $DIR/$tfile
18972 }
18973 run_test 248a "fast read verification"
18974
18975 test_248b() {
18976         # Default short_io_bytes=16384, try both smaller and larger sizes.
18977         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
18978         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
18979         echo "bs=53248 count=113 normal buffered write"
18980         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
18981                 error "dd of initial data file failed"
18982         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
18983
18984         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
18985         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
18986                 error "dd with sync normal writes failed"
18987         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
18988
18989         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
18990         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
18991                 error "dd with sync small writes failed"
18992         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
18993
18994         cancel_lru_locks osc
18995
18996         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
18997         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
18998         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
18999         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19000                 iflag=direct || error "dd with O_DIRECT small read failed"
19001         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19002         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19003                 error "compare $TMP/$tfile.1 failed"
19004
19005         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19006         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19007
19008         # just to see what the maximum tunable value is, and test parsing
19009         echo "test invalid parameter 2MB"
19010         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19011                 error "too-large short_io_bytes allowed"
19012         echo "test maximum parameter 512KB"
19013         # if we can set a larger short_io_bytes, run test regardless of version
19014         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19015                 # older clients may not allow setting it this large, that's OK
19016                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19017                         skip "Need at least client version 2.13.50"
19018                 error "medium short_io_bytes failed"
19019         fi
19020         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19021         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19022
19023         echo "test large parameter 64KB"
19024         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19025         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19026
19027         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19028         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19029                 error "dd with sync large writes failed"
19030         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19031
19032         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19033         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19034         num=$((113 * 4096 / PAGE_SIZE))
19035         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19036         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19037                 error "dd with O_DIRECT large writes failed"
19038         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19039                 error "compare $DIR/$tfile.3 failed"
19040
19041         cancel_lru_locks osc
19042
19043         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19044         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19045                 error "dd with O_DIRECT large read failed"
19046         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19047                 error "compare $TMP/$tfile.2 failed"
19048
19049         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19050         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19051                 error "dd with O_DIRECT large read failed"
19052         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19053                 error "compare $TMP/$tfile.3 failed"
19054 }
19055 run_test 248b "test short_io read and write for both small and large sizes"
19056
19057 test_249() { # LU-7890
19058         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19059                 skip "Need at least version 2.8.54"
19060
19061         rm -f $DIR/$tfile
19062         $LFS setstripe -c 1 $DIR/$tfile
19063         # Offset 2T == 4k * 512M
19064         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19065                 error "dd to 2T offset failed"
19066 }
19067 run_test 249 "Write above 2T file size"
19068
19069 test_250() {
19070         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19071          && skip "no 16TB file size limit on ZFS"
19072
19073         $LFS setstripe -c 1 $DIR/$tfile
19074         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19075         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19076         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19077         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19078                 conv=notrunc,fsync && error "append succeeded"
19079         return 0
19080 }
19081 run_test 250 "Write above 16T limit"
19082
19083 test_251() {
19084         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19085
19086         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19087         #Skip once - writing the first stripe will succeed
19088         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19089         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19090                 error "short write happened"
19091
19092         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19093         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19094                 error "short read happened"
19095
19096         rm -f $DIR/$tfile
19097 }
19098 run_test 251 "Handling short read and write correctly"
19099
19100 test_252() {
19101         remote_mds_nodsh && skip "remote MDS with nodsh"
19102         remote_ost_nodsh && skip "remote OST with nodsh"
19103         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19104                 skip_env "ldiskfs only test"
19105         fi
19106
19107         local tgt
19108         local dev
19109         local out
19110         local uuid
19111         local num
19112         local gen
19113
19114         # check lr_reader on OST0000
19115         tgt=ost1
19116         dev=$(facet_device $tgt)
19117         out=$(do_facet $tgt $LR_READER $dev)
19118         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19119         echo "$out"
19120         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19121         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19122                 error "Invalid uuid returned by $LR_READER on target $tgt"
19123         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19124
19125         # check lr_reader -c on MDT0000
19126         tgt=mds1
19127         dev=$(facet_device $tgt)
19128         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19129                 skip "$LR_READER does not support additional options"
19130         fi
19131         out=$(do_facet $tgt $LR_READER -c $dev)
19132         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19133         echo "$out"
19134         num=$(echo "$out" | grep -c "mdtlov")
19135         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19136                 error "Invalid number of mdtlov clients returned by $LR_READER"
19137         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19138
19139         # check lr_reader -cr on MDT0000
19140         out=$(do_facet $tgt $LR_READER -cr $dev)
19141         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19142         echo "$out"
19143         echo "$out" | grep -q "^reply_data:$" ||
19144                 error "$LR_READER should have returned 'reply_data' section"
19145         num=$(echo "$out" | grep -c "client_generation")
19146         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19147 }
19148 run_test 252 "check lr_reader tool"
19149
19150 test_253() {
19151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19152         remote_mds_nodsh && skip "remote MDS with nodsh"
19153         remote_mgs_nodsh && skip "remote MGS with nodsh"
19154
19155         local ostidx=0
19156         local rc=0
19157         local ost_name=$(ostname_from_index $ostidx)
19158
19159         # on the mdt's osc
19160         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19161         do_facet $SINGLEMDS $LCTL get_param -n \
19162                 osp.$mdtosc_proc1.reserved_mb_high ||
19163                 skip  "remote MDS does not support reserved_mb_high"
19164
19165         rm -rf $DIR/$tdir
19166         wait_mds_ost_sync
19167         wait_delete_completed
19168         mkdir $DIR/$tdir
19169
19170         pool_add $TESTNAME || error "Pool creation failed"
19171         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19172
19173         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19174                 error "Setstripe failed"
19175
19176         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19177
19178         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19179                     grep "watermarks")
19180         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19181
19182         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19183                         osp.$mdtosc_proc1.prealloc_status)
19184         echo "prealloc_status $oa_status"
19185
19186         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19187                 error "File creation should fail"
19188
19189         #object allocation was stopped, but we still able to append files
19190         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19191                 oflag=append || error "Append failed"
19192
19193         rm -f $DIR/$tdir/$tfile.0
19194
19195         # For this test, we want to delete the files we created to go out of
19196         # space but leave the watermark, so we remain nearly out of space
19197         ost_watermarks_enospc_delete_files $tfile $ostidx
19198
19199         wait_delete_completed
19200
19201         sleep_maxage
19202
19203         for i in $(seq 10 12); do
19204                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19205                         2>/dev/null || error "File creation failed after rm"
19206         done
19207
19208         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19209                         osp.$mdtosc_proc1.prealloc_status)
19210         echo "prealloc_status $oa_status"
19211
19212         if (( oa_status != 0 )); then
19213                 error "Object allocation still disable after rm"
19214         fi
19215 }
19216 run_test 253 "Check object allocation limit"
19217
19218 test_254() {
19219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19220         remote_mds_nodsh && skip "remote MDS with nodsh"
19221         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19222                 skip "MDS does not support changelog_size"
19223
19224         local cl_user
19225         local MDT0=$(facet_svc $SINGLEMDS)
19226
19227         changelog_register || error "changelog_register failed"
19228
19229         changelog_clear 0 || error "changelog_clear failed"
19230
19231         local size1=$(do_facet $SINGLEMDS \
19232                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19233         echo "Changelog size $size1"
19234
19235         rm -rf $DIR/$tdir
19236         $LFS mkdir -i 0 $DIR/$tdir
19237         # change something
19238         mkdir -p $DIR/$tdir/pics/2008/zachy
19239         touch $DIR/$tdir/pics/2008/zachy/timestamp
19240         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19241         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19242         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19243         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19244         rm $DIR/$tdir/pics/desktop.jpg
19245
19246         local size2=$(do_facet $SINGLEMDS \
19247                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19248         echo "Changelog size after work $size2"
19249
19250         (( $size2 > $size1 )) ||
19251                 error "new Changelog size=$size2 less than old size=$size1"
19252 }
19253 run_test 254 "Check changelog size"
19254
19255 ladvise_no_type()
19256 {
19257         local type=$1
19258         local file=$2
19259
19260         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19261                 awk -F: '{print $2}' | grep $type > /dev/null
19262         if [ $? -ne 0 ]; then
19263                 return 0
19264         fi
19265         return 1
19266 }
19267
19268 ladvise_no_ioctl()
19269 {
19270         local file=$1
19271
19272         lfs ladvise -a willread $file > /dev/null 2>&1
19273         if [ $? -eq 0 ]; then
19274                 return 1
19275         fi
19276
19277         lfs ladvise -a willread $file 2>&1 |
19278                 grep "Inappropriate ioctl for device" > /dev/null
19279         if [ $? -eq 0 ]; then
19280                 return 0
19281         fi
19282         return 1
19283 }
19284
19285 percent() {
19286         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19287 }
19288
19289 # run a random read IO workload
19290 # usage: random_read_iops <filename> <filesize> <iosize>
19291 random_read_iops() {
19292         local file=$1
19293         local fsize=$2
19294         local iosize=${3:-4096}
19295
19296         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19297                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19298 }
19299
19300 drop_file_oss_cache() {
19301         local file="$1"
19302         local nodes="$2"
19303
19304         $LFS ladvise -a dontneed $file 2>/dev/null ||
19305                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19306 }
19307
19308 ladvise_willread_performance()
19309 {
19310         local repeat=10
19311         local average_origin=0
19312         local average_cache=0
19313         local average_ladvise=0
19314
19315         for ((i = 1; i <= $repeat; i++)); do
19316                 echo "Iter $i/$repeat: reading without willread hint"
19317                 cancel_lru_locks osc
19318                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19319                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19320                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19321                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19322
19323                 cancel_lru_locks osc
19324                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19325                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19326                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19327
19328                 cancel_lru_locks osc
19329                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19330                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19331                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19332                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19333                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19334         done
19335         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19336         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19337         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19338
19339         speedup_cache=$(percent $average_cache $average_origin)
19340         speedup_ladvise=$(percent $average_ladvise $average_origin)
19341
19342         echo "Average uncached read: $average_origin"
19343         echo "Average speedup with OSS cached read: " \
19344                 "$average_cache = +$speedup_cache%"
19345         echo "Average speedup with ladvise willread: " \
19346                 "$average_ladvise = +$speedup_ladvise%"
19347
19348         local lowest_speedup=20
19349         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19350                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19351                         "got $average_cache%. Skipping ladvise willread check."
19352                 return 0
19353         fi
19354
19355         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19356         # it is still good to run until then to exercise 'ladvise willread'
19357         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19358                 [ "$ost1_FSTYPE" = "zfs" ] &&
19359                 echo "osd-zfs does not support dontneed or drop_caches" &&
19360                 return 0
19361
19362         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19363         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19364                 error_not_in_vm "Speedup with willread is less than " \
19365                         "$lowest_speedup%, got $average_ladvise%"
19366 }
19367
19368 test_255a() {
19369         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19370                 skip "lustre < 2.8.54 does not support ladvise "
19371         remote_ost_nodsh && skip "remote OST with nodsh"
19372
19373         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19374
19375         ladvise_no_type willread $DIR/$tfile &&
19376                 skip "willread ladvise is not supported"
19377
19378         ladvise_no_ioctl $DIR/$tfile &&
19379                 skip "ladvise ioctl is not supported"
19380
19381         local size_mb=100
19382         local size=$((size_mb * 1048576))
19383         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19384                 error "dd to $DIR/$tfile failed"
19385
19386         lfs ladvise -a willread $DIR/$tfile ||
19387                 error "Ladvise failed with no range argument"
19388
19389         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19390                 error "Ladvise failed with no -l or -e argument"
19391
19392         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19393                 error "Ladvise failed with only -e argument"
19394
19395         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19396                 error "Ladvise failed with only -l argument"
19397
19398         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19399                 error "End offset should not be smaller than start offset"
19400
19401         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19402                 error "End offset should not be equal to start offset"
19403
19404         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19405                 error "Ladvise failed with overflowing -s argument"
19406
19407         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19408                 error "Ladvise failed with overflowing -e argument"
19409
19410         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19411                 error "Ladvise failed with overflowing -l argument"
19412
19413         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19414                 error "Ladvise succeeded with conflicting -l and -e arguments"
19415
19416         echo "Synchronous ladvise should wait"
19417         local delay=4
19418 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19419         do_nodes $(comma_list $(osts_nodes)) \
19420                 $LCTL set_param fail_val=$delay fail_loc=0x237
19421
19422         local start_ts=$SECONDS
19423         lfs ladvise -a willread $DIR/$tfile ||
19424                 error "Ladvise failed with no range argument"
19425         local end_ts=$SECONDS
19426         local inteval_ts=$((end_ts - start_ts))
19427
19428         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19429                 error "Synchronous advice didn't wait reply"
19430         fi
19431
19432         echo "Asynchronous ladvise shouldn't wait"
19433         local start_ts=$SECONDS
19434         lfs ladvise -a willread -b $DIR/$tfile ||
19435                 error "Ladvise failed with no range argument"
19436         local end_ts=$SECONDS
19437         local inteval_ts=$((end_ts - start_ts))
19438
19439         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19440                 error "Asynchronous advice blocked"
19441         fi
19442
19443         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19444         ladvise_willread_performance
19445 }
19446 run_test 255a "check 'lfs ladvise -a willread'"
19447
19448 facet_meminfo() {
19449         local facet=$1
19450         local info=$2
19451
19452         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19453 }
19454
19455 test_255b() {
19456         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19457                 skip "lustre < 2.8.54 does not support ladvise "
19458         remote_ost_nodsh && skip "remote OST with nodsh"
19459
19460         lfs setstripe -c 1 -i 0 $DIR/$tfile
19461
19462         ladvise_no_type dontneed $DIR/$tfile &&
19463                 skip "dontneed ladvise is not supported"
19464
19465         ladvise_no_ioctl $DIR/$tfile &&
19466                 skip "ladvise ioctl is not supported"
19467
19468         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19469                 [ "$ost1_FSTYPE" = "zfs" ] &&
19470                 skip "zfs-osd does not support 'ladvise dontneed'"
19471
19472         local size_mb=100
19473         local size=$((size_mb * 1048576))
19474         # In order to prevent disturbance of other processes, only check 3/4
19475         # of the memory usage
19476         local kibibytes=$((size_mb * 1024 * 3 / 4))
19477
19478         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19479                 error "dd to $DIR/$tfile failed"
19480
19481         #force write to complete before dropping OST cache & checking memory
19482         sync
19483
19484         local total=$(facet_meminfo ost1 MemTotal)
19485         echo "Total memory: $total KiB"
19486
19487         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19488         local before_read=$(facet_meminfo ost1 Cached)
19489         echo "Cache used before read: $before_read KiB"
19490
19491         lfs ladvise -a willread $DIR/$tfile ||
19492                 error "Ladvise willread failed"
19493         local after_read=$(facet_meminfo ost1 Cached)
19494         echo "Cache used after read: $after_read KiB"
19495
19496         lfs ladvise -a dontneed $DIR/$tfile ||
19497                 error "Ladvise dontneed again failed"
19498         local no_read=$(facet_meminfo ost1 Cached)
19499         echo "Cache used after dontneed ladvise: $no_read KiB"
19500
19501         if [ $total -lt $((before_read + kibibytes)) ]; then
19502                 echo "Memory is too small, abort checking"
19503                 return 0
19504         fi
19505
19506         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19507                 error "Ladvise willread should use more memory" \
19508                         "than $kibibytes KiB"
19509         fi
19510
19511         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19512                 error "Ladvise dontneed should release more memory" \
19513                         "than $kibibytes KiB"
19514         fi
19515 }
19516 run_test 255b "check 'lfs ladvise -a dontneed'"
19517
19518 test_255c() {
19519         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19520                 skip "lustre < 2.10.50 does not support lockahead"
19521
19522         local count
19523         local new_count
19524         local difference
19525         local i
19526         local rc
19527
19528         test_mkdir -p $DIR/$tdir
19529         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19530
19531         #test 10 returns only success/failure
19532         i=10
19533         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19534         rc=$?
19535         if [ $rc -eq 255 ]; then
19536                 error "Ladvise test${i} failed, ${rc}"
19537         fi
19538
19539         #test 11 counts lock enqueue requests, all others count new locks
19540         i=11
19541         count=$(do_facet ost1 \
19542                 $LCTL get_param -n ost.OSS.ost.stats)
19543         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19544
19545         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19546         rc=$?
19547         if [ $rc -eq 255 ]; then
19548                 error "Ladvise test${i} failed, ${rc}"
19549         fi
19550
19551         new_count=$(do_facet ost1 \
19552                 $LCTL get_param -n ost.OSS.ost.stats)
19553         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19554                    awk '{ print $2 }')
19555
19556         difference="$((new_count - count))"
19557         if [ $difference -ne $rc ]; then
19558                 error "Ladvise test${i}, bad enqueue count, returned " \
19559                       "${rc}, actual ${difference}"
19560         fi
19561
19562         for i in $(seq 12 21); do
19563                 # If we do not do this, we run the risk of having too many
19564                 # locks and starting lock cancellation while we are checking
19565                 # lock counts.
19566                 cancel_lru_locks osc
19567
19568                 count=$($LCTL get_param -n \
19569                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19570
19571                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19572                 rc=$?
19573                 if [ $rc -eq 255 ]; then
19574                         error "Ladvise test ${i} failed, ${rc}"
19575                 fi
19576
19577                 new_count=$($LCTL get_param -n \
19578                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19579                 difference="$((new_count - count))"
19580
19581                 # Test 15 output is divided by 100 to map down to valid return
19582                 if [ $i -eq 15 ]; then
19583                         rc="$((rc * 100))"
19584                 fi
19585
19586                 if [ $difference -ne $rc ]; then
19587                         error "Ladvise test ${i}, bad lock count, returned " \
19588                               "${rc}, actual ${difference}"
19589                 fi
19590         done
19591
19592         #test 22 returns only success/failure
19593         i=22
19594         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19595         rc=$?
19596         if [ $rc -eq 255 ]; then
19597                 error "Ladvise test${i} failed, ${rc}"
19598         fi
19599 }
19600 run_test 255c "suite of ladvise lockahead tests"
19601
19602 test_256() {
19603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19604         remote_mds_nodsh && skip "remote MDS with nodsh"
19605         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19606         changelog_users $SINGLEMDS | grep "^cl" &&
19607                 skip "active changelog user"
19608
19609         local cl_user
19610         local cat_sl
19611         local mdt_dev
19612
19613         mdt_dev=$(mdsdevname 1)
19614         echo $mdt_dev
19615
19616         changelog_register || error "changelog_register failed"
19617
19618         rm -rf $DIR/$tdir
19619         mkdir -p $DIR/$tdir
19620
19621         changelog_clear 0 || error "changelog_clear failed"
19622
19623         # change something
19624         touch $DIR/$tdir/{1..10}
19625
19626         # stop the MDT
19627         stop $SINGLEMDS || error "Fail to stop MDT"
19628
19629         # remount the MDT
19630
19631         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19632
19633         #after mount new plainllog is used
19634         touch $DIR/$tdir/{11..19}
19635         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19636         stack_trap "rm -f $tmpfile"
19637         cat_sl=$(do_facet $SINGLEMDS "sync; \
19638                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19639                  llog_reader $tmpfile | grep -c type=1064553b")
19640         do_facet $SINGLEMDS llog_reader $tmpfile
19641
19642         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19643
19644         changelog_clear 0 || error "changelog_clear failed"
19645
19646         cat_sl=$(do_facet $SINGLEMDS "sync; \
19647                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19648                  llog_reader $tmpfile | grep -c type=1064553b")
19649
19650         if (( cat_sl == 2 )); then
19651                 error "Empty plain llog was not deleted from changelog catalog"
19652         elif (( cat_sl != 1 )); then
19653                 error "Active plain llog shouldn't be deleted from catalog"
19654         fi
19655 }
19656 run_test 256 "Check llog delete for empty and not full state"
19657
19658 test_257() {
19659         remote_mds_nodsh && skip "remote MDS with nodsh"
19660         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19661                 skip "Need MDS version at least 2.8.55"
19662
19663         test_mkdir $DIR/$tdir
19664
19665         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19666                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19667         stat $DIR/$tdir
19668
19669 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19670         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19671         local facet=mds$((mdtidx + 1))
19672         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19673         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19674
19675         stop $facet || error "stop MDS failed"
19676         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19677                 error "start MDS fail"
19678         wait_recovery_complete $facet
19679 }
19680 run_test 257 "xattr locks are not lost"
19681
19682 # Verify we take the i_mutex when security requires it
19683 test_258a() {
19684 #define OBD_FAIL_IMUTEX_SEC 0x141c
19685         $LCTL set_param fail_loc=0x141c
19686         touch $DIR/$tfile
19687         chmod u+s $DIR/$tfile
19688         chmod a+rwx $DIR/$tfile
19689         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19690         RC=$?
19691         if [ $RC -ne 0 ]; then
19692                 error "error, failed to take i_mutex, rc=$?"
19693         fi
19694         rm -f $DIR/$tfile
19695 }
19696 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19697
19698 # Verify we do NOT take the i_mutex in the normal case
19699 test_258b() {
19700 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19701         $LCTL set_param fail_loc=0x141d
19702         touch $DIR/$tfile
19703         chmod a+rwx $DIR
19704         chmod a+rw $DIR/$tfile
19705         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19706         RC=$?
19707         if [ $RC -ne 0 ]; then
19708                 error "error, took i_mutex unnecessarily, rc=$?"
19709         fi
19710         rm -f $DIR/$tfile
19711
19712 }
19713 run_test 258b "verify i_mutex security behavior"
19714
19715 test_259() {
19716         local file=$DIR/$tfile
19717         local before
19718         local after
19719
19720         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19721
19722         stack_trap "rm -f $file" EXIT
19723
19724         wait_delete_completed
19725         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19726         echo "before: $before"
19727
19728         $LFS setstripe -i 0 -c 1 $file
19729         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19730         sync_all_data
19731         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19732         echo "after write: $after"
19733
19734 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19735         do_facet ost1 $LCTL set_param fail_loc=0x2301
19736         $TRUNCATE $file 0
19737         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19738         echo "after truncate: $after"
19739
19740         stop ost1
19741         do_facet ost1 $LCTL set_param fail_loc=0
19742         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19743         sleep 2
19744         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19745         echo "after restart: $after"
19746         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19747                 error "missing truncate?"
19748
19749         return 0
19750 }
19751 run_test 259 "crash at delayed truncate"
19752
19753 test_260() {
19754 #define OBD_FAIL_MDC_CLOSE               0x806
19755         $LCTL set_param fail_loc=0x80000806
19756         touch $DIR/$tfile
19757
19758 }
19759 run_test 260 "Check mdc_close fail"
19760
19761 ### Data-on-MDT sanity tests ###
19762 test_270a() {
19763         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19764                 skip "Need MDS version at least 2.10.55 for DoM"
19765
19766         # create DoM file
19767         local dom=$DIR/$tdir/dom_file
19768         local tmp=$DIR/$tdir/tmp_file
19769
19770         mkdir -p $DIR/$tdir
19771
19772         # basic checks for DoM component creation
19773         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19774                 error "Can set MDT layout to non-first entry"
19775
19776         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19777                 error "Can define multiple entries as MDT layout"
19778
19779         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19780
19781         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19782         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19783         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19784
19785         local mdtidx=$($LFS getstripe -m $dom)
19786         local mdtname=MDT$(printf %04x $mdtidx)
19787         local facet=mds$((mdtidx + 1))
19788         local space_check=1
19789
19790         # Skip free space checks with ZFS
19791         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19792
19793         # write
19794         sync
19795         local size_tmp=$((65536 * 3))
19796         local mdtfree1=$(do_facet $facet \
19797                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19798
19799         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19800         # check also direct IO along write
19801         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19802         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19803         sync
19804         cmp $tmp $dom || error "file data is different"
19805         [ $(stat -c%s $dom) == $size_tmp ] ||
19806                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19807         if [ $space_check == 1 ]; then
19808                 local mdtfree2=$(do_facet $facet \
19809                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19810
19811                 # increase in usage from by $size_tmp
19812                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19813                         error "MDT free space wrong after write: " \
19814                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19815         fi
19816
19817         # truncate
19818         local size_dom=10000
19819
19820         $TRUNCATE $dom $size_dom
19821         [ $(stat -c%s $dom) == $size_dom ] ||
19822                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19823         if [ $space_check == 1 ]; then
19824                 mdtfree1=$(do_facet $facet \
19825                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19826                 # decrease in usage from $size_tmp to new $size_dom
19827                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19828                   $(((size_tmp - size_dom) / 1024)) ] ||
19829                         error "MDT free space is wrong after truncate: " \
19830                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19831         fi
19832
19833         # append
19834         cat $tmp >> $dom
19835         sync
19836         size_dom=$((size_dom + size_tmp))
19837         [ $(stat -c%s $dom) == $size_dom ] ||
19838                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19839         if [ $space_check == 1 ]; then
19840                 mdtfree2=$(do_facet $facet \
19841                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19842                 # increase in usage by $size_tmp from previous
19843                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19844                         error "MDT free space is wrong after append: " \
19845                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19846         fi
19847
19848         # delete
19849         rm $dom
19850         if [ $space_check == 1 ]; then
19851                 mdtfree1=$(do_facet $facet \
19852                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19853                 # decrease in usage by $size_dom from previous
19854                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
19855                         error "MDT free space is wrong after removal: " \
19856                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
19857         fi
19858
19859         # combined striping
19860         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
19861                 error "Can't create DoM + OST striping"
19862
19863         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
19864         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19865         # check also direct IO along write
19866         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19867         sync
19868         cmp $tmp $dom || error "file data is different"
19869         [ $(stat -c%s $dom) == $size_tmp ] ||
19870                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19871         rm $dom $tmp
19872
19873         return 0
19874 }
19875 run_test 270a "DoM: basic functionality tests"
19876
19877 test_270b() {
19878         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19879                 skip "Need MDS version at least 2.10.55"
19880
19881         local dom=$DIR/$tdir/dom_file
19882         local max_size=1048576
19883
19884         mkdir -p $DIR/$tdir
19885         $LFS setstripe -E $max_size -L mdt $dom
19886
19887         # truncate over the limit
19888         $TRUNCATE $dom $(($max_size + 1)) &&
19889                 error "successful truncate over the maximum size"
19890         # write over the limit
19891         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
19892                 error "successful write over the maximum size"
19893         # append over the limit
19894         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
19895         echo "12345" >> $dom && error "successful append over the maximum size"
19896         rm $dom
19897
19898         return 0
19899 }
19900 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
19901
19902 test_270c() {
19903         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19904                 skip "Need MDS version at least 2.10.55"
19905
19906         mkdir -p $DIR/$tdir
19907         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19908
19909         # check files inherit DoM EA
19910         touch $DIR/$tdir/first
19911         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
19912                 error "bad pattern"
19913         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
19914                 error "bad stripe count"
19915         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
19916                 error "bad stripe size"
19917
19918         # check directory inherits DoM EA and uses it as default
19919         mkdir $DIR/$tdir/subdir
19920         touch $DIR/$tdir/subdir/second
19921         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
19922                 error "bad pattern in sub-directory"
19923         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
19924                 error "bad stripe count in sub-directory"
19925         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
19926                 error "bad stripe size in sub-directory"
19927         return 0
19928 }
19929 run_test 270c "DoM: DoM EA inheritance tests"
19930
19931 test_270d() {
19932         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19933                 skip "Need MDS version at least 2.10.55"
19934
19935         mkdir -p $DIR/$tdir
19936         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19937
19938         # inherit default DoM striping
19939         mkdir $DIR/$tdir/subdir
19940         touch $DIR/$tdir/subdir/f1
19941
19942         # change default directory striping
19943         $LFS setstripe -c 1 $DIR/$tdir/subdir
19944         touch $DIR/$tdir/subdir/f2
19945         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
19946                 error "wrong default striping in file 2"
19947         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
19948                 error "bad pattern in file 2"
19949         return 0
19950 }
19951 run_test 270d "DoM: change striping from DoM to RAID0"
19952
19953 test_270e() {
19954         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19955                 skip "Need MDS version at least 2.10.55"
19956
19957         mkdir -p $DIR/$tdir/dom
19958         mkdir -p $DIR/$tdir/norm
19959         DOMFILES=20
19960         NORMFILES=10
19961         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
19962         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
19963
19964         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
19965         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
19966
19967         # find DoM files by layout
19968         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
19969         [ $NUM -eq  $DOMFILES ] ||
19970                 error "lfs find -L: found $NUM, expected $DOMFILES"
19971         echo "Test 1: lfs find 20 DOM files by layout: OK"
19972
19973         # there should be 1 dir with default DOM striping
19974         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
19975         [ $NUM -eq  1 ] ||
19976                 error "lfs find -L: found $NUM, expected 1 dir"
19977         echo "Test 2: lfs find 1 DOM dir by layout: OK"
19978
19979         # find DoM files by stripe size
19980         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
19981         [ $NUM -eq  $DOMFILES ] ||
19982                 error "lfs find -S: found $NUM, expected $DOMFILES"
19983         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
19984
19985         # find files by stripe offset except DoM files
19986         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
19987         [ $NUM -eq  $NORMFILES ] ||
19988                 error "lfs find -i: found $NUM, expected $NORMFILES"
19989         echo "Test 5: lfs find no DOM files by stripe index: OK"
19990         return 0
19991 }
19992 run_test 270e "DoM: lfs find with DoM files test"
19993
19994 test_270f() {
19995         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19996                 skip "Need MDS version at least 2.10.55"
19997
19998         local mdtname=${FSNAME}-MDT0000-mdtlov
19999         local dom=$DIR/$tdir/dom_file
20000         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20001                                                 lod.$mdtname.dom_stripesize)
20002         local dom_limit=131072
20003
20004         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20005         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20006                                                 lod.$mdtname.dom_stripesize)
20007         [ ${dom_limit} -eq ${dom_current} ] ||
20008                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20009
20010         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20011         $LFS setstripe -d $DIR/$tdir
20012         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20013                 error "Can't set directory default striping"
20014
20015         # exceed maximum stripe size
20016         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20017                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20018         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20019                 error "Able to create DoM component size more than LOD limit"
20020
20021         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20022         dom_current=$(do_facet mds1 $LCTL get_param -n \
20023                                                 lod.$mdtname.dom_stripesize)
20024         [ 0 -eq ${dom_current} ] ||
20025                 error "Can't set zero DoM stripe limit"
20026         rm $dom
20027
20028         # attempt to create DoM file on server with disabled DoM should
20029         # remove DoM entry from layout and be succeed
20030         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20031                 error "Can't create DoM file (DoM is disabled)"
20032         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20033                 error "File has DoM component while DoM is disabled"
20034         rm $dom
20035
20036         # attempt to create DoM file with only DoM stripe should return error
20037         $LFS setstripe -E $dom_limit -L mdt $dom &&
20038                 error "Able to create DoM-only file while DoM is disabled"
20039
20040         # too low values to be aligned with smallest stripe size 64K
20041         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20042         dom_current=$(do_facet mds1 $LCTL get_param -n \
20043                                                 lod.$mdtname.dom_stripesize)
20044         [ 30000 -eq ${dom_current} ] &&
20045                 error "Can set too small DoM stripe limit"
20046
20047         # 64K is a minimal stripe size in Lustre, expect limit of that size
20048         [ 65536 -eq ${dom_current} ] ||
20049                 error "Limit is not set to 64K but ${dom_current}"
20050
20051         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20052         dom_current=$(do_facet mds1 $LCTL get_param -n \
20053                                                 lod.$mdtname.dom_stripesize)
20054         echo $dom_current
20055         [ 2147483648 -eq ${dom_current} ] &&
20056                 error "Can set too large DoM stripe limit"
20057
20058         do_facet mds1 $LCTL set_param -n \
20059                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20060         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20061                 error "Can't create DoM component size after limit change"
20062         do_facet mds1 $LCTL set_param -n \
20063                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20064         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20065                 error "Can't create DoM file after limit decrease"
20066         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20067                 error "Can create big DoM component after limit decrease"
20068         touch ${dom}_def ||
20069                 error "Can't create file with old default layout"
20070
20071         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20072         return 0
20073 }
20074 run_test 270f "DoM: maximum DoM stripe size checks"
20075
20076 test_270g() {
20077         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20078                 skip "Need MDS version at least 2.13.52"
20079         local dom=$DIR/$tdir/$tfile
20080
20081         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20082         local lodname=${FSNAME}-MDT0000-mdtlov
20083
20084         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20085         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20086         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20087         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20088
20089         local dom_limit=1024
20090         local dom_threshold="50%"
20091
20092         $LFS setstripe -d $DIR/$tdir
20093         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20094                 error "Can't set directory default striping"
20095
20096         do_facet mds1 $LCTL set_param -n \
20097                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20098         # set 0 threshold and create DOM file to change tunable stripesize
20099         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20100         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20101                 error "Failed to create $dom file"
20102         # now tunable dom_cur_stripesize should reach maximum
20103         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20104                                         lod.${lodname}.dom_stripesize_cur_kb)
20105         [[ $dom_current == $dom_limit ]] ||
20106                 error "Current DOM stripesize is not maximum"
20107         rm $dom
20108
20109         # set threshold for further tests
20110         do_facet mds1 $LCTL set_param -n \
20111                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20112         echo "DOM threshold is $dom_threshold free space"
20113         local dom_def
20114         local dom_set
20115         # Spoof bfree to exceed threshold
20116         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20117         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20118         for spfree in 40 20 0 15 30 55; do
20119                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20120                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20121                         error "Failed to create $dom file"
20122                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20123                                         lod.${lodname}.dom_stripesize_cur_kb)
20124                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20125                 [[ $dom_def != $dom_current ]] ||
20126                         error "Default stripe size was not changed"
20127                 if [[ $spfree > 0 ]] ; then
20128                         dom_set=$($LFS getstripe -S $dom)
20129                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20130                                 error "DOM component size is still old"
20131                 else
20132                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20133                                 error "DoM component is set with no free space"
20134                 fi
20135                 rm $dom
20136                 dom_current=$dom_def
20137         done
20138 }
20139 run_test 270g "DoM: default DoM stripe size depends on free space"
20140
20141 test_270h() {
20142         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20143                 skip "Need MDS version at least 2.13.53"
20144
20145         local mdtname=${FSNAME}-MDT0000-mdtlov
20146         local dom=$DIR/$tdir/$tfile
20147         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20148
20149         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20150         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20151
20152         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20153         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20154                 error "can't create OST file"
20155         # mirrored file with DOM entry in the second mirror
20156         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20157                 error "can't create mirror with DoM component"
20158
20159         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20160
20161         # DOM component in the middle and has other enries in the same mirror,
20162         # should succeed but lost DoM component
20163         $LFS setstripe --copy=${dom}_1 $dom ||
20164                 error "Can't create file from OST|DOM mirror layout"
20165         # check new file has no DoM layout after all
20166         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20167                 error "File has DoM component while DoM is disabled"
20168 }
20169 run_test 270h "DoM: DoM stripe removal when disabled on server"
20170
20171 test_271a() {
20172         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20173                 skip "Need MDS version at least 2.10.55"
20174
20175         local dom=$DIR/$tdir/dom
20176
20177         mkdir -p $DIR/$tdir
20178
20179         $LFS setstripe -E 1024K -L mdt $dom
20180
20181         lctl set_param -n mdc.*.stats=clear
20182         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20183         cat $dom > /dev/null
20184         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20185         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20186         ls $dom
20187         rm -f $dom
20188 }
20189 run_test 271a "DoM: data is cached for read after write"
20190
20191 test_271b() {
20192         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20193                 skip "Need MDS version at least 2.10.55"
20194
20195         local dom=$DIR/$tdir/dom
20196
20197         mkdir -p $DIR/$tdir
20198
20199         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20200
20201         lctl set_param -n mdc.*.stats=clear
20202         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20203         cancel_lru_locks mdc
20204         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20205         # second stat to check size is cached on client
20206         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20207         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20208         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20209         rm -f $dom
20210 }
20211 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20212
20213 test_271ba() {
20214         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20215                 skip "Need MDS version at least 2.10.55"
20216
20217         local dom=$DIR/$tdir/dom
20218
20219         mkdir -p $DIR/$tdir
20220
20221         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20222
20223         lctl set_param -n mdc.*.stats=clear
20224         lctl set_param -n osc.*.stats=clear
20225         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20226         cancel_lru_locks mdc
20227         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20228         # second stat to check size is cached on client
20229         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20230         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20231         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20232         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20233         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20234         rm -f $dom
20235 }
20236 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20237
20238
20239 get_mdc_stats() {
20240         local mdtidx=$1
20241         local param=$2
20242         local mdt=MDT$(printf %04x $mdtidx)
20243
20244         if [ -z $param ]; then
20245                 lctl get_param -n mdc.*$mdt*.stats
20246         else
20247                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20248         fi
20249 }
20250
20251 test_271c() {
20252         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20253                 skip "Need MDS version at least 2.10.55"
20254
20255         local dom=$DIR/$tdir/dom
20256
20257         mkdir -p $DIR/$tdir
20258
20259         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20260
20261         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20262         local facet=mds$((mdtidx + 1))
20263
20264         cancel_lru_locks mdc
20265         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20266         createmany -o $dom 1000
20267         lctl set_param -n mdc.*.stats=clear
20268         smalliomany -w $dom 1000 200
20269         get_mdc_stats $mdtidx
20270         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20271         # Each file has 1 open, 1 IO enqueues, total 2000
20272         # but now we have also +1 getxattr for security.capability, total 3000
20273         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20274         unlinkmany $dom 1000
20275
20276         cancel_lru_locks mdc
20277         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20278         createmany -o $dom 1000
20279         lctl set_param -n mdc.*.stats=clear
20280         smalliomany -w $dom 1000 200
20281         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20282         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20283         # for OPEN and IO lock.
20284         [ $((enq - enq_2)) -ge 1000 ] ||
20285                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20286         unlinkmany $dom 1000
20287         return 0
20288 }
20289 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20290
20291 cleanup_271def_tests() {
20292         trap 0
20293         rm -f $1
20294 }
20295
20296 test_271d() {
20297         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20298                 skip "Need MDS version at least 2.10.57"
20299
20300         local dom=$DIR/$tdir/dom
20301         local tmp=$TMP/$tfile
20302         trap "cleanup_271def_tests $tmp" EXIT
20303
20304         mkdir -p $DIR/$tdir
20305
20306         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20307
20308         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20309
20310         cancel_lru_locks mdc
20311         dd if=/dev/urandom of=$tmp bs=1000 count=1
20312         dd if=$tmp of=$dom bs=1000 count=1
20313         cancel_lru_locks mdc
20314
20315         cat /etc/hosts >> $tmp
20316         lctl set_param -n mdc.*.stats=clear
20317
20318         # append data to the same file it should update local page
20319         echo "Append to the same page"
20320         cat /etc/hosts >> $dom
20321         local num=$(get_mdc_stats $mdtidx ost_read)
20322         local ra=$(get_mdc_stats $mdtidx req_active)
20323         local rw=$(get_mdc_stats $mdtidx req_waittime)
20324
20325         [ -z $num ] || error "$num READ RPC occured"
20326         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20327         echo "... DONE"
20328
20329         # compare content
20330         cmp $tmp $dom || error "file miscompare"
20331
20332         cancel_lru_locks mdc
20333         lctl set_param -n mdc.*.stats=clear
20334
20335         echo "Open and read file"
20336         cat $dom > /dev/null
20337         local num=$(get_mdc_stats $mdtidx ost_read)
20338         local ra=$(get_mdc_stats $mdtidx req_active)
20339         local rw=$(get_mdc_stats $mdtidx req_waittime)
20340
20341         [ -z $num ] || error "$num READ RPC occured"
20342         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20343         echo "... DONE"
20344
20345         # compare content
20346         cmp $tmp $dom || error "file miscompare"
20347
20348         return 0
20349 }
20350 run_test 271d "DoM: read on open (1K file in reply buffer)"
20351
20352 test_271f() {
20353         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20354                 skip "Need MDS version at least 2.10.57"
20355
20356         local dom=$DIR/$tdir/dom
20357         local tmp=$TMP/$tfile
20358         trap "cleanup_271def_tests $tmp" EXIT
20359
20360         mkdir -p $DIR/$tdir
20361
20362         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20363
20364         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20365
20366         cancel_lru_locks mdc
20367         dd if=/dev/urandom of=$tmp bs=265000 count=1
20368         dd if=$tmp of=$dom bs=265000 count=1
20369         cancel_lru_locks mdc
20370         cat /etc/hosts >> $tmp
20371         lctl set_param -n mdc.*.stats=clear
20372
20373         echo "Append to the same page"
20374         cat /etc/hosts >> $dom
20375         local num=$(get_mdc_stats $mdtidx ost_read)
20376         local ra=$(get_mdc_stats $mdtidx req_active)
20377         local rw=$(get_mdc_stats $mdtidx req_waittime)
20378
20379         [ -z $num ] || error "$num READ RPC occured"
20380         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20381         echo "... DONE"
20382
20383         # compare content
20384         cmp $tmp $dom || error "file miscompare"
20385
20386         cancel_lru_locks mdc
20387         lctl set_param -n mdc.*.stats=clear
20388
20389         echo "Open and read file"
20390         cat $dom > /dev/null
20391         local num=$(get_mdc_stats $mdtidx ost_read)
20392         local ra=$(get_mdc_stats $mdtidx req_active)
20393         local rw=$(get_mdc_stats $mdtidx req_waittime)
20394
20395         [ -z $num ] && num=0
20396         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20397         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20398         echo "... DONE"
20399
20400         # compare content
20401         cmp $tmp $dom || error "file miscompare"
20402
20403         return 0
20404 }
20405 run_test 271f "DoM: read on open (200K file and read tail)"
20406
20407 test_271g() {
20408         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20409                 skip "Skipping due to old client or server version"
20410
20411         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20412         # to get layout
20413         $CHECKSTAT -t file $DIR1/$tfile
20414
20415         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20416         MULTIOP_PID=$!
20417         sleep 1
20418         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20419         $LCTL set_param fail_loc=0x80000314
20420         rm $DIR1/$tfile || error "Unlink fails"
20421         RC=$?
20422         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20423         [ $RC -eq 0 ] || error "Failed write to stale object"
20424 }
20425 run_test 271g "Discard DoM data vs client flush race"
20426
20427 test_272a() {
20428         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20429                 skip "Need MDS version at least 2.11.50"
20430
20431         local dom=$DIR/$tdir/dom
20432         mkdir -p $DIR/$tdir
20433
20434         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20435         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20436                 error "failed to write data into $dom"
20437         local old_md5=$(md5sum $dom)
20438
20439         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20440                 error "failed to migrate to the same DoM component"
20441
20442         local new_md5=$(md5sum $dom)
20443
20444         [ "$old_md5" == "$new_md5" ] ||
20445                 error "md5sum differ: $old_md5, $new_md5"
20446
20447         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20448                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20449 }
20450 run_test 272a "DoM migration: new layout with the same DOM component"
20451
20452 test_272b() {
20453         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20454                 skip "Need MDS version at least 2.11.50"
20455
20456         local dom=$DIR/$tdir/dom
20457         mkdir -p $DIR/$tdir
20458         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20459
20460         local mdtidx=$($LFS getstripe -m $dom)
20461         local mdtname=MDT$(printf %04x $mdtidx)
20462         local facet=mds$((mdtidx + 1))
20463
20464         local mdtfree1=$(do_facet $facet \
20465                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20466         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20467                 error "failed to write data into $dom"
20468         local old_md5=$(md5sum $dom)
20469         cancel_lru_locks mdc
20470         local mdtfree1=$(do_facet $facet \
20471                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20472
20473         $LFS migrate -c2 $dom ||
20474                 error "failed to migrate to the new composite layout"
20475         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20476                 error "MDT stripe was not removed"
20477
20478         cancel_lru_locks mdc
20479         local new_md5=$(md5sum $dom)
20480         [ "$old_md5" == "$new_md5" ] ||
20481                 error "$old_md5 != $new_md5"
20482
20483         # Skip free space checks with ZFS
20484         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20485                 local mdtfree2=$(do_facet $facet \
20486                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20487                 [ $mdtfree2 -gt $mdtfree1 ] ||
20488                         error "MDT space is not freed after migration"
20489         fi
20490         return 0
20491 }
20492 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20493
20494 test_272c() {
20495         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20496                 skip "Need MDS version at least 2.11.50"
20497
20498         local dom=$DIR/$tdir/$tfile
20499         mkdir -p $DIR/$tdir
20500         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20501
20502         local mdtidx=$($LFS getstripe -m $dom)
20503         local mdtname=MDT$(printf %04x $mdtidx)
20504         local facet=mds$((mdtidx + 1))
20505
20506         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20507                 error "failed to write data into $dom"
20508         local old_md5=$(md5sum $dom)
20509         cancel_lru_locks mdc
20510         local mdtfree1=$(do_facet $facet \
20511                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20512
20513         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20514                 error "failed to migrate to the new composite layout"
20515         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20516                 error "MDT stripe was not removed"
20517
20518         cancel_lru_locks mdc
20519         local new_md5=$(md5sum $dom)
20520         [ "$old_md5" == "$new_md5" ] ||
20521                 error "$old_md5 != $new_md5"
20522
20523         # Skip free space checks with ZFS
20524         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20525                 local mdtfree2=$(do_facet $facet \
20526                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20527                 [ $mdtfree2 -gt $mdtfree1 ] ||
20528                         error "MDS space is not freed after migration"
20529         fi
20530         return 0
20531 }
20532 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20533
20534 test_272d() {
20535         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20536                 skip "Need MDS version at least 2.12.55"
20537
20538         local dom=$DIR/$tdir/$tfile
20539         mkdir -p $DIR/$tdir
20540         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20541
20542         local mdtidx=$($LFS getstripe -m $dom)
20543         local mdtname=MDT$(printf %04x $mdtidx)
20544         local facet=mds$((mdtidx + 1))
20545
20546         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20547                 error "failed to write data into $dom"
20548         local old_md5=$(md5sum $dom)
20549         cancel_lru_locks mdc
20550         local mdtfree1=$(do_facet $facet \
20551                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20552
20553         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20554                 error "failed mirroring to the new composite layout"
20555         $LFS mirror resync $dom ||
20556                 error "failed mirror resync"
20557         $LFS mirror split --mirror-id 1 -d $dom ||
20558                 error "failed mirror split"
20559
20560         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20561                 error "MDT stripe was not removed"
20562
20563         cancel_lru_locks mdc
20564         local new_md5=$(md5sum $dom)
20565         [ "$old_md5" == "$new_md5" ] ||
20566                 error "$old_md5 != $new_md5"
20567
20568         # Skip free space checks with ZFS
20569         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20570                 local mdtfree2=$(do_facet $facet \
20571                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20572                 [ $mdtfree2 -gt $mdtfree1 ] ||
20573                         error "MDS space is not freed after DOM mirror deletion"
20574         fi
20575         return 0
20576 }
20577 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20578
20579 test_272e() {
20580         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20581                 skip "Need MDS version at least 2.12.55"
20582
20583         local dom=$DIR/$tdir/$tfile
20584         mkdir -p $DIR/$tdir
20585         $LFS setstripe -c 2 $dom
20586
20587         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20588                 error "failed to write data into $dom"
20589         local old_md5=$(md5sum $dom)
20590         cancel_lru_locks mdc
20591
20592         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20593                 error "failed mirroring to the DOM layout"
20594         $LFS mirror resync $dom ||
20595                 error "failed mirror resync"
20596         $LFS mirror split --mirror-id 1 -d $dom ||
20597                 error "failed mirror split"
20598
20599         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20600                 error "MDT stripe was not removed"
20601
20602         cancel_lru_locks mdc
20603         local new_md5=$(md5sum $dom)
20604         [ "$old_md5" == "$new_md5" ] ||
20605                 error "$old_md5 != $new_md5"
20606
20607         return 0
20608 }
20609 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20610
20611 test_272f() {
20612         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20613                 skip "Need MDS version at least 2.12.55"
20614
20615         local dom=$DIR/$tdir/$tfile
20616         mkdir -p $DIR/$tdir
20617         $LFS setstripe -c 2 $dom
20618
20619         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20620                 error "failed to write data into $dom"
20621         local old_md5=$(md5sum $dom)
20622         cancel_lru_locks mdc
20623
20624         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20625                 error "failed migrating to the DOM file"
20626
20627         cancel_lru_locks mdc
20628         local new_md5=$(md5sum $dom)
20629         [ "$old_md5" != "$new_md5" ] &&
20630                 error "$old_md5 != $new_md5"
20631
20632         return 0
20633 }
20634 run_test 272f "DoM migration: OST-striped file to DOM file"
20635
20636 test_273a() {
20637         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20638                 skip "Need MDS version at least 2.11.50"
20639
20640         # Layout swap cannot be done if either file has DOM component,
20641         # this will never be supported, migration should be used instead
20642
20643         local dom=$DIR/$tdir/$tfile
20644         mkdir -p $DIR/$tdir
20645
20646         $LFS setstripe -c2 ${dom}_plain
20647         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20648         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20649                 error "can swap layout with DoM component"
20650         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20651                 error "can swap layout with DoM component"
20652
20653         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20654         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20655                 error "can swap layout with DoM component"
20656         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20657                 error "can swap layout with DoM component"
20658         return 0
20659 }
20660 run_test 273a "DoM: layout swapping should fail with DOM"
20661
20662 test_275() {
20663         remote_ost_nodsh && skip "remote OST with nodsh"
20664         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20665                 skip "Need OST version >= 2.10.57"
20666
20667         local file=$DIR/$tfile
20668         local oss
20669
20670         oss=$(comma_list $(osts_nodes))
20671
20672         dd if=/dev/urandom of=$file bs=1M count=2 ||
20673                 error "failed to create a file"
20674         cancel_lru_locks osc
20675
20676         #lock 1
20677         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20678                 error "failed to read a file"
20679
20680 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20681         $LCTL set_param fail_loc=0x8000031f
20682
20683         cancel_lru_locks osc &
20684         sleep 1
20685
20686 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20687         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20688         #IO takes another lock, but matches the PENDING one
20689         #and places it to the IO RPC
20690         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20691                 error "failed to read a file with PENDING lock"
20692 }
20693 run_test 275 "Read on a canceled duplicate lock"
20694
20695 test_276() {
20696         remote_ost_nodsh && skip "remote OST with nodsh"
20697         local pid
20698
20699         do_facet ost1 "(while true; do \
20700                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20701                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20702         pid=$!
20703
20704         for LOOP in $(seq 20); do
20705                 stop ost1
20706                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20707         done
20708         kill -9 $pid
20709         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20710                 rm $TMP/sanity_276_pid"
20711 }
20712 run_test 276 "Race between mount and obd_statfs"
20713
20714 test_277() {
20715         $LCTL set_param ldlm.namespaces.*.lru_size=0
20716         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20717         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20718                         grep ^used_mb | awk '{print $2}')
20719         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20720         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20721                 oflag=direct conv=notrunc
20722         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20723                         grep ^used_mb | awk '{print $2}')
20724         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20725 }
20726 run_test 277 "Direct IO shall drop page cache"
20727
20728 test_278() {
20729         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20730         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20731         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20732                 skip "needs the same host for mdt1 mdt2" && return
20733
20734         local pid1
20735         local pid2
20736
20737 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20738         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20739         stop mds2 &
20740         pid2=$!
20741
20742         stop mds1
20743
20744         echo "Starting MDTs"
20745         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20746         wait $pid2
20747 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20748 #will return NULL
20749         do_facet mds2 $LCTL set_param fail_loc=0
20750
20751         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20752         wait_recovery_complete mds2
20753 }
20754 run_test 278 "Race starting MDS between MDTs stop/start"
20755
20756 test_280() {
20757         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20758                 skip "Need MGS version at least 2.13.52"
20759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20760         combined_mgs_mds || skip "needs combined MGS/MDT"
20761
20762         umount_client $MOUNT
20763 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20764         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20765
20766         mount_client $MOUNT &
20767         sleep 1
20768         stop mgs || error "stop mgs failed"
20769         #for a race mgs would crash
20770         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20771         mount_client $MOUNT || error "mount client failed"
20772 }
20773 run_test 280 "Race between MGS umount and client llog processing"
20774
20775 cleanup_test_300() {
20776         trap 0
20777         umask $SAVE_UMASK
20778 }
20779 test_striped_dir() {
20780         local mdt_index=$1
20781         local stripe_count
20782         local stripe_index
20783
20784         mkdir -p $DIR/$tdir
20785
20786         SAVE_UMASK=$(umask)
20787         trap cleanup_test_300 RETURN EXIT
20788
20789         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20790                                                 $DIR/$tdir/striped_dir ||
20791                 error "set striped dir error"
20792
20793         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20794         [ "$mode" = "755" ] || error "expect 755 got $mode"
20795
20796         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20797                 error "getdirstripe failed"
20798         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20799         if [ "$stripe_count" != "2" ]; then
20800                 error "1:stripe_count is $stripe_count, expect 2"
20801         fi
20802         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20803         if [ "$stripe_count" != "2" ]; then
20804                 error "2:stripe_count is $stripe_count, expect 2"
20805         fi
20806
20807         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20808         if [ "$stripe_index" != "$mdt_index" ]; then
20809                 error "stripe_index is $stripe_index, expect $mdt_index"
20810         fi
20811
20812         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20813                 error "nlink error after create striped dir"
20814
20815         mkdir $DIR/$tdir/striped_dir/a
20816         mkdir $DIR/$tdir/striped_dir/b
20817
20818         stat $DIR/$tdir/striped_dir/a ||
20819                 error "create dir under striped dir failed"
20820         stat $DIR/$tdir/striped_dir/b ||
20821                 error "create dir under striped dir failed"
20822
20823         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20824                 error "nlink error after mkdir"
20825
20826         rmdir $DIR/$tdir/striped_dir/a
20827         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20828                 error "nlink error after rmdir"
20829
20830         rmdir $DIR/$tdir/striped_dir/b
20831         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20832                 error "nlink error after rmdir"
20833
20834         chattr +i $DIR/$tdir/striped_dir
20835         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20836                 error "immutable flags not working under striped dir!"
20837         chattr -i $DIR/$tdir/striped_dir
20838
20839         rmdir $DIR/$tdir/striped_dir ||
20840                 error "rmdir striped dir error"
20841
20842         cleanup_test_300
20843
20844         true
20845 }
20846
20847 test_300a() {
20848         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20849                 skip "skipped for lustre < 2.7.0"
20850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20851         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20852
20853         test_striped_dir 0 || error "failed on striped dir on MDT0"
20854         test_striped_dir 1 || error "failed on striped dir on MDT0"
20855 }
20856 run_test 300a "basic striped dir sanity test"
20857
20858 test_300b() {
20859         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20860                 skip "skipped for lustre < 2.7.0"
20861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20862         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20863
20864         local i
20865         local mtime1
20866         local mtime2
20867         local mtime3
20868
20869         test_mkdir $DIR/$tdir || error "mkdir fail"
20870         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20871                 error "set striped dir error"
20872         for i in {0..9}; do
20873                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
20874                 sleep 1
20875                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
20876                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
20877                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
20878                 sleep 1
20879                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
20880                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
20881                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
20882         done
20883         true
20884 }
20885 run_test 300b "check ctime/mtime for striped dir"
20886
20887 test_300c() {
20888         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20889                 skip "skipped for lustre < 2.7.0"
20890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20891         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20892
20893         local file_count
20894
20895         mkdir -p $DIR/$tdir
20896         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
20897                 error "set striped dir error"
20898
20899         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
20900                 error "chown striped dir failed"
20901
20902         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
20903                 error "create 5k files failed"
20904
20905         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
20906
20907         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
20908
20909         rm -rf $DIR/$tdir
20910 }
20911 run_test 300c "chown && check ls under striped directory"
20912
20913 test_300d() {
20914         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20915                 skip "skipped for lustre < 2.7.0"
20916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20917         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20918
20919         local stripe_count
20920         local file
20921
20922         mkdir -p $DIR/$tdir
20923         $LFS setstripe -c 2 $DIR/$tdir
20924
20925         #local striped directory
20926         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20927                 error "set striped dir error"
20928         #look at the directories for debug purposes
20929         ls -l $DIR/$tdir
20930         $LFS getdirstripe $DIR/$tdir
20931         ls -l $DIR/$tdir/striped_dir
20932         $LFS getdirstripe $DIR/$tdir/striped_dir
20933         createmany -o $DIR/$tdir/striped_dir/f 10 ||
20934                 error "create 10 files failed"
20935
20936         #remote striped directory
20937         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
20938                 error "set striped dir error"
20939         #look at the directories for debug purposes
20940         ls -l $DIR/$tdir
20941         $LFS getdirstripe $DIR/$tdir
20942         ls -l $DIR/$tdir/remote_striped_dir
20943         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
20944         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
20945                 error "create 10 files failed"
20946
20947         for file in $(find $DIR/$tdir); do
20948                 stripe_count=$($LFS getstripe -c $file)
20949                 [ $stripe_count -eq 2 ] ||
20950                         error "wrong stripe $stripe_count for $file"
20951         done
20952
20953         rm -rf $DIR/$tdir
20954 }
20955 run_test 300d "check default stripe under striped directory"
20956
20957 test_300e() {
20958         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20959                 skip "Need MDS version at least 2.7.55"
20960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20961         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20962
20963         local stripe_count
20964         local file
20965
20966         mkdir -p $DIR/$tdir
20967
20968         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20969                 error "set striped dir error"
20970
20971         touch $DIR/$tdir/striped_dir/a
20972         touch $DIR/$tdir/striped_dir/b
20973         touch $DIR/$tdir/striped_dir/c
20974
20975         mkdir $DIR/$tdir/striped_dir/dir_a
20976         mkdir $DIR/$tdir/striped_dir/dir_b
20977         mkdir $DIR/$tdir/striped_dir/dir_c
20978
20979         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
20980                 error "set striped adir under striped dir error"
20981
20982         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
20983                 error "set striped bdir under striped dir error"
20984
20985         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
20986                 error "set striped cdir under striped dir error"
20987
20988         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
20989                 error "rename dir under striped dir fails"
20990
20991         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
20992                 error "rename dir under different stripes fails"
20993
20994         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
20995                 error "rename file under striped dir should succeed"
20996
20997         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
20998                 error "rename dir under striped dir should succeed"
20999
21000         rm -rf $DIR/$tdir
21001 }
21002 run_test 300e "check rename under striped directory"
21003
21004 test_300f() {
21005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21006         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21007         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21008                 skip "Need MDS version at least 2.7.55"
21009
21010         local stripe_count
21011         local file
21012
21013         rm -rf $DIR/$tdir
21014         mkdir -p $DIR/$tdir
21015
21016         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21017                 error "set striped dir error"
21018
21019         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21020                 error "set striped dir error"
21021
21022         touch $DIR/$tdir/striped_dir/a
21023         mkdir $DIR/$tdir/striped_dir/dir_a
21024         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21025                 error "create striped dir under striped dir fails"
21026
21027         touch $DIR/$tdir/striped_dir1/b
21028         mkdir $DIR/$tdir/striped_dir1/dir_b
21029         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21030                 error "create striped dir under striped dir fails"
21031
21032         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21033                 error "rename dir under different striped dir should fail"
21034
21035         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21036                 error "rename striped dir under diff striped dir should fail"
21037
21038         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21039                 error "rename file under diff striped dirs fails"
21040
21041         rm -rf $DIR/$tdir
21042 }
21043 run_test 300f "check rename cross striped directory"
21044
21045 test_300_check_default_striped_dir()
21046 {
21047         local dirname=$1
21048         local default_count=$2
21049         local default_index=$3
21050         local stripe_count
21051         local stripe_index
21052         local dir_stripe_index
21053         local dir
21054
21055         echo "checking $dirname $default_count $default_index"
21056         $LFS setdirstripe -D -c $default_count -i $default_index \
21057                                 -t all_char $DIR/$tdir/$dirname ||
21058                 error "set default stripe on striped dir error"
21059         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21060         [ $stripe_count -eq $default_count ] ||
21061                 error "expect $default_count get $stripe_count for $dirname"
21062
21063         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21064         [ $stripe_index -eq $default_index ] ||
21065                 error "expect $default_index get $stripe_index for $dirname"
21066
21067         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21068                                                 error "create dirs failed"
21069
21070         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21071         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21072         for dir in $(find $DIR/$tdir/$dirname/*); do
21073                 stripe_count=$($LFS getdirstripe -c $dir)
21074                 [ $stripe_count -eq $default_count ] ||
21075                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21076                 error "stripe count $default_count != $stripe_count for $dir"
21077
21078                 stripe_index=$($LFS getdirstripe -i $dir)
21079                 [ $default_index -eq -1 ] ||
21080                         [ $stripe_index -eq $default_index ] ||
21081                         error "$stripe_index != $default_index for $dir"
21082
21083                 #check default stripe
21084                 stripe_count=$($LFS getdirstripe -D -c $dir)
21085                 [ $stripe_count -eq $default_count ] ||
21086                 error "default count $default_count != $stripe_count for $dir"
21087
21088                 stripe_index=$($LFS getdirstripe -D -i $dir)
21089                 [ $stripe_index -eq $default_index ] ||
21090                 error "default index $default_index != $stripe_index for $dir"
21091         done
21092         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21093 }
21094
21095 test_300g() {
21096         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21097         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21098                 skip "Need MDS version at least 2.7.55"
21099
21100         local dir
21101         local stripe_count
21102         local stripe_index
21103
21104         mkdir $DIR/$tdir
21105         mkdir $DIR/$tdir/normal_dir
21106
21107         #Checking when client cache stripe index
21108         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21109         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21110                 error "create striped_dir failed"
21111
21112         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21113                 error "create dir0 fails"
21114         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21115         [ $stripe_index -eq 0 ] ||
21116                 error "dir0 expect index 0 got $stripe_index"
21117
21118         mkdir $DIR/$tdir/striped_dir/dir1 ||
21119                 error "create dir1 fails"
21120         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21121         [ $stripe_index -eq 1 ] ||
21122                 error "dir1 expect index 1 got $stripe_index"
21123
21124         #check default stripe count/stripe index
21125         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21126         test_300_check_default_striped_dir normal_dir 1 0
21127         test_300_check_default_striped_dir normal_dir 2 1
21128         test_300_check_default_striped_dir normal_dir 2 -1
21129
21130         #delete default stripe information
21131         echo "delete default stripeEA"
21132         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21133                 error "set default stripe on striped dir error"
21134
21135         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21136         for dir in $(find $DIR/$tdir/normal_dir/*); do
21137                 stripe_count=$($LFS getdirstripe -c $dir)
21138                 [ $stripe_count -eq 0 ] ||
21139                         error "expect 1 get $stripe_count for $dir"
21140                 stripe_index=$($LFS getdirstripe -i $dir)
21141                 [ $stripe_index -eq 0 ] ||
21142                         error "expect 0 get $stripe_index for $dir"
21143         done
21144 }
21145 run_test 300g "check default striped directory for normal directory"
21146
21147 test_300h() {
21148         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21149         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21150                 skip "Need MDS version at least 2.7.55"
21151
21152         local dir
21153         local stripe_count
21154
21155         mkdir $DIR/$tdir
21156         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21157                 error "set striped dir error"
21158
21159         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21160         test_300_check_default_striped_dir striped_dir 1 0
21161         test_300_check_default_striped_dir striped_dir 2 1
21162         test_300_check_default_striped_dir striped_dir 2 -1
21163
21164         #delete default stripe information
21165         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21166                 error "set default stripe on striped dir error"
21167
21168         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21169         for dir in $(find $DIR/$tdir/striped_dir/*); do
21170                 stripe_count=$($LFS getdirstripe -c $dir)
21171                 [ $stripe_count -eq 0 ] ||
21172                         error "expect 1 get $stripe_count for $dir"
21173         done
21174 }
21175 run_test 300h "check default striped directory for striped directory"
21176
21177 test_300i() {
21178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21179         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21180         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21181                 skip "Need MDS version at least 2.7.55"
21182
21183         local stripe_count
21184         local file
21185
21186         mkdir $DIR/$tdir
21187
21188         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21189                 error "set striped dir error"
21190
21191         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21192                 error "create files under striped dir failed"
21193
21194         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21195                 error "set striped hashdir error"
21196
21197         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21198                 error "create dir0 under hash dir failed"
21199         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21200                 error "create dir1 under hash dir failed"
21201
21202         # unfortunately, we need to umount to clear dir layout cache for now
21203         # once we fully implement dir layout, we can drop this
21204         umount_client $MOUNT || error "umount failed"
21205         mount_client $MOUNT || error "mount failed"
21206
21207         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21208         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21209         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21210
21211         #set the stripe to be unknown hash type
21212         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21213         $LCTL set_param fail_loc=0x1901
21214         for ((i = 0; i < 10; i++)); do
21215                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21216                         error "stat f-$i failed"
21217                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21218         done
21219
21220         touch $DIR/$tdir/striped_dir/f0 &&
21221                 error "create under striped dir with unknown hash should fail"
21222
21223         $LCTL set_param fail_loc=0
21224
21225         umount_client $MOUNT || error "umount failed"
21226         mount_client $MOUNT || error "mount failed"
21227
21228         return 0
21229 }
21230 run_test 300i "client handle unknown hash type striped directory"
21231
21232 test_300j() {
21233         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21235         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21236                 skip "Need MDS version at least 2.7.55"
21237
21238         local stripe_count
21239         local file
21240
21241         mkdir $DIR/$tdir
21242
21243         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21244         $LCTL set_param fail_loc=0x1702
21245         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21246                 error "set striped dir error"
21247
21248         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21249                 error "create files under striped dir failed"
21250
21251         $LCTL set_param fail_loc=0
21252
21253         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21254
21255         return 0
21256 }
21257 run_test 300j "test large update record"
21258
21259 test_300k() {
21260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21261         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21262         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21263                 skip "Need MDS version at least 2.7.55"
21264
21265         # this test needs a huge transaction
21266         local kb
21267         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21268              osd*.$FSNAME-MDT0000.kbytestotal")
21269         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21270
21271         local stripe_count
21272         local file
21273
21274         mkdir $DIR/$tdir
21275
21276         #define OBD_FAIL_LARGE_STRIPE   0x1703
21277         $LCTL set_param fail_loc=0x1703
21278         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21279                 error "set striped dir error"
21280         $LCTL set_param fail_loc=0
21281
21282         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21283                 error "getstripeddir fails"
21284         rm -rf $DIR/$tdir/striped_dir ||
21285                 error "unlink striped dir fails"
21286
21287         return 0
21288 }
21289 run_test 300k "test large striped directory"
21290
21291 test_300l() {
21292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21293         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21294         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21295                 skip "Need MDS version at least 2.7.55"
21296
21297         local stripe_index
21298
21299         test_mkdir -p $DIR/$tdir/striped_dir
21300         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21301                         error "chown $RUNAS_ID failed"
21302         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21303                 error "set default striped dir failed"
21304
21305         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21306         $LCTL set_param fail_loc=0x80000158
21307         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21308
21309         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21310         [ $stripe_index -eq 1 ] ||
21311                 error "expect 1 get $stripe_index for $dir"
21312 }
21313 run_test 300l "non-root user to create dir under striped dir with stale layout"
21314
21315 test_300m() {
21316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21317         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21318         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21319                 skip "Need MDS version at least 2.7.55"
21320
21321         mkdir -p $DIR/$tdir/striped_dir
21322         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21323                 error "set default stripes dir error"
21324
21325         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21326
21327         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21328         [ $stripe_count -eq 0 ] ||
21329                         error "expect 0 get $stripe_count for a"
21330
21331         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21332                 error "set default stripes dir error"
21333
21334         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21335
21336         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21337         [ $stripe_count -eq 0 ] ||
21338                         error "expect 0 get $stripe_count for b"
21339
21340         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21341                 error "set default stripes dir error"
21342
21343         mkdir $DIR/$tdir/striped_dir/c &&
21344                 error "default stripe_index is invalid, mkdir c should fails"
21345
21346         rm -rf $DIR/$tdir || error "rmdir fails"
21347 }
21348 run_test 300m "setstriped directory on single MDT FS"
21349
21350 cleanup_300n() {
21351         local list=$(comma_list $(mdts_nodes))
21352
21353         trap 0
21354         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21355 }
21356
21357 test_300n() {
21358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21359         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21360         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21361                 skip "Need MDS version at least 2.7.55"
21362         remote_mds_nodsh && skip "remote MDS with nodsh"
21363
21364         local stripe_index
21365         local list=$(comma_list $(mdts_nodes))
21366
21367         trap cleanup_300n RETURN EXIT
21368         mkdir -p $DIR/$tdir
21369         chmod 777 $DIR/$tdir
21370         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21371                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21372                 error "create striped dir succeeds with gid=0"
21373
21374         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21375         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21376                 error "create striped dir fails with gid=-1"
21377
21378         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21379         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21380                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21381                 error "set default striped dir succeeds with gid=0"
21382
21383
21384         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21385         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21386                 error "set default striped dir fails with gid=-1"
21387
21388
21389         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21390         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21391                                         error "create test_dir fails"
21392         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21393                                         error "create test_dir1 fails"
21394         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21395                                         error "create test_dir2 fails"
21396         cleanup_300n
21397 }
21398 run_test 300n "non-root user to create dir under striped dir with default EA"
21399
21400 test_300o() {
21401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21402         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21403         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21404                 skip "Need MDS version at least 2.7.55"
21405
21406         local numfree1
21407         local numfree2
21408
21409         mkdir -p $DIR/$tdir
21410
21411         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21412         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21413         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21414                 skip "not enough free inodes $numfree1 $numfree2"
21415         fi
21416
21417         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21418         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21419         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21420                 skip "not enough free space $numfree1 $numfree2"
21421         fi
21422
21423         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21424                 error "setdirstripe fails"
21425
21426         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21427                 error "create dirs fails"
21428
21429         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21430         ls $DIR/$tdir/striped_dir > /dev/null ||
21431                 error "ls striped dir fails"
21432         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21433                 error "unlink big striped dir fails"
21434 }
21435 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21436
21437 test_300p() {
21438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21439         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21440         remote_mds_nodsh && skip "remote MDS with nodsh"
21441
21442         mkdir -p $DIR/$tdir
21443
21444         #define OBD_FAIL_OUT_ENOSPC     0x1704
21445         do_facet mds2 lctl set_param fail_loc=0x80001704
21446         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21447                  && error "create striped directory should fail"
21448
21449         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21450
21451         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21452         true
21453 }
21454 run_test 300p "create striped directory without space"
21455
21456 test_300q() {
21457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21458         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21459
21460         local fd=$(free_fd)
21461         local cmd="exec $fd<$tdir"
21462         cd $DIR
21463         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21464         eval $cmd
21465         cmd="exec $fd<&-"
21466         trap "eval $cmd" EXIT
21467         cd $tdir || error "cd $tdir fails"
21468         rmdir  ../$tdir || error "rmdir $tdir fails"
21469         mkdir local_dir && error "create dir succeeds"
21470         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21471         eval $cmd
21472         return 0
21473 }
21474 run_test 300q "create remote directory under orphan directory"
21475
21476 test_300r() {
21477         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21478                 skip "Need MDS version at least 2.7.55" && return
21479         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21480
21481         mkdir $DIR/$tdir
21482
21483         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21484                 error "set striped dir error"
21485
21486         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21487                 error "getstripeddir fails"
21488
21489         local stripe_count
21490         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21491                       awk '/lmv_stripe_count:/ { print $2 }')
21492
21493         [ $MDSCOUNT -ne $stripe_count ] &&
21494                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21495
21496         rm -rf $DIR/$tdir/striped_dir ||
21497                 error "unlink striped dir fails"
21498 }
21499 run_test 300r "test -1 striped directory"
21500
21501 prepare_remote_file() {
21502         mkdir $DIR/$tdir/src_dir ||
21503                 error "create remote source failed"
21504
21505         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21506                  error "cp to remote source failed"
21507         touch $DIR/$tdir/src_dir/a
21508
21509         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21510                 error "create remote target dir failed"
21511
21512         touch $DIR/$tdir/tgt_dir/b
21513
21514         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21515                 error "rename dir cross MDT failed!"
21516
21517         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21518                 error "src_child still exists after rename"
21519
21520         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21521                 error "missing file(a) after rename"
21522
21523         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21524                 error "diff after rename"
21525 }
21526
21527 test_310a() {
21528         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21530
21531         local remote_file=$DIR/$tdir/tgt_dir/b
21532
21533         mkdir -p $DIR/$tdir
21534
21535         prepare_remote_file || error "prepare remote file failed"
21536
21537         #open-unlink file
21538         $OPENUNLINK $remote_file $remote_file ||
21539                 error "openunlink $remote_file failed"
21540         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21541 }
21542 run_test 310a "open unlink remote file"
21543
21544 test_310b() {
21545         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21547
21548         local remote_file=$DIR/$tdir/tgt_dir/b
21549
21550         mkdir -p $DIR/$tdir
21551
21552         prepare_remote_file || error "prepare remote file failed"
21553
21554         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21555         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21556         $CHECKSTAT -t file $remote_file || error "check file failed"
21557 }
21558 run_test 310b "unlink remote file with multiple links while open"
21559
21560 test_310c() {
21561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21562         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21563
21564         local remote_file=$DIR/$tdir/tgt_dir/b
21565
21566         mkdir -p $DIR/$tdir
21567
21568         prepare_remote_file || error "prepare remote file failed"
21569
21570         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21571         multiop_bg_pause $remote_file O_uc ||
21572                         error "mulitop failed for remote file"
21573         MULTIPID=$!
21574         $MULTIOP $DIR/$tfile Ouc
21575         kill -USR1 $MULTIPID
21576         wait $MULTIPID
21577 }
21578 run_test 310c "open-unlink remote file with multiple links"
21579
21580 #LU-4825
21581 test_311() {
21582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21583         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21584         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21585                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21586         remote_mds_nodsh && skip "remote MDS with nodsh"
21587
21588         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21589         local mdts=$(comma_list $(mdts_nodes))
21590
21591         mkdir -p $DIR/$tdir
21592         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21593         createmany -o $DIR/$tdir/$tfile. 1000
21594
21595         # statfs data is not real time, let's just calculate it
21596         old_iused=$((old_iused + 1000))
21597
21598         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21599                         osp.*OST0000*MDT0000.create_count")
21600         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21601                                 osp.*OST0000*MDT0000.max_create_count")
21602         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21603
21604         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21605         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21606         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21607
21608         unlinkmany $DIR/$tdir/$tfile. 1000
21609
21610         do_nodes $mdts "$LCTL set_param -n \
21611                         osp.*OST0000*.max_create_count=$max_count"
21612         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21613                 do_nodes $mdts "$LCTL set_param -n \
21614                                 osp.*OST0000*.create_count=$count"
21615         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21616                         grep "=0" && error "create_count is zero"
21617
21618         local new_iused
21619         for i in $(seq 120); do
21620                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21621                 # system may be too busy to destroy all objs in time, use
21622                 # a somewhat small value to not fail autotest
21623                 [ $((old_iused - new_iused)) -gt 400 ] && break
21624                 sleep 1
21625         done
21626
21627         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21628         [ $((old_iused - new_iused)) -gt 400 ] ||
21629                 error "objs not destroyed after unlink"
21630 }
21631 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21632
21633 zfs_oid_to_objid()
21634 {
21635         local ost=$1
21636         local objid=$2
21637
21638         local vdevdir=$(dirname $(facet_vdevice $ost))
21639         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21640         local zfs_zapid=$(do_facet $ost $cmd |
21641                           grep -w "/O/0/d$((objid%32))" -C 5 |
21642                           awk '/Object/{getline; print $1}')
21643         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21644                           awk "/$objid = /"'{printf $3}')
21645
21646         echo $zfs_objid
21647 }
21648
21649 zfs_object_blksz() {
21650         local ost=$1
21651         local objid=$2
21652
21653         local vdevdir=$(dirname $(facet_vdevice $ost))
21654         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21655         local blksz=$(do_facet $ost $cmd $objid |
21656                       awk '/dblk/{getline; printf $4}')
21657
21658         case "${blksz: -1}" in
21659                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21660                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21661                 *) ;;
21662         esac
21663
21664         echo $blksz
21665 }
21666
21667 test_312() { # LU-4856
21668         remote_ost_nodsh && skip "remote OST with nodsh"
21669         [ "$ost1_FSTYPE" = "zfs" ] ||
21670                 skip_env "the test only applies to zfs"
21671
21672         local max_blksz=$(do_facet ost1 \
21673                           $ZFS get -p recordsize $(facet_device ost1) |
21674                           awk '!/VALUE/{print $3}')
21675
21676         # to make life a little bit easier
21677         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21678         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21679
21680         local tf=$DIR/$tdir/$tfile
21681         touch $tf
21682         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21683
21684         # Get ZFS object id
21685         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21686         # block size change by sequential overwrite
21687         local bs
21688
21689         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21690                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21691
21692                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21693                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21694         done
21695         rm -f $tf
21696
21697         # block size change by sequential append write
21698         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21699         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21700         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21701         local count
21702
21703         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21704                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21705                         oflag=sync conv=notrunc
21706
21707                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21708                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21709                         error "blksz error, actual $blksz, " \
21710                                 "expected: 2 * $count * $PAGE_SIZE"
21711         done
21712         rm -f $tf
21713
21714         # random write
21715         touch $tf
21716         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21717         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21718
21719         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21720         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21721         [ $blksz -eq $PAGE_SIZE ] ||
21722                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21723
21724         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21725         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21726         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21727
21728         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21729         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21730         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21731 }
21732 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21733
21734 test_313() {
21735         remote_ost_nodsh && skip "remote OST with nodsh"
21736
21737         local file=$DIR/$tfile
21738
21739         rm -f $file
21740         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21741
21742         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21743         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21744         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21745                 error "write should failed"
21746         do_facet ost1 "$LCTL set_param fail_loc=0"
21747         rm -f $file
21748 }
21749 run_test 313 "io should fail after last_rcvd update fail"
21750
21751 test_314() {
21752         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21753
21754         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21755         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21756         rm -f $DIR/$tfile
21757         wait_delete_completed
21758         do_facet ost1 "$LCTL set_param fail_loc=0"
21759 }
21760 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21761
21762 test_315() { # LU-618
21763         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21764
21765         local file=$DIR/$tfile
21766         rm -f $file
21767
21768         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21769                 error "multiop file write failed"
21770         $MULTIOP $file oO_RDONLY:r4063232_c &
21771         PID=$!
21772
21773         sleep 2
21774
21775         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21776         kill -USR1 $PID
21777
21778         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21779         rm -f $file
21780 }
21781 run_test 315 "read should be accounted"
21782
21783 test_316() {
21784         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21785         large_xattr_enabled || skip_env "ea_inode feature disabled"
21786
21787         rm -rf $DIR/$tdir/d
21788         mkdir -p $DIR/$tdir/d
21789         chown nobody $DIR/$tdir/d
21790         touch $DIR/$tdir/d/file
21791
21792         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21793 }
21794 run_test 316 "lfs mv"
21795
21796 test_317() {
21797         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21798                 skip "Need MDS version at least 2.11.53"
21799         if [ "$ost1_FSTYPE" == "zfs" ]; then
21800                 skip "LU-10370: no implementation for ZFS"
21801         fi
21802
21803         local trunc_sz
21804         local grant_blk_size
21805
21806         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21807                         awk '/grant_block_size:/ { print $2; exit; }')
21808         #
21809         # Create File of size 5M. Truncate it to below size's and verify
21810         # blocks count.
21811         #
21812         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21813                 error "Create file $DIR/$tfile failed"
21814         stack_trap "rm -f $DIR/$tfile" EXIT
21815
21816         for trunc_sz in 2097152 4097 4000 509 0; do
21817                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21818                         error "truncate $tfile to $trunc_sz failed"
21819                 local sz=$(stat --format=%s $DIR/$tfile)
21820                 local blk=$(stat --format=%b $DIR/$tfile)
21821                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21822                                      grant_blk_size) * 8))
21823
21824                 if [[ $blk -ne $trunc_blk ]]; then
21825                         $(which stat) $DIR/$tfile
21826                         error "Expected Block $trunc_blk got $blk for $tfile"
21827                 fi
21828
21829                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21830                         error "Expected Size $trunc_sz got $sz for $tfile"
21831         done
21832
21833         #
21834         # sparse file test
21835         # Create file with a hole and write actual two blocks. Block count
21836         # must be 16.
21837         #
21838         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21839                 conv=fsync || error "Create file : $DIR/$tfile"
21840
21841         # Calculate the final truncate size.
21842         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21843
21844         #
21845         # truncate to size $trunc_sz bytes. Strip the last block
21846         # The block count must drop to 8
21847         #
21848         $TRUNCATE $DIR/$tfile $trunc_sz ||
21849                 error "truncate $tfile to $trunc_sz failed"
21850
21851         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
21852         sz=$(stat --format=%s $DIR/$tfile)
21853         blk=$(stat --format=%b $DIR/$tfile)
21854
21855         if [[ $blk -ne $trunc_bsz ]]; then
21856                 $(which stat) $DIR/$tfile
21857                 error "Expected Block $trunc_bsz got $blk for $tfile"
21858         fi
21859
21860         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21861                 error "Expected Size $trunc_sz got $sz for $tfile"
21862 }
21863 run_test 317 "Verify blocks get correctly update after truncate"
21864
21865 test_318() {
21866         local old_max_active=$($LCTL get_param -n \
21867                             llite.*.max_read_ahead_async_active 2>/dev/null)
21868
21869         $LCTL set_param llite.*.max_read_ahead_async_active=256
21870         local max_active=$($LCTL get_param -n \
21871                            llite.*.max_read_ahead_async_active 2>/dev/null)
21872         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
21873
21874         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
21875                 error "set max_read_ahead_async_active should succeed"
21876
21877         $LCTL set_param llite.*.max_read_ahead_async_active=512
21878         max_active=$($LCTL get_param -n \
21879                      llite.*.max_read_ahead_async_active 2>/dev/null)
21880         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
21881
21882         # restore @max_active
21883         [ $old_max_active -ne 0 ] && $LCTL set_param \
21884                 llite.*.max_read_ahead_async_active=$old_max_active
21885
21886         local old_threshold=$($LCTL get_param -n \
21887                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21888         local max_per_file_mb=$($LCTL get_param -n \
21889                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
21890
21891         local invalid=$(($max_per_file_mb + 1))
21892         $LCTL set_param \
21893                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
21894                         && error "set $invalid should fail"
21895
21896         local valid=$(($invalid - 1))
21897         $LCTL set_param \
21898                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
21899                         error "set $valid should succeed"
21900         local threshold=$($LCTL get_param -n \
21901                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21902         [ $threshold -eq $valid ] || error \
21903                 "expect threshold $valid got $threshold"
21904         $LCTL set_param \
21905                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
21906 }
21907 run_test 318 "Verify async readahead tunables"
21908
21909 test_319() {
21910         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
21911
21912         local before=$(date +%s)
21913         local evict
21914         local mdir=$DIR/$tdir
21915         local file=$mdir/xxx
21916
21917         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
21918         touch $file
21919
21920 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
21921         $LCTL set_param fail_val=5 fail_loc=0x8000032c
21922         $LFS mv -m1 $file &
21923
21924         sleep 1
21925         dd if=$file of=/dev/null
21926         wait
21927         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
21928           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
21929
21930         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
21931 }
21932 run_test 319 "lost lease lock on migrate error"
21933
21934 test_398a() { # LU-4198
21935         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21936         $LCTL set_param ldlm.namespaces.*.lru_size=clear
21937
21938         # request a new lock on client
21939         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21940
21941         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21942         local lock_count=$($LCTL get_param -n \
21943                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21944         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
21945
21946         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
21947
21948         # no lock cached, should use lockless IO and not enqueue new lock
21949         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21950         lock_count=$($LCTL get_param -n \
21951                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21952         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
21953 }
21954 run_test 398a "direct IO should cancel lock otherwise lockless"
21955
21956 test_398b() { # LU-4198
21957         which fio || skip_env "no fio installed"
21958         $LFS setstripe -c -1 $DIR/$tfile
21959
21960         local size=12
21961         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
21962
21963         local njobs=4
21964         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
21965         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21966                 --numjobs=$njobs --fallocate=none \
21967                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21968                 --filename=$DIR/$tfile &
21969         bg_pid=$!
21970
21971         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
21972         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
21973                 --numjobs=$njobs --fallocate=none \
21974                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21975                 --filename=$DIR/$tfile || true
21976         wait $bg_pid
21977
21978         rm -rf $DIR/$tfile
21979 }
21980 run_test 398b "DIO and buffer IO race"
21981
21982 test_398c() { # LU-4198
21983         which fio || skip_env "no fio installed"
21984
21985         saved_debug=$($LCTL get_param -n debug)
21986         $LCTL set_param debug=0
21987
21988         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
21989         ((size /= 1024)) # by megabytes
21990         ((size /= 2)) # write half of the OST at most
21991         [ $size -gt 40 ] && size=40 #reduce test time anyway
21992
21993         $LFS setstripe -c 1 $DIR/$tfile
21994
21995         # it seems like ldiskfs reserves more space than necessary if the
21996         # writing blocks are not mapped, so it extends the file firstly
21997         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
21998         cancel_lru_locks osc
21999
22000         # clear and verify rpc_stats later
22001         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22002
22003         local njobs=4
22004         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22005         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22006                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22007                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22008                 --filename=$DIR/$tfile
22009         [ $? -eq 0 ] || error "fio write error"
22010
22011         [ $($LCTL get_param -n \
22012          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22013                 error "Locks were requested while doing AIO"
22014
22015         # get the percentage of 1-page I/O
22016         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22017                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22018                 awk '{print $7}')
22019         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22020
22021         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22022         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22023                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22024                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22025                 --filename=$DIR/$tfile
22026         [ $? -eq 0 ] || error "fio mixed read write error"
22027
22028         echo "AIO with large block size ${size}M"
22029         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22030                 --numjobs=1 --fallocate=none --ioengine=libaio \
22031                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22032                 --filename=$DIR/$tfile
22033         [ $? -eq 0 ] || error "fio large block size failed"
22034
22035         rm -rf $DIR/$tfile
22036         $LCTL set_param debug="$saved_debug"
22037 }
22038 run_test 398c "run fio to test AIO"
22039
22040 test_398d() { #  LU-13846
22041         test -f aiocp || skip_env "no aiocp installed"
22042         local aio_file=$DIR/aio_file
22043
22044         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22045
22046         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22047         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22048
22049         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22050
22051         # make sure we don't crash and fail properly
22052         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22053                 error "aio not aligned with PAGE SIZE should fail"
22054
22055         rm -rf $DIR/$tfile $aio_file
22056 }
22057 run_test 398d "run aiocp to verify block size > stripe size"
22058
22059 test_fake_rw() {
22060         local read_write=$1
22061         if [ "$read_write" = "write" ]; then
22062                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22063         elif [ "$read_write" = "read" ]; then
22064                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22065         else
22066                 error "argument error"
22067         fi
22068
22069         # turn off debug for performance testing
22070         local saved_debug=$($LCTL get_param -n debug)
22071         $LCTL set_param debug=0
22072
22073         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22074
22075         # get ost1 size - $FSNAME-OST0000
22076         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22077         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22078         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22079
22080         if [ "$read_write" = "read" ]; then
22081                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
22082         fi
22083
22084         local start_time=$(date +%s.%N)
22085         $dd_cmd bs=1M count=$blocks oflag=sync ||
22086                 error "real dd $read_write error"
22087         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22088
22089         if [ "$read_write" = "write" ]; then
22090                 rm -f $DIR/$tfile
22091         fi
22092
22093         # define OBD_FAIL_OST_FAKE_RW           0x238
22094         do_facet ost1 $LCTL set_param fail_loc=0x238
22095
22096         local start_time=$(date +%s.%N)
22097         $dd_cmd bs=1M count=$blocks oflag=sync ||
22098                 error "fake dd $read_write error"
22099         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22100
22101         if [ "$read_write" = "write" ]; then
22102                 # verify file size
22103                 cancel_lru_locks osc
22104                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22105                         error "$tfile size not $blocks MB"
22106         fi
22107         do_facet ost1 $LCTL set_param fail_loc=0
22108
22109         echo "fake $read_write $duration_fake vs. normal $read_write" \
22110                 "$duration in seconds"
22111         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22112                 error_not_in_vm "fake write is slower"
22113
22114         $LCTL set_param -n debug="$saved_debug"
22115         rm -f $DIR/$tfile
22116 }
22117 test_399a() { # LU-7655 for OST fake write
22118         remote_ost_nodsh && skip "remote OST with nodsh"
22119
22120         test_fake_rw write
22121 }
22122 run_test 399a "fake write should not be slower than normal write"
22123
22124 test_399b() { # LU-8726 for OST fake read
22125         remote_ost_nodsh && skip "remote OST with nodsh"
22126         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22127                 skip_env "ldiskfs only test"
22128         fi
22129
22130         test_fake_rw read
22131 }
22132 run_test 399b "fake read should not be slower than normal read"
22133
22134 test_400a() { # LU-1606, was conf-sanity test_74
22135         if ! which $CC > /dev/null 2>&1; then
22136                 skip_env "$CC is not installed"
22137         fi
22138
22139         local extra_flags=''
22140         local out=$TMP/$tfile
22141         local prefix=/usr/include/lustre
22142         local prog
22143
22144         # Oleg removes c files in his test rig so test if any c files exist
22145         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22146                 skip_env "Needed c test files are missing"
22147
22148         if ! [[ -d $prefix ]]; then
22149                 # Assume we're running in tree and fixup the include path.
22150                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22151                 extra_flags+=" -L$LUSTRE/utils/.lib"
22152         fi
22153
22154         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22155                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22156                         error "client api broken"
22157         done
22158         rm -f $out
22159 }
22160 run_test 400a "Lustre client api program can compile and link"
22161
22162 test_400b() { # LU-1606, LU-5011
22163         local header
22164         local out=$TMP/$tfile
22165         local prefix=/usr/include/linux/lustre
22166
22167         # We use a hard coded prefix so that this test will not fail
22168         # when run in tree. There are headers in lustre/include/lustre/
22169         # that are not packaged (like lustre_idl.h) and have more
22170         # complicated include dependencies (like config.h and lnet/types.h).
22171         # Since this test about correct packaging we just skip them when
22172         # they don't exist (see below) rather than try to fixup cppflags.
22173
22174         if ! which $CC > /dev/null 2>&1; then
22175                 skip_env "$CC is not installed"
22176         fi
22177
22178         for header in $prefix/*.h; do
22179                 if ! [[ -f "$header" ]]; then
22180                         continue
22181                 fi
22182
22183                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22184                         continue # lustre_ioctl.h is internal header
22185                 fi
22186
22187                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22188                         error "cannot compile '$header'"
22189         done
22190         rm -f $out
22191 }
22192 run_test 400b "packaged headers can be compiled"
22193
22194 test_401a() { #LU-7437
22195         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22196         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22197
22198         #count the number of parameters by "list_param -R"
22199         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22200         #count the number of parameters by listing proc files
22201         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22202         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22203         echo "proc_dirs='$proc_dirs'"
22204         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22205         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22206                       sort -u | wc -l)
22207
22208         [ $params -eq $procs ] ||
22209                 error "found $params parameters vs. $procs proc files"
22210
22211         # test the list_param -D option only returns directories
22212         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22213         #count the number of parameters by listing proc directories
22214         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22215                 sort -u | wc -l)
22216
22217         [ $params -eq $procs ] ||
22218                 error "found $params parameters vs. $procs proc files"
22219 }
22220 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22221
22222 test_401b() {
22223         local save=$($LCTL get_param -n jobid_var)
22224         local tmp=testing
22225
22226         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
22227                 error "no error returned when setting bad parameters"
22228
22229         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
22230         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22231
22232         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
22233         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
22234         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22235 }
22236 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22237
22238 test_401c() {
22239         local jobid_var_old=$($LCTL get_param -n jobid_var)
22240         local jobid_var_new
22241
22242         $LCTL set_param jobid_var= &&
22243                 error "no error returned for 'set_param a='"
22244
22245         jobid_var_new=$($LCTL get_param -n jobid_var)
22246         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22247                 error "jobid_var was changed by setting without value"
22248
22249         $LCTL set_param jobid_var &&
22250                 error "no error returned for 'set_param a'"
22251
22252         jobid_var_new=$($LCTL get_param -n jobid_var)
22253         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22254                 error "jobid_var was changed by setting without value"
22255 }
22256 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22257
22258 test_401d() {
22259         local jobid_var_old=$($LCTL get_param -n jobid_var)
22260         local jobid_var_new
22261         local new_value="foo=bar"
22262
22263         $LCTL set_param jobid_var=$new_value ||
22264                 error "'set_param a=b' did not accept a value containing '='"
22265
22266         jobid_var_new=$($LCTL get_param -n jobid_var)
22267         [[ "$jobid_var_new" == "$new_value" ]] ||
22268                 error "'set_param a=b' failed on a value containing '='"
22269
22270         # Reset the jobid_var to test the other format
22271         $LCTL set_param jobid_var=$jobid_var_old
22272         jobid_var_new=$($LCTL get_param -n jobid_var)
22273         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22274                 error "failed to reset jobid_var"
22275
22276         $LCTL set_param jobid_var $new_value ||
22277                 error "'set_param a b' did not accept a value containing '='"
22278
22279         jobid_var_new=$($LCTL get_param -n jobid_var)
22280         [[ "$jobid_var_new" == "$new_value" ]] ||
22281                 error "'set_param a b' failed on a value containing '='"
22282
22283         $LCTL set_param jobid_var $jobid_var_old
22284         jobid_var_new=$($LCTL get_param -n jobid_var)
22285         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22286                 error "failed to reset jobid_var"
22287 }
22288 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22289
22290 test_402() {
22291         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22292         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22293                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22294         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22295                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22296                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22297         remote_mds_nodsh && skip "remote MDS with nodsh"
22298
22299         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22300 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22301         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22302         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22303                 echo "Touch failed - OK"
22304 }
22305 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22306
22307 test_403() {
22308         local file1=$DIR/$tfile.1
22309         local file2=$DIR/$tfile.2
22310         local tfile=$TMP/$tfile
22311
22312         rm -f $file1 $file2 $tfile
22313
22314         touch $file1
22315         ln $file1 $file2
22316
22317         # 30 sec OBD_TIMEOUT in ll_getattr()
22318         # right before populating st_nlink
22319         $LCTL set_param fail_loc=0x80001409
22320         stat -c %h $file1 > $tfile &
22321
22322         # create an alias, drop all locks and reclaim the dentry
22323         < $file2
22324         cancel_lru_locks mdc
22325         cancel_lru_locks osc
22326         sysctl -w vm.drop_caches=2
22327
22328         wait
22329
22330         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22331
22332         rm -f $tfile $file1 $file2
22333 }
22334 run_test 403 "i_nlink should not drop to zero due to aliasing"
22335
22336 test_404() { # LU-6601
22337         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22338                 skip "Need server version newer than 2.8.52"
22339         remote_mds_nodsh && skip "remote MDS with nodsh"
22340
22341         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22342                 awk '/osp .*-osc-MDT/ { print $4}')
22343
22344         local osp
22345         for osp in $mosps; do
22346                 echo "Deactivate: " $osp
22347                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22348                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22349                         awk -vp=$osp '$4 == p { print $2 }')
22350                 [ $stat = IN ] || {
22351                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22352                         error "deactivate error"
22353                 }
22354                 echo "Activate: " $osp
22355                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22356                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22357                         awk -vp=$osp '$4 == p { print $2 }')
22358                 [ $stat = UP ] || {
22359                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22360                         error "activate error"
22361                 }
22362         done
22363 }
22364 run_test 404 "validate manual {de}activated works properly for OSPs"
22365
22366 test_405() {
22367         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22368         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22369                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22370                         skip "Layout swap lock is not supported"
22371
22372         check_swap_layouts_support
22373         check_swap_layout_no_dom $DIR
22374
22375         test_mkdir $DIR/$tdir
22376         swap_lock_test -d $DIR/$tdir ||
22377                 error "One layout swap locked test failed"
22378 }
22379 run_test 405 "Various layout swap lock tests"
22380
22381 test_406() {
22382         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22383         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22384         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22386         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22387                 skip "Need MDS version at least 2.8.50"
22388
22389         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22390         local test_pool=$TESTNAME
22391
22392         pool_add $test_pool || error "pool_add failed"
22393         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22394                 error "pool_add_targets failed"
22395
22396         save_layout_restore_at_exit $MOUNT
22397
22398         # parent set default stripe count only, child will stripe from both
22399         # parent and fs default
22400         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22401                 error "setstripe $MOUNT failed"
22402         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22403         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22404         for i in $(seq 10); do
22405                 local f=$DIR/$tdir/$tfile.$i
22406                 touch $f || error "touch failed"
22407                 local count=$($LFS getstripe -c $f)
22408                 [ $count -eq $OSTCOUNT ] ||
22409                         error "$f stripe count $count != $OSTCOUNT"
22410                 local offset=$($LFS getstripe -i $f)
22411                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22412                 local size=$($LFS getstripe -S $f)
22413                 [ $size -eq $((def_stripe_size * 2)) ] ||
22414                         error "$f stripe size $size != $((def_stripe_size * 2))"
22415                 local pool=$($LFS getstripe -p $f)
22416                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22417         done
22418
22419         # change fs default striping, delete parent default striping, now child
22420         # will stripe from new fs default striping only
22421         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22422                 error "change $MOUNT default stripe failed"
22423         $LFS setstripe -c 0 $DIR/$tdir ||
22424                 error "delete $tdir default stripe failed"
22425         for i in $(seq 11 20); do
22426                 local f=$DIR/$tdir/$tfile.$i
22427                 touch $f || error "touch $f failed"
22428                 local count=$($LFS getstripe -c $f)
22429                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22430                 local offset=$($LFS getstripe -i $f)
22431                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22432                 local size=$($LFS getstripe -S $f)
22433                 [ $size -eq $def_stripe_size ] ||
22434                         error "$f stripe size $size != $def_stripe_size"
22435                 local pool=$($LFS getstripe -p $f)
22436                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22437         done
22438
22439         unlinkmany $DIR/$tdir/$tfile. 1 20
22440
22441         local f=$DIR/$tdir/$tfile
22442         pool_remove_all_targets $test_pool $f
22443         pool_remove $test_pool $f
22444 }
22445 run_test 406 "DNE support fs default striping"
22446
22447 test_407() {
22448         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22449         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22450                 skip "Need MDS version at least 2.8.55"
22451         remote_mds_nodsh && skip "remote MDS with nodsh"
22452
22453         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22454                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22455         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22456                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22457         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22458
22459         #define OBD_FAIL_DT_TXN_STOP    0x2019
22460         for idx in $(seq $MDSCOUNT); do
22461                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22462         done
22463         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22464         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22465                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22466         true
22467 }
22468 run_test 407 "transaction fail should cause operation fail"
22469
22470 test_408() {
22471         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22472
22473         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22474         lctl set_param fail_loc=0x8000040a
22475         # let ll_prepare_partial_page() fail
22476         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22477
22478         rm -f $DIR/$tfile
22479
22480         # create at least 100 unused inodes so that
22481         # shrink_icache_memory(0) should not return 0
22482         touch $DIR/$tfile-{0..100}
22483         rm -f $DIR/$tfile-{0..100}
22484         sync
22485
22486         echo 2 > /proc/sys/vm/drop_caches
22487 }
22488 run_test 408 "drop_caches should not hang due to page leaks"
22489
22490 test_409()
22491 {
22492         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22493
22494         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22495         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22496         touch $DIR/$tdir/guard || error "(2) Fail to create"
22497
22498         local PREFIX=$(str_repeat 'A' 128)
22499         echo "Create 1K hard links start at $(date)"
22500         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22501                 error "(3) Fail to hard link"
22502
22503         echo "Links count should be right although linkEA overflow"
22504         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22505         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22506         [ $linkcount -eq 1001 ] ||
22507                 error "(5) Unexpected hard links count: $linkcount"
22508
22509         echo "List all links start at $(date)"
22510         ls -l $DIR/$tdir/foo > /dev/null ||
22511                 error "(6) Fail to list $DIR/$tdir/foo"
22512
22513         echo "Unlink hard links start at $(date)"
22514         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22515                 error "(7) Fail to unlink"
22516         echo "Unlink hard links finished at $(date)"
22517 }
22518 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22519
22520 test_410()
22521 {
22522         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22523                 skip "Need client version at least 2.9.59"
22524         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22525                 skip "Need MODULES build"
22526
22527         # Create a file, and stat it from the kernel
22528         local testfile=$DIR/$tfile
22529         touch $testfile
22530
22531         local run_id=$RANDOM
22532         local my_ino=$(stat --format "%i" $testfile)
22533
22534         # Try to insert the module. This will always fail as the
22535         # module is designed to not be inserted.
22536         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22537             &> /dev/null
22538
22539         # Anything but success is a test failure
22540         dmesg | grep -q \
22541             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22542             error "no inode match"
22543 }
22544 run_test 410 "Test inode number returned from kernel thread"
22545
22546 cleanup_test411_cgroup() {
22547         trap 0
22548         rmdir "$1"
22549 }
22550
22551 test_411() {
22552         local cg_basedir=/sys/fs/cgroup/memory
22553         # LU-9966
22554         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22555                 skip "no setup for cgroup"
22556
22557         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22558                 error "test file creation failed"
22559         cancel_lru_locks osc
22560
22561         # Create a very small memory cgroup to force a slab allocation error
22562         local cgdir=$cg_basedir/osc_slab_alloc
22563         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22564         trap "cleanup_test411_cgroup $cgdir" EXIT
22565         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22566         echo 1M > $cgdir/memory.limit_in_bytes
22567
22568         # Should not LBUG, just be killed by oom-killer
22569         # dd will return 0 even allocation failure in some environment.
22570         # So don't check return value
22571         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22572         cleanup_test411_cgroup $cgdir
22573
22574         return 0
22575 }
22576 run_test 411 "Slab allocation error with cgroup does not LBUG"
22577
22578 test_412() {
22579         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22580         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22581                 skip "Need server version at least 2.10.55"
22582         fi
22583
22584         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22585                 error "mkdir failed"
22586         $LFS getdirstripe $DIR/$tdir
22587         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22588         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22589                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22590         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22591         [ $stripe_count -eq 2 ] ||
22592                 error "expect 2 get $stripe_count"
22593 }
22594 run_test 412 "mkdir on specific MDTs"
22595
22596 test_qos_mkdir() {
22597         local mkdir_cmd=$1
22598         local stripe_count=$2
22599         local mdts=$(comma_list $(mdts_nodes))
22600
22601         local testdir
22602         local lmv_qos_prio_free
22603         local lmv_qos_threshold_rr
22604         local lmv_qos_maxage
22605         local lod_qos_prio_free
22606         local lod_qos_threshold_rr
22607         local lod_qos_maxage
22608         local count
22609         local i
22610
22611         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22612         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22613         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22614                 head -n1)
22615         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22616         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22617         stack_trap "$LCTL set_param \
22618                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22619         stack_trap "$LCTL set_param \
22620                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22621         stack_trap "$LCTL set_param \
22622                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22623
22624         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22625                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22626         lod_qos_prio_free=${lod_qos_prio_free%%%}
22627         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22628                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22629         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22630         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22631                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22632         stack_trap "do_nodes $mdts $LCTL set_param \
22633                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22634         stack_trap "do_nodes $mdts $LCTL set_param \
22635                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22636                 EXIT
22637         stack_trap "do_nodes $mdts $LCTL set_param \
22638                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22639
22640         echo
22641         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22642
22643         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22644         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22645
22646         testdir=$DIR/$tdir-s$stripe_count/rr
22647
22648         for i in $(seq $((100 * MDSCOUNT))); do
22649                 eval $mkdir_cmd $testdir/subdir$i ||
22650                         error "$mkdir_cmd subdir$i failed"
22651         done
22652
22653         for i in $(seq $MDSCOUNT); do
22654                 count=$($LFS getdirstripe -i $testdir/* |
22655                                 grep ^$((i - 1))$ | wc -l)
22656                 echo "$count directories created on MDT$((i - 1))"
22657                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22658
22659                 if [ $stripe_count -gt 1 ]; then
22660                         count=$($LFS getdirstripe $testdir/* |
22661                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22662                         echo "$count stripes created on MDT$((i - 1))"
22663                         # deviation should < 5% of average
22664                         [ $count -lt $((95 * stripe_count)) ] ||
22665                         [ $count -gt $((105 * stripe_count)) ] &&
22666                                 error "stripes are not evenly distributed"
22667                 fi
22668         done
22669
22670         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22671         do_nodes $mdts $LCTL set_param \
22672                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22673
22674         echo
22675         echo "Check for uneven MDTs: "
22676
22677         local ffree
22678         local bavail
22679         local max
22680         local min
22681         local max_index
22682         local min_index
22683         local tmp
22684
22685         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22686         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22687         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22688
22689         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22690         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22691         max_index=0
22692         min_index=0
22693         for ((i = 1; i < ${#ffree[@]}; i++)); do
22694                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22695                 if [ $tmp -gt $max ]; then
22696                         max=$tmp
22697                         max_index=$i
22698                 fi
22699                 if [ $tmp -lt $min ]; then
22700                         min=$tmp
22701                         min_index=$i
22702                 fi
22703         done
22704
22705         [ ${ffree[min_index]} -eq 0 ] &&
22706                 skip "no free files in MDT$min_index"
22707         [ ${ffree[min_index]} -gt 100000000 ] &&
22708                 skip "too much free files in MDT$min_index"
22709
22710         # Check if we need to generate uneven MDTs
22711         local threshold=50
22712         local diff=$(((max - min) * 100 / min))
22713         local value="$(generate_string 1024)"
22714
22715         while [ $diff -lt $threshold ]; do
22716                 # generate uneven MDTs, create till $threshold% diff
22717                 echo -n "weight diff=$diff% must be > $threshold% ..."
22718                 count=$((${ffree[min_index]} / 10))
22719                 # 50 sec per 10000 files in vm
22720                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22721                         skip "$count files to create"
22722                 echo "Fill MDT$min_index with $count files"
22723                 [ -d $DIR/$tdir-MDT$min_index ] ||
22724                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22725                         error "mkdir $tdir-MDT$min_index failed"
22726                 for i in $(seq $count); do
22727                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22728                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22729                                 error "create f$j_$i failed"
22730                         setfattr -n user.413b -v $value \
22731                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22732                                 error "setfattr f$j_$i failed"
22733                 done
22734
22735                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22736                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22737                 max=$(((${ffree[max_index]} >> 8) * \
22738                         (${bavail[max_index]} * bsize >> 16)))
22739                 min=$(((${ffree[min_index]} >> 8) * \
22740                         (${bavail[min_index]} * bsize >> 16)))
22741                 diff=$(((max - min) * 100 / min))
22742         done
22743
22744         echo "MDT filesfree available: ${ffree[@]}"
22745         echo "MDT blocks available: ${bavail[@]}"
22746         echo "weight diff=$diff%"
22747
22748         echo
22749         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22750
22751         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22752         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22753         # decrease statfs age, so that it can be updated in time
22754         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22755         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22756
22757         sleep 1
22758
22759         testdir=$DIR/$tdir-s$stripe_count/qos
22760
22761         for i in $(seq $((100 * MDSCOUNT))); do
22762                 eval $mkdir_cmd $testdir/subdir$i ||
22763                         error "$mkdir_cmd subdir$i failed"
22764         done
22765
22766         for i in $(seq $MDSCOUNT); do
22767                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22768                         wc -l)
22769                 echo "$count directories created on MDT$((i - 1))"
22770
22771                 if [ $stripe_count -gt 1 ]; then
22772                         count=$($LFS getdirstripe $testdir/* |
22773                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22774                         echo "$count stripes created on MDT$((i - 1))"
22775                 fi
22776         done
22777
22778         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
22779         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22780
22781         # D-value should > 10% of averge
22782         [ $((max - min)) -lt 10 ] &&
22783                 error "subdirs shouldn't be evenly distributed"
22784
22785         # ditto
22786         if [ $stripe_count -gt 1 ]; then
22787                 max=$($LFS getdirstripe $testdir/* |
22788                         grep -P "^\s+$max_index\t" | wc -l)
22789                 min=$($LFS getdirstripe $testdir/* |
22790                         grep -P "^\s+$min_index\t" | wc -l)
22791                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22792                         error "stripes shouldn't be evenly distributed"|| true
22793         fi
22794 }
22795
22796 test_413a() {
22797         [ $MDSCOUNT -lt 2 ] &&
22798                 skip "We need at least 2 MDTs for this test"
22799
22800         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22801                 skip "Need server version at least 2.12.52"
22802
22803         local stripe_count
22804
22805         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22806                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22807                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22808                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22809                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22810         done
22811 }
22812 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22813
22814 test_413b() {
22815         [ $MDSCOUNT -lt 2 ] &&
22816                 skip "We need at least 2 MDTs for this test"
22817
22818         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22819                 skip "Need server version at least 2.12.52"
22820
22821         local stripe_count
22822
22823         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22824                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22825                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22826                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22827                 $LFS setdirstripe -D -c $stripe_count \
22828                         $DIR/$tdir-s$stripe_count/rr ||
22829                         error "setdirstripe failed"
22830                 $LFS setdirstripe -D -c $stripe_count \
22831                         $DIR/$tdir-s$stripe_count/qos ||
22832                         error "setdirstripe failed"
22833                 test_qos_mkdir "mkdir" $stripe_count
22834         done
22835 }
22836 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
22837
22838 test_414() {
22839 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
22840         $LCTL set_param fail_loc=0x80000521
22841         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
22842         rm -f $DIR/$tfile
22843 }
22844 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
22845
22846 test_415() {
22847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22848         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22849                 skip "Need server version at least 2.11.52"
22850
22851         # LU-11102
22852         local total
22853         local setattr_pid
22854         local start_time
22855         local end_time
22856         local duration
22857
22858         total=500
22859         # this test may be slow on ZFS
22860         [ "$mds1_FSTYPE" == "zfs" ] && total=100
22861
22862         # though this test is designed for striped directory, let's test normal
22863         # directory too since lock is always saved as CoS lock.
22864         test_mkdir $DIR/$tdir || error "mkdir $tdir"
22865         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
22866
22867         (
22868                 while true; do
22869                         touch $DIR/$tdir
22870                 done
22871         ) &
22872         setattr_pid=$!
22873
22874         start_time=$(date +%s)
22875         for i in $(seq $total); do
22876                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
22877                         > /dev/null
22878         done
22879         end_time=$(date +%s)
22880         duration=$((end_time - start_time))
22881
22882         kill -9 $setattr_pid
22883
22884         echo "rename $total files took $duration sec"
22885         [ $duration -lt 100 ] || error "rename took $duration sec"
22886 }
22887 run_test 415 "lock revoke is not missing"
22888
22889 test_416() {
22890         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22891                 skip "Need server version at least 2.11.55"
22892
22893         # define OBD_FAIL_OSD_TXN_START    0x19a
22894         do_facet mds1 lctl set_param fail_loc=0x19a
22895
22896         lfs mkdir -c $MDSCOUNT $DIR/$tdir
22897
22898         true
22899 }
22900 run_test 416 "transaction start failure won't cause system hung"
22901
22902 cleanup_417() {
22903         trap 0
22904         do_nodes $(comma_list $(mdts_nodes)) \
22905                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
22906         do_nodes $(comma_list $(mdts_nodes)) \
22907                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
22908         do_nodes $(comma_list $(mdts_nodes)) \
22909                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
22910 }
22911
22912 test_417() {
22913         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22914         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
22915                 skip "Need MDS version at least 2.11.56"
22916
22917         trap cleanup_417 RETURN EXIT
22918
22919         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
22920         do_nodes $(comma_list $(mdts_nodes)) \
22921                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
22922         $LFS migrate -m 0 $DIR/$tdir.1 &&
22923                 error "migrate dir $tdir.1 should fail"
22924
22925         do_nodes $(comma_list $(mdts_nodes)) \
22926                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
22927         $LFS mkdir -i 1 $DIR/$tdir.2 &&
22928                 error "create remote dir $tdir.2 should fail"
22929
22930         do_nodes $(comma_list $(mdts_nodes)) \
22931                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
22932         $LFS mkdir -c 2 $DIR/$tdir.3 &&
22933                 error "create striped dir $tdir.3 should fail"
22934         true
22935 }
22936 run_test 417 "disable remote dir, striped dir and dir migration"
22937
22938 # Checks that the outputs of df [-i] and lfs df [-i] match
22939 #
22940 # usage: check_lfs_df <blocks | inodes> <mountpoint>
22941 check_lfs_df() {
22942         local dir=$2
22943         local inodes
22944         local df_out
22945         local lfs_df_out
22946         local count
22947         local passed=false
22948
22949         # blocks or inodes
22950         [ "$1" == "blocks" ] && inodes= || inodes="-i"
22951
22952         for count in {1..100}; do
22953                 cancel_lru_locks
22954                 sync; sleep 0.2
22955
22956                 # read the lines of interest
22957                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
22958                         error "df $inodes $dir | tail -n +2 failed"
22959                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
22960                         error "lfs df $inodes $dir | grep summary: failed"
22961
22962                 # skip first substrings of each output as they are different
22963                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
22964                 # compare the two outputs
22965                 passed=true
22966                 for i in {1..5}; do
22967                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
22968                 done
22969                 $passed && break
22970         done
22971
22972         if ! $passed; then
22973                 df -P $inodes $dir
22974                 echo
22975                 lfs df $inodes $dir
22976                 error "df and lfs df $1 output mismatch: "      \
22977                       "df ${inodes}: ${df_out[*]}, "            \
22978                       "lfs df ${inodes}: ${lfs_df_out[*]}"
22979         fi
22980 }
22981
22982 test_418() {
22983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22984
22985         local dir=$DIR/$tdir
22986         local numfiles=$((RANDOM % 4096 + 2))
22987         local numblocks=$((RANDOM % 256 + 1))
22988
22989         wait_delete_completed
22990         test_mkdir $dir
22991
22992         # check block output
22993         check_lfs_df blocks $dir
22994         # check inode output
22995         check_lfs_df inodes $dir
22996
22997         # create a single file and retest
22998         echo "Creating a single file and testing"
22999         createmany -o $dir/$tfile- 1 &>/dev/null ||
23000                 error "creating 1 file in $dir failed"
23001         check_lfs_df blocks $dir
23002         check_lfs_df inodes $dir
23003
23004         # create a random number of files
23005         echo "Creating $((numfiles - 1)) files and testing"
23006         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23007                 error "creating $((numfiles - 1)) files in $dir failed"
23008
23009         # write a random number of blocks to the first test file
23010         echo "Writing $numblocks 4K blocks and testing"
23011         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23012                 count=$numblocks &>/dev/null ||
23013                 error "dd to $dir/${tfile}-0 failed"
23014
23015         # retest
23016         check_lfs_df blocks $dir
23017         check_lfs_df inodes $dir
23018
23019         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23020                 error "unlinking $numfiles files in $dir failed"
23021 }
23022 run_test 418 "df and lfs df outputs match"
23023
23024 test_419()
23025 {
23026         local dir=$DIR/$tdir
23027
23028         mkdir -p $dir
23029         touch $dir/file
23030
23031         cancel_lru_locks mdc
23032
23033         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23034         $LCTL set_param fail_loc=0x1410
23035         cat $dir/file
23036         $LCTL set_param fail_loc=0
23037         rm -rf $dir
23038 }
23039 run_test 419 "Verify open file by name doesn't crash kernel"
23040
23041 test_420()
23042 {
23043         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23044                 skip "Need MDS version at least 2.12.53"
23045
23046         local SAVE_UMASK=$(umask)
23047         local dir=$DIR/$tdir
23048         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23049
23050         mkdir -p $dir
23051         umask 0000
23052         mkdir -m03777 $dir/testdir
23053         ls -dn $dir/testdir
23054         # Need to remove trailing '.' when SELinux is enabled
23055         local dirperms=$(ls -dn $dir/testdir |
23056                          awk '{ sub(/\.$/, "", $1); print $1}')
23057         [ $dirperms == "drwxrwsrwt" ] ||
23058                 error "incorrect perms on $dir/testdir"
23059
23060         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23061                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23062         ls -n $dir/testdir/testfile
23063         local fileperms=$(ls -n $dir/testdir/testfile |
23064                           awk '{ sub(/\.$/, "", $1); print $1}')
23065         [ $fileperms == "-rwxr-xr-x" ] ||
23066                 error "incorrect perms on $dir/testdir/testfile"
23067
23068         umask $SAVE_UMASK
23069 }
23070 run_test 420 "clear SGID bit on non-directories for non-members"
23071
23072 test_421a() {
23073         local cnt
23074         local fid1
23075         local fid2
23076
23077         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23078                 skip "Need MDS version at least 2.12.54"
23079
23080         test_mkdir $DIR/$tdir
23081         createmany -o $DIR/$tdir/f 3
23082         cnt=$(ls -1 $DIR/$tdir | wc -l)
23083         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23084
23085         fid1=$(lfs path2fid $DIR/$tdir/f1)
23086         fid2=$(lfs path2fid $DIR/$tdir/f2)
23087         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23088
23089         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23090         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23091
23092         cnt=$(ls -1 $DIR/$tdir | wc -l)
23093         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23094
23095         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23096         createmany -o $DIR/$tdir/f 3
23097         cnt=$(ls -1 $DIR/$tdir | wc -l)
23098         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23099
23100         fid1=$(lfs path2fid $DIR/$tdir/f1)
23101         fid2=$(lfs path2fid $DIR/$tdir/f2)
23102         echo "remove using fsname $FSNAME"
23103         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23104
23105         cnt=$(ls -1 $DIR/$tdir | wc -l)
23106         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23107 }
23108 run_test 421a "simple rm by fid"
23109
23110 test_421b() {
23111         local cnt
23112         local FID1
23113         local FID2
23114
23115         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23116                 skip "Need MDS version at least 2.12.54"
23117
23118         test_mkdir $DIR/$tdir
23119         createmany -o $DIR/$tdir/f 3
23120         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23121         MULTIPID=$!
23122
23123         FID1=$(lfs path2fid $DIR/$tdir/f1)
23124         FID2=$(lfs path2fid $DIR/$tdir/f2)
23125         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23126
23127         kill -USR1 $MULTIPID
23128         wait
23129
23130         cnt=$(ls $DIR/$tdir | wc -l)
23131         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23132 }
23133 run_test 421b "rm by fid on open file"
23134
23135 test_421c() {
23136         local cnt
23137         local FIDS
23138
23139         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23140                 skip "Need MDS version at least 2.12.54"
23141
23142         test_mkdir $DIR/$tdir
23143         createmany -o $DIR/$tdir/f 3
23144         touch $DIR/$tdir/$tfile
23145         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23146         cnt=$(ls -1 $DIR/$tdir | wc -l)
23147         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23148
23149         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23150         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23151
23152         cnt=$(ls $DIR/$tdir | wc -l)
23153         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23154 }
23155 run_test 421c "rm by fid against hardlinked files"
23156
23157 test_421d() {
23158         local cnt
23159         local FIDS
23160
23161         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23162                 skip "Need MDS version at least 2.12.54"
23163
23164         test_mkdir $DIR/$tdir
23165         createmany -o $DIR/$tdir/f 4097
23166         cnt=$(ls -1 $DIR/$tdir | wc -l)
23167         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23168
23169         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23170         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23171
23172         cnt=$(ls $DIR/$tdir | wc -l)
23173         rm -rf $DIR/$tdir
23174         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23175 }
23176 run_test 421d "rmfid en masse"
23177
23178 test_421e() {
23179         local cnt
23180         local FID
23181
23182         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23183         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23184                 skip "Need MDS version at least 2.12.54"
23185
23186         mkdir -p $DIR/$tdir
23187         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23188         createmany -o $DIR/$tdir/striped_dir/f 512
23189         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23190         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23191
23192         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23193                 sed "s/[/][^:]*://g")
23194         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23195
23196         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23197         rm -rf $DIR/$tdir
23198         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23199 }
23200 run_test 421e "rmfid in DNE"
23201
23202 test_421f() {
23203         local cnt
23204         local FID
23205
23206         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23207                 skip "Need MDS version at least 2.12.54"
23208
23209         test_mkdir $DIR/$tdir
23210         touch $DIR/$tdir/f
23211         cnt=$(ls -1 $DIR/$tdir | wc -l)
23212         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23213
23214         FID=$(lfs path2fid $DIR/$tdir/f)
23215         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23216         # rmfid should fail
23217         cnt=$(ls -1 $DIR/$tdir | wc -l)
23218         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23219
23220         chmod a+rw $DIR/$tdir
23221         ls -la $DIR/$tdir
23222         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23223         # rmfid should fail
23224         cnt=$(ls -1 $DIR/$tdir | wc -l)
23225         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23226
23227         rm -f $DIR/$tdir/f
23228         $RUNAS touch $DIR/$tdir/f
23229         FID=$(lfs path2fid $DIR/$tdir/f)
23230         echo "rmfid as root"
23231         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23232         cnt=$(ls -1 $DIR/$tdir | wc -l)
23233         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23234
23235         rm -f $DIR/$tdir/f
23236         $RUNAS touch $DIR/$tdir/f
23237         cnt=$(ls -1 $DIR/$tdir | wc -l)
23238         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23239         FID=$(lfs path2fid $DIR/$tdir/f)
23240         # rmfid w/o user_fid2path mount option should fail
23241         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23242         cnt=$(ls -1 $DIR/$tdir | wc -l)
23243         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23244
23245         umount_client $MOUNT || error "failed to umount client"
23246         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23247                 error "failed to mount client'"
23248
23249         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23250         # rmfid should succeed
23251         cnt=$(ls -1 $DIR/$tdir | wc -l)
23252         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23253
23254         # rmfid shouldn't allow to remove files due to dir's permission
23255         chmod a+rwx $DIR/$tdir
23256         touch $DIR/$tdir/f
23257         ls -la $DIR/$tdir
23258         FID=$(lfs path2fid $DIR/$tdir/f)
23259         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23260
23261         umount_client $MOUNT || error "failed to umount client"
23262         mount_client $MOUNT "$MOUNT_OPTS" ||
23263                 error "failed to mount client'"
23264
23265 }
23266 run_test 421f "rmfid checks permissions"
23267
23268 test_421g() {
23269         local cnt
23270         local FIDS
23271
23272         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23273         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23274                 skip "Need MDS version at least 2.12.54"
23275
23276         mkdir -p $DIR/$tdir
23277         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23278         createmany -o $DIR/$tdir/striped_dir/f 512
23279         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23280         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23281
23282         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23283                 sed "s/[/][^:]*://g")
23284
23285         rm -f $DIR/$tdir/striped_dir/f1*
23286         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23287         removed=$((512 - cnt))
23288
23289         # few files have been just removed, so we expect
23290         # rmfid to fail on their fids
23291         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23292         [ $removed != $errors ] && error "$errors != $removed"
23293
23294         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23295         rm -rf $DIR/$tdir
23296         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23297 }
23298 run_test 421g "rmfid to return errors properly"
23299
23300 test_422() {
23301         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23302         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23303         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23304         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23305         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23306
23307         local amc=$(at_max_get client)
23308         local amo=$(at_max_get mds1)
23309         local timeout=`lctl get_param -n timeout`
23310
23311         at_max_set 0 client
23312         at_max_set 0 mds1
23313
23314 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23315         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23316                         fail_val=$(((2*timeout + 10)*1000))
23317         touch $DIR/$tdir/d3/file &
23318         sleep 2
23319 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23320         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23321                         fail_val=$((2*timeout + 5))
23322         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23323         local pid=$!
23324         sleep 1
23325         kill -9 $pid
23326         sleep $((2 * timeout))
23327         echo kill $pid
23328         kill -9 $pid
23329         lctl mark touch
23330         touch $DIR/$tdir/d2/file3
23331         touch $DIR/$tdir/d2/file4
23332         touch $DIR/$tdir/d2/file5
23333
23334         wait
23335         at_max_set $amc client
23336         at_max_set $amo mds1
23337
23338         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23339         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23340                 error "Watchdog is always throttled"
23341 }
23342 run_test 422 "kill a process with RPC in progress"
23343
23344 stat_test() {
23345     df -h $MOUNT &
23346     df -h $MOUNT &
23347     df -h $MOUNT &
23348     df -h $MOUNT &
23349     df -h $MOUNT &
23350     df -h $MOUNT &
23351 }
23352
23353 test_423() {
23354     local _stats
23355     # ensure statfs cache is expired
23356     sleep 2;
23357
23358     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23359     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23360
23361     return 0
23362 }
23363 run_test 423 "statfs should return a right data"
23364
23365 test_424() {
23366 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23367         $LCTL set_param fail_loc=0x80000522
23368         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23369         rm -f $DIR/$tfile
23370 }
23371 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23372
23373 test_425() {
23374         test_mkdir -c -1 $DIR/$tdir
23375         $LFS setstripe -c -1 $DIR/$tdir
23376
23377         lru_resize_disable "" 100
23378         stack_trap "lru_resize_enable" EXIT
23379
23380         sleep 5
23381
23382         for i in $(seq $((MDSCOUNT * 125))); do
23383                 local t=$DIR/$tdir/$tfile_$i
23384
23385                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
23386                         error_noexit "Create file $t"
23387         done
23388         stack_trap "rm -rf $DIR/$tdir" EXIT
23389
23390         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
23391                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
23392                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
23393
23394                 [ $lock_count -le $lru_size ] ||
23395                         error "osc lock count $lock_count > lru size $lru_size"
23396         done
23397
23398         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
23399                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
23400                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
23401
23402                 [ $lock_count -le $lru_size ] ||
23403                         error "mdc lock count $lock_count > lru size $lru_size"
23404         done
23405 }
23406 run_test 425 "lock count should not exceed lru size"
23407
23408 prep_801() {
23409         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23410         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23411                 skip "Need server version at least 2.9.55"
23412
23413         start_full_debug_logging
23414 }
23415
23416 post_801() {
23417         stop_full_debug_logging
23418 }
23419
23420 barrier_stat() {
23421         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23422                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23423                            awk '/The barrier for/ { print $7 }')
23424                 echo $st
23425         else
23426                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23427                 echo \'$st\'
23428         fi
23429 }
23430
23431 barrier_expired() {
23432         local expired
23433
23434         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23435                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23436                           awk '/will be expired/ { print $7 }')
23437         else
23438                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23439         fi
23440
23441         echo $expired
23442 }
23443
23444 test_801a() {
23445         prep_801
23446
23447         echo "Start barrier_freeze at: $(date)"
23448         #define OBD_FAIL_BARRIER_DELAY          0x2202
23449         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23450         # Do not reduce barrier time - See LU-11873
23451         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23452
23453         sleep 2
23454         local b_status=$(barrier_stat)
23455         echo "Got barrier status at: $(date)"
23456         [ "$b_status" = "'freezing_p1'" ] ||
23457                 error "(1) unexpected barrier status $b_status"
23458
23459         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23460         wait
23461         b_status=$(barrier_stat)
23462         [ "$b_status" = "'frozen'" ] ||
23463                 error "(2) unexpected barrier status $b_status"
23464
23465         local expired=$(barrier_expired)
23466         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23467         sleep $((expired + 3))
23468
23469         b_status=$(barrier_stat)
23470         [ "$b_status" = "'expired'" ] ||
23471                 error "(3) unexpected barrier status $b_status"
23472
23473         # Do not reduce barrier time - See LU-11873
23474         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23475                 error "(4) fail to freeze barrier"
23476
23477         b_status=$(barrier_stat)
23478         [ "$b_status" = "'frozen'" ] ||
23479                 error "(5) unexpected barrier status $b_status"
23480
23481         echo "Start barrier_thaw at: $(date)"
23482         #define OBD_FAIL_BARRIER_DELAY          0x2202
23483         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23484         do_facet mgs $LCTL barrier_thaw $FSNAME &
23485
23486         sleep 2
23487         b_status=$(barrier_stat)
23488         echo "Got barrier status at: $(date)"
23489         [ "$b_status" = "'thawing'" ] ||
23490                 error "(6) unexpected barrier status $b_status"
23491
23492         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23493         wait
23494         b_status=$(barrier_stat)
23495         [ "$b_status" = "'thawed'" ] ||
23496                 error "(7) unexpected barrier status $b_status"
23497
23498         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23499         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23500         do_facet mgs $LCTL barrier_freeze $FSNAME
23501
23502         b_status=$(barrier_stat)
23503         [ "$b_status" = "'failed'" ] ||
23504                 error "(8) unexpected barrier status $b_status"
23505
23506         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23507         do_facet mgs $LCTL barrier_thaw $FSNAME
23508
23509         post_801
23510 }
23511 run_test 801a "write barrier user interfaces and stat machine"
23512
23513 test_801b() {
23514         prep_801
23515
23516         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23517         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23518         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23519         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23520         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23521
23522         cancel_lru_locks mdc
23523
23524         # 180 seconds should be long enough
23525         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23526
23527         local b_status=$(barrier_stat)
23528         [ "$b_status" = "'frozen'" ] ||
23529                 error "(6) unexpected barrier status $b_status"
23530
23531         mkdir $DIR/$tdir/d0/d10 &
23532         mkdir_pid=$!
23533
23534         touch $DIR/$tdir/d1/f13 &
23535         touch_pid=$!
23536
23537         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23538         ln_pid=$!
23539
23540         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23541         mv_pid=$!
23542
23543         rm -f $DIR/$tdir/d4/f12 &
23544         rm_pid=$!
23545
23546         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
23547
23548         # To guarantee taht the 'stat' is not blocked
23549         b_status=$(barrier_stat)
23550         [ "$b_status" = "'frozen'" ] ||
23551                 error "(8) unexpected barrier status $b_status"
23552
23553         # let above commands to run at background
23554         sleep 5
23555
23556         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
23557         ps -p $touch_pid || error "(10) touch should be blocked"
23558         ps -p $ln_pid || error "(11) link should be blocked"
23559         ps -p $mv_pid || error "(12) rename should be blocked"
23560         ps -p $rm_pid || error "(13) unlink should be blocked"
23561
23562         b_status=$(barrier_stat)
23563         [ "$b_status" = "'frozen'" ] ||
23564                 error "(14) unexpected barrier status $b_status"
23565
23566         do_facet mgs $LCTL barrier_thaw $FSNAME
23567         b_status=$(barrier_stat)
23568         [ "$b_status" = "'thawed'" ] ||
23569                 error "(15) unexpected barrier status $b_status"
23570
23571         wait $mkdir_pid || error "(16) mkdir should succeed"
23572         wait $touch_pid || error "(17) touch should succeed"
23573         wait $ln_pid || error "(18) link should succeed"
23574         wait $mv_pid || error "(19) rename should succeed"
23575         wait $rm_pid || error "(20) unlink should succeed"
23576
23577         post_801
23578 }
23579 run_test 801b "modification will be blocked by write barrier"
23580
23581 test_801c() {
23582         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23583
23584         prep_801
23585
23586         stop mds2 || error "(1) Fail to stop mds2"
23587
23588         do_facet mgs $LCTL barrier_freeze $FSNAME 30
23589
23590         local b_status=$(barrier_stat)
23591         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
23592                 do_facet mgs $LCTL barrier_thaw $FSNAME
23593                 error "(2) unexpected barrier status $b_status"
23594         }
23595
23596         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23597                 error "(3) Fail to rescan barrier bitmap"
23598
23599         # Do not reduce barrier time - See LU-11873
23600         do_facet mgs $LCTL barrier_freeze $FSNAME 20
23601
23602         b_status=$(barrier_stat)
23603         [ "$b_status" = "'frozen'" ] ||
23604                 error "(4) unexpected barrier status $b_status"
23605
23606         do_facet mgs $LCTL barrier_thaw $FSNAME
23607         b_status=$(barrier_stat)
23608         [ "$b_status" = "'thawed'" ] ||
23609                 error "(5) unexpected barrier status $b_status"
23610
23611         local devname=$(mdsdevname 2)
23612
23613         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
23614
23615         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23616                 error "(7) Fail to rescan barrier bitmap"
23617
23618         post_801
23619 }
23620 run_test 801c "rescan barrier bitmap"
23621
23622 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
23623 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
23624 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
23625 saved_MOUNT_OPTS=$MOUNT_OPTS
23626
23627 cleanup_802a() {
23628         trap 0
23629
23630         stopall
23631         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
23632         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
23633         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
23634         MOUNT_OPTS=$saved_MOUNT_OPTS
23635         setupall
23636 }
23637
23638 test_802a() {
23639         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
23640         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23641         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23642                 skip "Need server version at least 2.9.55"
23643
23644         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
23645
23646         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23647
23648         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23649                 error "(2) Fail to copy"
23650
23651         trap cleanup_802a EXIT
23652
23653         # sync by force before remount as readonly
23654         sync; sync_all_data; sleep 3; sync_all_data
23655
23656         stopall
23657
23658         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
23659         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
23660         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
23661
23662         echo "Mount the server as read only"
23663         setupall server_only || error "(3) Fail to start servers"
23664
23665         echo "Mount client without ro should fail"
23666         mount_client $MOUNT &&
23667                 error "(4) Mount client without 'ro' should fail"
23668
23669         echo "Mount client with ro should succeed"
23670         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
23671         mount_client $MOUNT ||
23672                 error "(5) Mount client with 'ro' should succeed"
23673
23674         echo "Modify should be refused"
23675         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23676
23677         echo "Read should be allowed"
23678         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23679                 error "(7) Read should succeed under ro mode"
23680
23681         cleanup_802a
23682 }
23683 run_test 802a "simulate readonly device"
23684
23685 test_802b() {
23686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23687         remote_mds_nodsh && skip "remote MDS with nodsh"
23688
23689         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
23690                 skip "readonly option not available"
23691
23692         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
23693
23694         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23695                 error "(2) Fail to copy"
23696
23697         # write back all cached data before setting MDT to readonly
23698         cancel_lru_locks
23699         sync_all_data
23700
23701         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
23702         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
23703
23704         echo "Modify should be refused"
23705         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23706
23707         echo "Read should be allowed"
23708         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23709                 error "(7) Read should succeed under ro mode"
23710
23711         # disable readonly
23712         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
23713 }
23714 run_test 802b "be able to set MDTs to readonly"
23715
23716 test_803() {
23717         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23718         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23719                 skip "MDS needs to be newer than 2.10.54"
23720
23721         mkdir -p $DIR/$tdir
23722         # Create some objects on all MDTs to trigger related logs objects
23723         for idx in $(seq $MDSCOUNT); do
23724                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
23725                         $DIR/$tdir/dir${idx} ||
23726                         error "Fail to create $DIR/$tdir/dir${idx}"
23727         done
23728
23729         sync; sleep 3
23730         wait_delete_completed # ensure old test cleanups are finished
23731         echo "before create:"
23732         $LFS df -i $MOUNT
23733         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23734
23735         for i in {1..10}; do
23736                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
23737                         error "Fail to create $DIR/$tdir/foo$i"
23738         done
23739
23740         sync; sleep 3
23741         echo "after create:"
23742         $LFS df -i $MOUNT
23743         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23744
23745         # allow for an llog to be cleaned up during the test
23746         [ $after_used -ge $((before_used + 10 - 1)) ] ||
23747                 error "before ($before_used) + 10 > after ($after_used)"
23748
23749         for i in {1..10}; do
23750                 rm -rf $DIR/$tdir/foo$i ||
23751                         error "Fail to remove $DIR/$tdir/foo$i"
23752         done
23753
23754         sleep 3 # avoid MDT return cached statfs
23755         wait_delete_completed
23756         echo "after unlink:"
23757         $LFS df -i $MOUNT
23758         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23759
23760         # allow for an llog to be created during the test
23761         [ $after_used -le $((before_used + 1)) ] ||
23762                 error "after ($after_used) > before ($before_used) + 1"
23763 }
23764 run_test 803 "verify agent object for remote object"
23765
23766 test_804() {
23767         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23768         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23769                 skip "MDS needs to be newer than 2.10.54"
23770         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
23771
23772         mkdir -p $DIR/$tdir
23773         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
23774                 error "Fail to create $DIR/$tdir/dir0"
23775
23776         local fid=$($LFS path2fid $DIR/$tdir/dir0)
23777         local dev=$(mdsdevname 2)
23778
23779         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23780                 grep ${fid} || error "NOT found agent entry for dir0"
23781
23782         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
23783                 error "Fail to create $DIR/$tdir/dir1"
23784
23785         touch $DIR/$tdir/dir1/foo0 ||
23786                 error "Fail to create $DIR/$tdir/dir1/foo0"
23787         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
23788         local rc=0
23789
23790         for idx in $(seq $MDSCOUNT); do
23791                 dev=$(mdsdevname $idx)
23792                 do_facet mds${idx} \
23793                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23794                         grep ${fid} && rc=$idx
23795         done
23796
23797         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
23798                 error "Fail to rename foo0 to foo1"
23799         if [ $rc -eq 0 ]; then
23800                 for idx in $(seq $MDSCOUNT); do
23801                         dev=$(mdsdevname $idx)
23802                         do_facet mds${idx} \
23803                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23804                         grep ${fid} && rc=$idx
23805                 done
23806         fi
23807
23808         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
23809                 error "Fail to rename foo1 to foo2"
23810         if [ $rc -eq 0 ]; then
23811                 for idx in $(seq $MDSCOUNT); do
23812                         dev=$(mdsdevname $idx)
23813                         do_facet mds${idx} \
23814                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23815                         grep ${fid} && rc=$idx
23816                 done
23817         fi
23818
23819         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
23820
23821         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
23822                 error "Fail to link to $DIR/$tdir/dir1/foo2"
23823         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
23824                 error "Fail to rename foo2 to foo0"
23825         unlink $DIR/$tdir/dir1/foo0 ||
23826                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
23827         rm -rf $DIR/$tdir/dir0 ||
23828                 error "Fail to rm $DIR/$tdir/dir0"
23829
23830         for idx in $(seq $MDSCOUNT); do
23831                 dev=$(mdsdevname $idx)
23832                 rc=0
23833
23834                 stop mds${idx}
23835                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
23836                         rc=$?
23837                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
23838                         error "mount mds$idx failed"
23839                 df $MOUNT > /dev/null 2>&1
23840
23841                 # e2fsck should not return error
23842                 [ $rc -eq 0 ] ||
23843                         error "e2fsck detected error on MDT${idx}: rc=$rc"
23844         done
23845 }
23846 run_test 804 "verify agent entry for remote entry"
23847
23848 cleanup_805() {
23849         do_facet $SINGLEMDS zfs set quota=$old $fsset
23850         unlinkmany $DIR/$tdir/f- 1000000
23851         trap 0
23852 }
23853
23854 test_805() {
23855         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
23856         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
23857         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
23858                 skip "netfree not implemented before 0.7"
23859         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
23860                 skip "Need MDS version at least 2.10.57"
23861
23862         local fsset
23863         local freekb
23864         local usedkb
23865         local old
23866         local quota
23867         local pref="osd-zfs.$FSNAME-MDT0000."
23868
23869         # limit available space on MDS dataset to meet nospace issue
23870         # quickly. then ZFS 0.7.2 can use reserved space if asked
23871         # properly (using netfree flag in osd_declare_destroy()
23872         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
23873         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
23874                 gawk '{print $3}')
23875         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
23876         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
23877         let "usedkb=usedkb-freekb"
23878         let "freekb=freekb/2"
23879         if let "freekb > 5000"; then
23880                 let "freekb=5000"
23881         fi
23882         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
23883         trap cleanup_805 EXIT
23884         mkdir $DIR/$tdir
23885         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
23886                 error "Can't set PFL layout"
23887         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
23888         rm -rf $DIR/$tdir || error "not able to remove"
23889         do_facet $SINGLEMDS zfs set quota=$old $fsset
23890         trap 0
23891 }
23892 run_test 805 "ZFS can remove from full fs"
23893
23894 # Size-on-MDS test
23895 check_lsom_data()
23896 {
23897         local file=$1
23898         local size=$($LFS getsom -s $file)
23899         local expect=$(stat -c %s $file)
23900
23901         [[ $size == $expect ]] ||
23902                 error "$file expected size: $expect, got: $size"
23903
23904         local blocks=$($LFS getsom -b $file)
23905         expect=$(stat -c %b $file)
23906         [[ $blocks == $expect ]] ||
23907                 error "$file expected blocks: $expect, got: $blocks"
23908 }
23909
23910 check_lsom_size()
23911 {
23912         local size=$($LFS getsom -s $1)
23913         local expect=$2
23914
23915         [[ $size == $expect ]] ||
23916                 error "$file expected size: $expect, got: $size"
23917 }
23918
23919 test_806() {
23920         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23921                 skip "Need MDS version at least 2.11.52"
23922
23923         local bs=1048576
23924
23925         touch $DIR/$tfile || error "touch $tfile failed"
23926
23927         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23928         save_lustre_params client "llite.*.xattr_cache" > $save
23929         lctl set_param llite.*.xattr_cache=0
23930         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23931
23932         # single-threaded write
23933         echo "Test SOM for single-threaded write"
23934         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
23935                 error "write $tfile failed"
23936         check_lsom_size $DIR/$tfile $bs
23937
23938         local num=32
23939         local size=$(($num * $bs))
23940         local offset=0
23941         local i
23942
23943         echo "Test SOM for single client multi-threaded($num) write"
23944         $TRUNCATE $DIR/$tfile 0
23945         for ((i = 0; i < $num; i++)); do
23946                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23947                 local pids[$i]=$!
23948                 offset=$((offset + $bs))
23949         done
23950         for (( i=0; i < $num; i++ )); do
23951                 wait ${pids[$i]}
23952         done
23953         check_lsom_size $DIR/$tfile $size
23954
23955         $TRUNCATE $DIR/$tfile 0
23956         for ((i = 0; i < $num; i++)); do
23957                 offset=$((offset - $bs))
23958                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23959                 local pids[$i]=$!
23960         done
23961         for (( i=0; i < $num; i++ )); do
23962                 wait ${pids[$i]}
23963         done
23964         check_lsom_size $DIR/$tfile $size
23965
23966         # multi-client writes
23967         num=$(get_node_count ${CLIENTS//,/ })
23968         size=$(($num * $bs))
23969         offset=0
23970         i=0
23971
23972         echo "Test SOM for multi-client ($num) writes"
23973         $TRUNCATE $DIR/$tfile 0
23974         for client in ${CLIENTS//,/ }; do
23975                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23976                 local pids[$i]=$!
23977                 i=$((i + 1))
23978                 offset=$((offset + $bs))
23979         done
23980         for (( i=0; i < $num; i++ )); do
23981                 wait ${pids[$i]}
23982         done
23983         check_lsom_size $DIR/$tfile $offset
23984
23985         i=0
23986         $TRUNCATE $DIR/$tfile 0
23987         for client in ${CLIENTS//,/ }; do
23988                 offset=$((offset - $bs))
23989                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23990                 local pids[$i]=$!
23991                 i=$((i + 1))
23992         done
23993         for (( i=0; i < $num; i++ )); do
23994                 wait ${pids[$i]}
23995         done
23996         check_lsom_size $DIR/$tfile $size
23997
23998         # verify truncate
23999         echo "Test SOM for truncate"
24000         $TRUNCATE $DIR/$tfile 1048576
24001         check_lsom_size $DIR/$tfile 1048576
24002         $TRUNCATE $DIR/$tfile 1234
24003         check_lsom_size $DIR/$tfile 1234
24004
24005         # verify SOM blocks count
24006         echo "Verify SOM block count"
24007         $TRUNCATE $DIR/$tfile 0
24008         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24009                 error "failed to write file $tfile"
24010         check_lsom_data $DIR/$tfile
24011 }
24012 run_test 806 "Verify Lazy Size on MDS"
24013
24014 test_807() {
24015         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24016         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24017                 skip "Need MDS version at least 2.11.52"
24018
24019         # Registration step
24020         changelog_register || error "changelog_register failed"
24021         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24022         changelog_users $SINGLEMDS | grep -q $cl_user ||
24023                 error "User $cl_user not found in changelog_users"
24024
24025         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24026         save_lustre_params client "llite.*.xattr_cache" > $save
24027         lctl set_param llite.*.xattr_cache=0
24028         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24029
24030         rm -rf $DIR/$tdir || error "rm $tdir failed"
24031         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24032         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24033         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24034         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24035                 error "truncate $tdir/trunc failed"
24036
24037         local bs=1048576
24038         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24039                 error "write $tfile failed"
24040
24041         # multi-client wirtes
24042         local num=$(get_node_count ${CLIENTS//,/ })
24043         local offset=0
24044         local i=0
24045
24046         echo "Test SOM for multi-client ($num) writes"
24047         touch $DIR/$tfile || error "touch $tfile failed"
24048         $TRUNCATE $DIR/$tfile 0
24049         for client in ${CLIENTS//,/ }; do
24050                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24051                 local pids[$i]=$!
24052                 i=$((i + 1))
24053                 offset=$((offset + $bs))
24054         done
24055         for (( i=0; i < $num; i++ )); do
24056                 wait ${pids[$i]}
24057         done
24058
24059         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24060         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24061         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24062         check_lsom_data $DIR/$tdir/trunc
24063         check_lsom_data $DIR/$tdir/single_dd
24064         check_lsom_data $DIR/$tfile
24065
24066         rm -rf $DIR/$tdir
24067         # Deregistration step
24068         changelog_deregister || error "changelog_deregister failed"
24069 }
24070 run_test 807 "verify LSOM syncing tool"
24071
24072 check_som_nologged()
24073 {
24074         local lines=$($LFS changelog $FSNAME-MDT0000 |
24075                 grep 'x=trusted.som' | wc -l)
24076         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24077 }
24078
24079 test_808() {
24080         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24081                 skip "Need MDS version at least 2.11.55"
24082
24083         # Registration step
24084         changelog_register || error "changelog_register failed"
24085
24086         touch $DIR/$tfile || error "touch $tfile failed"
24087         check_som_nologged
24088
24089         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24090                 error "write $tfile failed"
24091         check_som_nologged
24092
24093         $TRUNCATE $DIR/$tfile 1234
24094         check_som_nologged
24095
24096         $TRUNCATE $DIR/$tfile 1048576
24097         check_som_nologged
24098
24099         # Deregistration step
24100         changelog_deregister || error "changelog_deregister failed"
24101 }
24102 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24103
24104 check_som_nodata()
24105 {
24106         $LFS getsom $1
24107         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24108 }
24109
24110 test_809() {
24111         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24112                 skip "Need MDS version at least 2.11.56"
24113
24114         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24115                 error "failed to create DoM-only file $DIR/$tfile"
24116         touch $DIR/$tfile || error "touch $tfile failed"
24117         check_som_nodata $DIR/$tfile
24118
24119         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24120                 error "write $tfile failed"
24121         check_som_nodata $DIR/$tfile
24122
24123         $TRUNCATE $DIR/$tfile 1234
24124         check_som_nodata $DIR/$tfile
24125
24126         $TRUNCATE $DIR/$tfile 4097
24127         check_som_nodata $DIR/$file
24128 }
24129 run_test 809 "Verify no SOM xattr store for DoM-only files"
24130
24131 test_810() {
24132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24133         $GSS && skip_env "could not run with gss"
24134         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24135                 skip "OST < 2.12.58 doesn't align checksum"
24136
24137         set_checksums 1
24138         stack_trap "set_checksums $ORIG_CSUM" EXIT
24139         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24140
24141         local csum
24142         local before
24143         local after
24144         for csum in $CKSUM_TYPES; do
24145                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24146                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24147                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24148                         eval set -- $i
24149                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24150                         before=$(md5sum $DIR/$tfile)
24151                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24152                         after=$(md5sum $DIR/$tfile)
24153                         [ "$before" == "$after" ] ||
24154                                 error "$csum: $before != $after bs=$1 seek=$2"
24155                 done
24156         done
24157 }
24158 run_test 810 "partial page writes on ZFS (LU-11663)"
24159
24160 test_812a() {
24161         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24162                 skip "OST < 2.12.51 doesn't support this fail_loc"
24163         [ "$SHARED_KEY" = true ] &&
24164                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24165
24166         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24167         # ensure ost1 is connected
24168         stat $DIR/$tfile >/dev/null || error "can't stat"
24169         wait_osc_import_state client ost1 FULL
24170         # no locks, no reqs to let the connection idle
24171         cancel_lru_locks osc
24172
24173         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24174 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24175         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24176         wait_osc_import_state client ost1 CONNECTING
24177         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24178
24179         stat $DIR/$tfile >/dev/null || error "can't stat file"
24180 }
24181 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24182
24183 test_812b() { # LU-12378
24184         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24185                 skip "OST < 2.12.51 doesn't support this fail_loc"
24186         [ "$SHARED_KEY" = true ] &&
24187                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24188
24189         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24190         # ensure ost1 is connected
24191         stat $DIR/$tfile >/dev/null || error "can't stat"
24192         wait_osc_import_state client ost1 FULL
24193         # no locks, no reqs to let the connection idle
24194         cancel_lru_locks osc
24195
24196         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24197 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24198         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24199         wait_osc_import_state client ost1 CONNECTING
24200         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24201
24202         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24203         wait_osc_import_state client ost1 IDLE
24204 }
24205 run_test 812b "do not drop no resend request for idle connect"
24206
24207 test_813() {
24208         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24209         [ -z "$file_heat_sav" ] && skip "no file heat support"
24210
24211         local readsample
24212         local writesample
24213         local readbyte
24214         local writebyte
24215         local readsample1
24216         local writesample1
24217         local readbyte1
24218         local writebyte1
24219
24220         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24221         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24222
24223         $LCTL set_param -n llite.*.file_heat=1
24224         echo "Turn on file heat"
24225         echo "Period second: $period_second, Decay percentage: $decay_pct"
24226
24227         echo "QQQQ" > $DIR/$tfile
24228         echo "QQQQ" > $DIR/$tfile
24229         echo "QQQQ" > $DIR/$tfile
24230         cat $DIR/$tfile > /dev/null
24231         cat $DIR/$tfile > /dev/null
24232         cat $DIR/$tfile > /dev/null
24233         cat $DIR/$tfile > /dev/null
24234
24235         local out=$($LFS heat_get $DIR/$tfile)
24236
24237         $LFS heat_get $DIR/$tfile
24238         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24239         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24240         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24241         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24242
24243         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24244         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24245         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24246         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24247
24248         sleep $((period_second + 3))
24249         echo "Sleep $((period_second + 3)) seconds..."
24250         # The recursion formula to calculate the heat of the file f is as
24251         # follow:
24252         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24253         # Where Hi is the heat value in the period between time points i*I and
24254         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24255         # to the weight of Ci.
24256         out=$($LFS heat_get $DIR/$tfile)
24257         $LFS heat_get $DIR/$tfile
24258         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24259         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24260         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24261         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24262
24263         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24264                 error "read sample ($readsample) is wrong"
24265         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24266                 error "write sample ($writesample) is wrong"
24267         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24268                 error "read bytes ($readbyte) is wrong"
24269         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24270                 error "write bytes ($writebyte) is wrong"
24271
24272         echo "QQQQ" > $DIR/$tfile
24273         echo "QQQQ" > $DIR/$tfile
24274         echo "QQQQ" > $DIR/$tfile
24275         cat $DIR/$tfile > /dev/null
24276         cat $DIR/$tfile > /dev/null
24277         cat $DIR/$tfile > /dev/null
24278         cat $DIR/$tfile > /dev/null
24279
24280         sleep $((period_second + 3))
24281         echo "Sleep $((period_second + 3)) seconds..."
24282
24283         out=$($LFS heat_get $DIR/$tfile)
24284         $LFS heat_get $DIR/$tfile
24285         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24286         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24287         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24288         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24289
24290         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24291                 4 * $decay_pct) / 100") -eq 1 ] ||
24292                 error "read sample ($readsample1) is wrong"
24293         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24294                 3 * $decay_pct) / 100") -eq 1 ] ||
24295                 error "write sample ($writesample1) is wrong"
24296         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24297                 20 * $decay_pct) / 100") -eq 1 ] ||
24298                 error "read bytes ($readbyte1) is wrong"
24299         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24300                 15 * $decay_pct) / 100") -eq 1 ] ||
24301                 error "write bytes ($writebyte1) is wrong"
24302
24303         echo "Turn off file heat for the file $DIR/$tfile"
24304         $LFS heat_set -o $DIR/$tfile
24305
24306         echo "QQQQ" > $DIR/$tfile
24307         echo "QQQQ" > $DIR/$tfile
24308         echo "QQQQ" > $DIR/$tfile
24309         cat $DIR/$tfile > /dev/null
24310         cat $DIR/$tfile > /dev/null
24311         cat $DIR/$tfile > /dev/null
24312         cat $DIR/$tfile > /dev/null
24313
24314         out=$($LFS heat_get $DIR/$tfile)
24315         $LFS heat_get $DIR/$tfile
24316         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24317         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24318         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24319         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24320
24321         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24322         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24323         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24324         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24325
24326         echo "Trun on file heat for the file $DIR/$tfile"
24327         $LFS heat_set -O $DIR/$tfile
24328
24329         echo "QQQQ" > $DIR/$tfile
24330         echo "QQQQ" > $DIR/$tfile
24331         echo "QQQQ" > $DIR/$tfile
24332         cat $DIR/$tfile > /dev/null
24333         cat $DIR/$tfile > /dev/null
24334         cat $DIR/$tfile > /dev/null
24335         cat $DIR/$tfile > /dev/null
24336
24337         out=$($LFS heat_get $DIR/$tfile)
24338         $LFS heat_get $DIR/$tfile
24339         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24340         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24341         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24342         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24343
24344         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24345         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24346         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24347         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24348
24349         $LFS heat_set -c $DIR/$tfile
24350         $LCTL set_param -n llite.*.file_heat=0
24351         echo "Turn off file heat support for the Lustre filesystem"
24352
24353         echo "QQQQ" > $DIR/$tfile
24354         echo "QQQQ" > $DIR/$tfile
24355         echo "QQQQ" > $DIR/$tfile
24356         cat $DIR/$tfile > /dev/null
24357         cat $DIR/$tfile > /dev/null
24358         cat $DIR/$tfile > /dev/null
24359         cat $DIR/$tfile > /dev/null
24360
24361         out=$($LFS heat_get $DIR/$tfile)
24362         $LFS heat_get $DIR/$tfile
24363         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24364         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24365         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24366         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24367
24368         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24369         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24370         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24371         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24372
24373         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24374         rm -f $DIR/$tfile
24375 }
24376 run_test 813 "File heat verfication"
24377
24378 test_814()
24379 {
24380         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24381         echo -n y >> $DIR/$tfile
24382         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24383         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24384 }
24385 run_test 814 "sparse cp works as expected (LU-12361)"
24386
24387 test_815()
24388 {
24389         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24390         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24391 }
24392 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24393
24394 test_816() {
24395         [ "$SHARED_KEY" = true ] &&
24396                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24397
24398         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24399         # ensure ost1 is connected
24400         stat $DIR/$tfile >/dev/null || error "can't stat"
24401         wait_osc_import_state client ost1 FULL
24402         # no locks, no reqs to let the connection idle
24403         cancel_lru_locks osc
24404         lru_resize_disable osc
24405         local before
24406         local now
24407         before=$($LCTL get_param -n \
24408                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24409
24410         wait_osc_import_state client ost1 IDLE
24411         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24412         now=$($LCTL get_param -n \
24413               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24414         [ $before == $now ] || error "lru_size changed $before != $now"
24415 }
24416 run_test 816 "do not reset lru_resize on idle reconnect"
24417
24418 cleanup_817() {
24419         umount $tmpdir
24420         exportfs -u localhost:$DIR/nfsexp
24421         rm -rf $DIR/nfsexp
24422 }
24423
24424 test_817() {
24425         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24426
24427         mkdir -p $DIR/nfsexp
24428         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24429                 error "failed to export nfs"
24430
24431         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24432         stack_trap cleanup_817 EXIT
24433
24434         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24435                 error "failed to mount nfs to $tmpdir"
24436
24437         cp /bin/true $tmpdir
24438         $DIR/nfsexp/true || error "failed to execute 'true' command"
24439 }
24440 run_test 817 "nfsd won't cache write lock for exec file"
24441
24442 test_818() {
24443         mkdir $DIR/$tdir
24444         $LFS setstripe -c1 -i0 $DIR/$tfile
24445         $LFS setstripe -c1 -i1 $DIR/$tfile
24446         stop $SINGLEMDS
24447         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24448         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24449         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24450                 error "start $SINGLEMDS failed"
24451         rm -rf $DIR/$tdir
24452 }
24453 run_test 818 "unlink with failed llog"
24454
24455 test_819a() {
24456         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24457         cancel_lru_locks osc
24458         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24459         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24460         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24461         rm -f $TDIR/$tfile
24462 }
24463 run_test 819a "too big niobuf in read"
24464
24465 test_819b() {
24466         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24467         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24468         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24469         cancel_lru_locks osc
24470         sleep 1
24471         rm -f $TDIR/$tfile
24472 }
24473 run_test 819b "too big niobuf in write"
24474
24475
24476 function test_820_start_ost() {
24477         sleep 5
24478
24479         for num in $(seq $OSTCOUNT); do
24480                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24481         done
24482 }
24483
24484 test_820() {
24485         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24486
24487         mkdir $DIR/$tdir
24488         umount_client $MOUNT || error "umount failed"
24489         for num in $(seq $OSTCOUNT); do
24490                 stop ost$num
24491         done
24492
24493         # mount client with no active OSTs
24494         # so that the client can't initialize max LOV EA size
24495         # from OSC notifications
24496         mount_client $MOUNT || error "mount failed"
24497         # delay OST starting to keep this 0 max EA size for a while
24498         test_820_start_ost &
24499
24500         # create a directory on MDS2
24501         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24502                 error "Failed to create directory"
24503         # open intent should update default EA size
24504         # see mdc_update_max_ea_from_body()
24505         # notice this is the very first RPC to MDS2
24506         cp /etc/services $DIR/$tdir/mds2 ||
24507                 error "Failed to copy files to mds$n"
24508 }
24509 run_test 820 "update max EA from open intent"
24510
24511 #
24512 # tests that do cleanup/setup should be run at the end
24513 #
24514
24515 test_900() {
24516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24517         local ls
24518
24519         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
24520         $LCTL set_param fail_loc=0x903
24521
24522         cancel_lru_locks MGC
24523
24524         FAIL_ON_ERROR=true cleanup
24525         FAIL_ON_ERROR=true setup
24526 }
24527 run_test 900 "umount should not race with any mgc requeue thread"
24528
24529 # LUS-6253/LU-11185
24530 test_901() {
24531         local oldc
24532         local newc
24533         local olds
24534         local news
24535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24536
24537         # some get_param have a bug to handle dot in param name
24538         cancel_lru_locks MGC
24539         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24540         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24541         umount_client $MOUNT || error "umount failed"
24542         mount_client $MOUNT || error "mount failed"
24543         cancel_lru_locks MGC
24544         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24545         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24546
24547         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
24548         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
24549
24550         return 0
24551 }
24552 run_test 901 "don't leak a mgc lock on client umount"
24553
24554 # LU-13377
24555 test_902() {
24556         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
24557                 skip "client does not have LU-13377 fix"
24558         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
24559         $LCTL set_param fail_loc=0x1415
24560         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24561         cancel_lru_locks osc
24562         rm -f $DIR/$tfile
24563 }
24564 run_test 902 "test short write doesn't hang lustre"
24565
24566 complete $SECONDS
24567 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
24568 check_and_cleanup_lustre
24569 if [ "$I_MOUNTED" != "yes" ]; then
24570         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
24571 fi
24572 exit_status