Whamcloud - gitweb
LU-13006 jobid: enhance tests to check per-session jobids.
[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         # test '%j' access to environment variable - if supported
16570         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
16571                 JOBENV="JOBCOMPLEX"
16572                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16573
16574                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16575         fi
16576
16577         # test '%j' access to per-session jobid - if supported
16578         if lctl list_param jobid_this_session > /dev/null 2>&1
16579         then
16580                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
16581                 lctl set_param jobid_this_session=$USER
16582
16583                 JOBENV="JOBCOMPLEX"
16584                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16585
16586                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16587         fi
16588 }
16589 run_test 205a "Verify job stats"
16590
16591 # LU-13117, LU-13597
16592 test_205b() {
16593         job_stats="mdt.*.job_stats"
16594         $LCTL set_param $job_stats=clear
16595         # Setting jobid_var to USER might not be supported
16596         $LCTL set_param jobid_var=USER || true
16597         $LCTL set_param jobid_name="%e.%u"
16598         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16599         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16600                 grep "job_id:.*foolish" &&
16601                         error "Unexpected jobid found"
16602         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16603                 grep "open:.*min.*max.*sum" ||
16604                         error "wrong job_stats format found"
16605 }
16606 run_test 205b "Verify job stats jobid and output format"
16607
16608 # LU-13733
16609 test_205c() {
16610         $LCTL set_param llite.*.stats=0
16611         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16612         $LCTL get_param llite.*.stats
16613         $LCTL get_param llite.*.stats | grep \
16614                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16615                         error "wrong client stats format found"
16616 }
16617 run_test 205c "Verify client stats format"
16618
16619 # LU-1480, LU-1773 and LU-1657
16620 test_206() {
16621         mkdir -p $DIR/$tdir
16622         $LFS setstripe -c -1 $DIR/$tdir
16623 #define OBD_FAIL_LOV_INIT 0x1403
16624         $LCTL set_param fail_loc=0xa0001403
16625         $LCTL set_param fail_val=1
16626         touch $DIR/$tdir/$tfile || true
16627 }
16628 run_test 206 "fail lov_init_raid0() doesn't lbug"
16629
16630 test_207a() {
16631         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16632         local fsz=`stat -c %s $DIR/$tfile`
16633         cancel_lru_locks mdc
16634
16635         # do not return layout in getattr intent
16636 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16637         $LCTL set_param fail_loc=0x170
16638         local sz=`stat -c %s $DIR/$tfile`
16639
16640         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16641
16642         rm -rf $DIR/$tfile
16643 }
16644 run_test 207a "can refresh layout at glimpse"
16645
16646 test_207b() {
16647         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16648         local cksum=`md5sum $DIR/$tfile`
16649         local fsz=`stat -c %s $DIR/$tfile`
16650         cancel_lru_locks mdc
16651         cancel_lru_locks osc
16652
16653         # do not return layout in getattr intent
16654 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16655         $LCTL set_param fail_loc=0x171
16656
16657         # it will refresh layout after the file is opened but before read issues
16658         echo checksum is "$cksum"
16659         echo "$cksum" |md5sum -c --quiet || error "file differs"
16660
16661         rm -rf $DIR/$tfile
16662 }
16663 run_test 207b "can refresh layout at open"
16664
16665 test_208() {
16666         # FIXME: in this test suite, only RD lease is used. This is okay
16667         # for now as only exclusive open is supported. After generic lease
16668         # is done, this test suite should be revised. - Jinshan
16669
16670         remote_mds_nodsh && skip "remote MDS with nodsh"
16671         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16672                 skip "Need MDS version at least 2.4.52"
16673
16674         echo "==== test 1: verify get lease work"
16675         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16676
16677         echo "==== test 2: verify lease can be broken by upcoming open"
16678         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16679         local PID=$!
16680         sleep 1
16681
16682         $MULTIOP $DIR/$tfile oO_RDONLY:c
16683         kill -USR1 $PID && wait $PID || error "break lease error"
16684
16685         echo "==== test 3: verify lease can't be granted if an open already exists"
16686         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16687         local PID=$!
16688         sleep 1
16689
16690         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16691         kill -USR1 $PID && wait $PID || error "open file error"
16692
16693         echo "==== test 4: lease can sustain over recovery"
16694         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16695         PID=$!
16696         sleep 1
16697
16698         fail mds1
16699
16700         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16701
16702         echo "==== test 5: lease broken can't be regained by replay"
16703         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16704         PID=$!
16705         sleep 1
16706
16707         # open file to break lease and then recovery
16708         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16709         fail mds1
16710
16711         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16712
16713         rm -f $DIR/$tfile
16714 }
16715 run_test 208 "Exclusive open"
16716
16717 test_209() {
16718         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16719                 skip_env "must have disp_stripe"
16720
16721         touch $DIR/$tfile
16722         sync; sleep 5; sync;
16723
16724         echo 3 > /proc/sys/vm/drop_caches
16725         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16726                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16727         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16728
16729         # open/close 500 times
16730         for i in $(seq 500); do
16731                 cat $DIR/$tfile
16732         done
16733
16734         echo 3 > /proc/sys/vm/drop_caches
16735         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16736                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16737         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16738
16739         echo "before: $req_before, after: $req_after"
16740         [ $((req_after - req_before)) -ge 300 ] &&
16741                 error "open/close requests are not freed"
16742         return 0
16743 }
16744 run_test 209 "read-only open/close requests should be freed promptly"
16745
16746 test_210() {
16747         local pid
16748
16749         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16750         pid=$!
16751         sleep 1
16752
16753         $LFS getstripe $DIR/$tfile
16754         kill -USR1 $pid
16755         wait $pid || error "multiop failed"
16756
16757         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16758         pid=$!
16759         sleep 1
16760
16761         $LFS getstripe $DIR/$tfile
16762         kill -USR1 $pid
16763         wait $pid || error "multiop failed"
16764 }
16765 run_test 210 "lfs getstripe does not break leases"
16766
16767 test_212() {
16768         size=`date +%s`
16769         size=$((size % 8192 + 1))
16770         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16771         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16772         rm -f $DIR/f212 $DIR/f212.xyz
16773 }
16774 run_test 212 "Sendfile test ============================================"
16775
16776 test_213() {
16777         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16778         cancel_lru_locks osc
16779         lctl set_param fail_loc=0x8000040f
16780         # generate a read lock
16781         cat $DIR/$tfile > /dev/null
16782         # write to the file, it will try to cancel the above read lock.
16783         cat /etc/hosts >> $DIR/$tfile
16784 }
16785 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16786
16787 test_214() { # for bug 20133
16788         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16789         for (( i=0; i < 340; i++ )) ; do
16790                 touch $DIR/$tdir/d214c/a$i
16791         done
16792
16793         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16794         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16795         ls $DIR/d214c || error "ls $DIR/d214c failed"
16796         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16797         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16798 }
16799 run_test 214 "hash-indexed directory test - bug 20133"
16800
16801 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16802 create_lnet_proc_files() {
16803         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16804 }
16805
16806 # counterpart of create_lnet_proc_files
16807 remove_lnet_proc_files() {
16808         rm -f $TMP/lnet_$1.sys
16809 }
16810
16811 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16812 # 3rd arg as regexp for body
16813 check_lnet_proc_stats() {
16814         local l=$(cat "$TMP/lnet_$1" |wc -l)
16815         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16816
16817         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16818 }
16819
16820 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16821 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16822 # optional and can be regexp for 2nd line (lnet.routes case)
16823 check_lnet_proc_entry() {
16824         local blp=2          # blp stands for 'position of 1st line of body'
16825         [ -z "$5" ] || blp=3 # lnet.routes case
16826
16827         local l=$(cat "$TMP/lnet_$1" |wc -l)
16828         # subtracting one from $blp because the body can be empty
16829         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16830
16831         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16832                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16833
16834         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16835                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16836
16837         # bail out if any unexpected line happened
16838         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16839         [ "$?" != 0 ] || error "$2 misformatted"
16840 }
16841
16842 test_215() { # for bugs 18102, 21079, 21517
16843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16844
16845         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16846         local P='[1-9][0-9]*'           # positive numeric
16847         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16848         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16849         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16850         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16851
16852         local L1 # regexp for 1st line
16853         local L2 # regexp for 2nd line (optional)
16854         local BR # regexp for the rest (body)
16855
16856         # lnet.stats should look as 11 space-separated non-negative numerics
16857         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16858         create_lnet_proc_files "stats"
16859         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16860         remove_lnet_proc_files "stats"
16861
16862         # lnet.routes should look like this:
16863         # Routing disabled/enabled
16864         # net hops priority state router
16865         # where net is a string like tcp0, hops > 0, priority >= 0,
16866         # state is up/down,
16867         # router is a string like 192.168.1.1@tcp2
16868         L1="^Routing (disabled|enabled)$"
16869         L2="^net +hops +priority +state +router$"
16870         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16871         create_lnet_proc_files "routes"
16872         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16873         remove_lnet_proc_files "routes"
16874
16875         # lnet.routers should look like this:
16876         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16877         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16878         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16879         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16880         L1="^ref +rtr_ref +alive +router$"
16881         BR="^$P +$P +(up|down) +$NID$"
16882         create_lnet_proc_files "routers"
16883         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16884         remove_lnet_proc_files "routers"
16885
16886         # lnet.peers should look like this:
16887         # nid refs state last max rtr min tx min queue
16888         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16889         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16890         # numeric (0 or >0 or <0), queue >= 0.
16891         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16892         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16893         create_lnet_proc_files "peers"
16894         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16895         remove_lnet_proc_files "peers"
16896
16897         # lnet.buffers  should look like this:
16898         # pages count credits min
16899         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16900         L1="^pages +count +credits +min$"
16901         BR="^ +$N +$N +$I +$I$"
16902         create_lnet_proc_files "buffers"
16903         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16904         remove_lnet_proc_files "buffers"
16905
16906         # lnet.nis should look like this:
16907         # nid status alive refs peer rtr max tx min
16908         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16909         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16910         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16911         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16912         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16913         create_lnet_proc_files "nis"
16914         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16915         remove_lnet_proc_files "nis"
16916
16917         # can we successfully write to lnet.stats?
16918         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
16919 }
16920 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
16921
16922 test_216() { # bug 20317
16923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16924         remote_ost_nodsh && skip "remote OST with nodsh"
16925
16926         local node
16927         local facets=$(get_facets OST)
16928         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16929
16930         save_lustre_params client "osc.*.contention_seconds" > $p
16931         save_lustre_params $facets \
16932                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
16933         save_lustre_params $facets \
16934                 "ldlm.namespaces.filter-*.contended_locks" >> $p
16935         save_lustre_params $facets \
16936                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
16937         clear_stats osc.*.osc_stats
16938
16939         # agressive lockless i/o settings
16940         do_nodes $(comma_list $(osts_nodes)) \
16941                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
16942                         ldlm.namespaces.filter-*.contended_locks=0 \
16943                         ldlm.namespaces.filter-*.contention_seconds=60"
16944         lctl set_param -n osc.*.contention_seconds=60
16945
16946         $DIRECTIO write $DIR/$tfile 0 10 4096
16947         $CHECKSTAT -s 40960 $DIR/$tfile
16948
16949         # disable lockless i/o
16950         do_nodes $(comma_list $(osts_nodes)) \
16951                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
16952                         ldlm.namespaces.filter-*.contended_locks=32 \
16953                         ldlm.namespaces.filter-*.contention_seconds=0"
16954         lctl set_param -n osc.*.contention_seconds=0
16955         clear_stats osc.*.osc_stats
16956
16957         dd if=/dev/zero of=$DIR/$tfile count=0
16958         $CHECKSTAT -s 0 $DIR/$tfile
16959
16960         restore_lustre_params <$p
16961         rm -f $p
16962         rm $DIR/$tfile
16963 }
16964 run_test 216 "check lockless direct write updates file size and kms correctly"
16965
16966 test_217() { # bug 22430
16967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16968
16969         local node
16970         local nid
16971
16972         for node in $(nodes_list); do
16973                 nid=$(host_nids_address $node $NETTYPE)
16974                 if [[ $nid = *-* ]] ; then
16975                         echo "lctl ping $(h2nettype $nid)"
16976                         lctl ping $(h2nettype $nid)
16977                 else
16978                         echo "skipping $node (no hyphen detected)"
16979                 fi
16980         done
16981 }
16982 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
16983
16984 test_218() {
16985        # do directio so as not to populate the page cache
16986        log "creating a 10 Mb file"
16987        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
16988        log "starting reads"
16989        dd if=$DIR/$tfile of=/dev/null bs=4096 &
16990        log "truncating the file"
16991        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
16992        log "killing dd"
16993        kill %+ || true # reads might have finished
16994        echo "wait until dd is finished"
16995        wait
16996        log "removing the temporary file"
16997        rm -rf $DIR/$tfile || error "tmp file removal failed"
16998 }
16999 run_test 218 "parallel read and truncate should not deadlock"
17000
17001 test_219() {
17002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17003
17004         # write one partial page
17005         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17006         # set no grant so vvp_io_commit_write will do sync write
17007         $LCTL set_param fail_loc=0x411
17008         # write a full page at the end of file
17009         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17010
17011         $LCTL set_param fail_loc=0
17012         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17013         $LCTL set_param fail_loc=0x411
17014         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17015
17016         # LU-4201
17017         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17018         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17019 }
17020 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17021
17022 test_220() { #LU-325
17023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17024         remote_ost_nodsh && skip "remote OST with nodsh"
17025         remote_mds_nodsh && skip "remote MDS with nodsh"
17026         remote_mgs_nodsh && skip "remote MGS with nodsh"
17027
17028         local OSTIDX=0
17029
17030         # create on MDT0000 so the last_id and next_id are correct
17031         mkdir $DIR/$tdir
17032         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17033         OST=${OST%_UUID}
17034
17035         # on the mdt's osc
17036         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17037         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17038                         osp.$mdtosc_proc1.prealloc_last_id)
17039         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17040                         osp.$mdtosc_proc1.prealloc_next_id)
17041
17042         $LFS df -i
17043
17044         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17045         #define OBD_FAIL_OST_ENOINO              0x229
17046         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17047         create_pool $FSNAME.$TESTNAME || return 1
17048         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17049
17050         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17051
17052         MDSOBJS=$((last_id - next_id))
17053         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17054
17055         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17056         echo "OST still has $count kbytes free"
17057
17058         echo "create $MDSOBJS files @next_id..."
17059         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17060
17061         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17062                         osp.$mdtosc_proc1.prealloc_last_id)
17063         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17064                         osp.$mdtosc_proc1.prealloc_next_id)
17065
17066         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17067         $LFS df -i
17068
17069         echo "cleanup..."
17070
17071         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17072         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17073
17074         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17075                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17076         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17077                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17078         echo "unlink $MDSOBJS files @$next_id..."
17079         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17080 }
17081 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17082
17083 test_221() {
17084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17085
17086         dd if=`which date` of=$MOUNT/date oflag=sync
17087         chmod +x $MOUNT/date
17088
17089         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17090         $LCTL set_param fail_loc=0x80001401
17091
17092         $MOUNT/date > /dev/null
17093         rm -f $MOUNT/date
17094 }
17095 run_test 221 "make sure fault and truncate race to not cause OOM"
17096
17097 test_222a () {
17098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17099
17100         rm -rf $DIR/$tdir
17101         test_mkdir $DIR/$tdir
17102         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17103         createmany -o $DIR/$tdir/$tfile 10
17104         cancel_lru_locks mdc
17105         cancel_lru_locks osc
17106         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17107         $LCTL set_param fail_loc=0x31a
17108         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17109         $LCTL set_param fail_loc=0
17110         rm -r $DIR/$tdir
17111 }
17112 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17113
17114 test_222b () {
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_DELAY           0x31a
17124         $LCTL set_param fail_loc=0x31a
17125         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17126         $LCTL set_param fail_loc=0
17127 }
17128 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17129
17130 test_223 () {
17131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17132
17133         rm -rf $DIR/$tdir
17134         test_mkdir $DIR/$tdir
17135         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17136         createmany -o $DIR/$tdir/$tfile 10
17137         cancel_lru_locks mdc
17138         cancel_lru_locks osc
17139         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17140         $LCTL set_param fail_loc=0x31b
17141         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17142         $LCTL set_param fail_loc=0
17143         rm -r $DIR/$tdir
17144 }
17145 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17146
17147 test_224a() { # LU-1039, MRP-303
17148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17149
17150         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17151         $LCTL set_param fail_loc=0x508
17152         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17153         $LCTL set_param fail_loc=0
17154         df $DIR
17155 }
17156 run_test 224a "Don't panic on bulk IO failure"
17157
17158 test_224b() { # LU-1039, MRP-303
17159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17160
17161         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17162         cancel_lru_locks osc
17163         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17164         $LCTL set_param fail_loc=0x515
17165         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17166         $LCTL set_param fail_loc=0
17167         df $DIR
17168 }
17169 run_test 224b "Don't panic on bulk IO failure"
17170
17171 test_224c() { # LU-6441
17172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17173         remote_mds_nodsh && skip "remote MDS with nodsh"
17174
17175         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17176         save_writethrough $p
17177         set_cache writethrough on
17178
17179         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17180         local at_max=$($LCTL get_param -n at_max)
17181         local timeout=$($LCTL get_param -n timeout)
17182         local test_at="at_max"
17183         local param_at="$FSNAME.sys.at_max"
17184         local test_timeout="timeout"
17185         local param_timeout="$FSNAME.sys.timeout"
17186
17187         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17188
17189         set_persistent_param_and_check client "$test_at" "$param_at" 0
17190         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17191
17192         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17193         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17194         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17195         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17196         sync
17197         do_facet ost1 "$LCTL set_param fail_loc=0"
17198
17199         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17200         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17201                 $timeout
17202
17203         $LCTL set_param -n $pages_per_rpc
17204         restore_lustre_params < $p
17205         rm -f $p
17206 }
17207 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17208
17209 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17210 test_225a () {
17211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17212         if [ -z ${MDSSURVEY} ]; then
17213                 skip_env "mds-survey not found"
17214         fi
17215         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17216                 skip "Need MDS version at least 2.2.51"
17217
17218         local mds=$(facet_host $SINGLEMDS)
17219         local target=$(do_nodes $mds 'lctl dl' |
17220                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17221
17222         local cmd1="file_count=1000 thrhi=4"
17223         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17224         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17225         local cmd="$cmd1 $cmd2 $cmd3"
17226
17227         rm -f ${TMP}/mds_survey*
17228         echo + $cmd
17229         eval $cmd || error "mds-survey with zero-stripe failed"
17230         cat ${TMP}/mds_survey*
17231         rm -f ${TMP}/mds_survey*
17232 }
17233 run_test 225a "Metadata survey sanity with zero-stripe"
17234
17235 test_225b () {
17236         if [ -z ${MDSSURVEY} ]; then
17237                 skip_env "mds-survey not found"
17238         fi
17239         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17240                 skip "Need MDS version at least 2.2.51"
17241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17242         remote_mds_nodsh && skip "remote MDS with nodsh"
17243         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17244                 skip_env "Need to mount OST to test"
17245         fi
17246
17247         local mds=$(facet_host $SINGLEMDS)
17248         local target=$(do_nodes $mds 'lctl dl' |
17249                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17250
17251         local cmd1="file_count=1000 thrhi=4"
17252         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17253         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17254         local cmd="$cmd1 $cmd2 $cmd3"
17255
17256         rm -f ${TMP}/mds_survey*
17257         echo + $cmd
17258         eval $cmd || error "mds-survey with stripe_count failed"
17259         cat ${TMP}/mds_survey*
17260         rm -f ${TMP}/mds_survey*
17261 }
17262 run_test 225b "Metadata survey sanity with stripe_count = 1"
17263
17264 mcreate_path2fid () {
17265         local mode=$1
17266         local major=$2
17267         local minor=$3
17268         local name=$4
17269         local desc=$5
17270         local path=$DIR/$tdir/$name
17271         local fid
17272         local rc
17273         local fid_path
17274
17275         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17276                 error "cannot create $desc"
17277
17278         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17279         rc=$?
17280         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17281
17282         fid_path=$($LFS fid2path $MOUNT $fid)
17283         rc=$?
17284         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17285
17286         [ "$path" == "$fid_path" ] ||
17287                 error "fid2path returned $fid_path, expected $path"
17288
17289         echo "pass with $path and $fid"
17290 }
17291
17292 test_226a () {
17293         rm -rf $DIR/$tdir
17294         mkdir -p $DIR/$tdir
17295
17296         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17297         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17298         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17299         mcreate_path2fid 0040666 0 0 dir "directory"
17300         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17301         mcreate_path2fid 0100666 0 0 file "regular file"
17302         mcreate_path2fid 0120666 0 0 link "symbolic link"
17303         mcreate_path2fid 0140666 0 0 sock "socket"
17304 }
17305 run_test 226a "call path2fid and fid2path on files of all type"
17306
17307 test_226b () {
17308         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17309
17310         local MDTIDX=1
17311
17312         rm -rf $DIR/$tdir
17313         mkdir -p $DIR/$tdir
17314         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17315                 error "create remote directory failed"
17316         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17317         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17318                                 "character special file (null)"
17319         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17320                                 "character special file (no device)"
17321         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17322         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17323                                 "block special file (loop)"
17324         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17325         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17326         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17327 }
17328 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17329
17330 test_226c () {
17331         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17332         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17333                 skip "Need MDS version at least 2.13.55"
17334
17335         local submnt=/mnt/submnt
17336         local srcfile=/etc/passwd
17337         local dstfile=$submnt/passwd
17338         local path
17339         local fid
17340
17341         rm -rf $DIR/$tdir
17342         rm -rf $submnt
17343         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17344                 error "create remote directory failed"
17345         mkdir -p $submnt || error "create $submnt failed"
17346         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17347                 error "mount $submnt failed"
17348         stack_trap "umount $submnt" EXIT
17349
17350         cp $srcfile $dstfile
17351         fid=$($LFS path2fid $dstfile)
17352         path=$($LFS fid2path $submnt "$fid")
17353         [ "$path" = "$dstfile" ] ||
17354                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17355 }
17356 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17357
17358 # LU-1299 Executing or running ldd on a truncated executable does not
17359 # cause an out-of-memory condition.
17360 test_227() {
17361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17362         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17363
17364         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17365         chmod +x $MOUNT/date
17366
17367         $MOUNT/date > /dev/null
17368         ldd $MOUNT/date > /dev/null
17369         rm -f $MOUNT/date
17370 }
17371 run_test 227 "running truncated executable does not cause OOM"
17372
17373 # LU-1512 try to reuse idle OI blocks
17374 test_228a() {
17375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17376         remote_mds_nodsh && skip "remote MDS with nodsh"
17377         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17378
17379         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17380         local myDIR=$DIR/$tdir
17381
17382         mkdir -p $myDIR
17383         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17384         $LCTL set_param fail_loc=0x80001002
17385         createmany -o $myDIR/t- 10000
17386         $LCTL set_param fail_loc=0
17387         # The guard is current the largest FID holder
17388         touch $myDIR/guard
17389         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17390                     tr -d '[')
17391         local IDX=$(($SEQ % 64))
17392
17393         do_facet $SINGLEMDS sync
17394         # Make sure journal flushed.
17395         sleep 6
17396         local blk1=$(do_facet $SINGLEMDS \
17397                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17398                      grep Blockcount | awk '{print $4}')
17399
17400         # Remove old files, some OI blocks will become idle.
17401         unlinkmany $myDIR/t- 10000
17402         # Create new files, idle OI blocks should be reused.
17403         createmany -o $myDIR/t- 2000
17404         do_facet $SINGLEMDS sync
17405         # Make sure journal flushed.
17406         sleep 6
17407         local blk2=$(do_facet $SINGLEMDS \
17408                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17409                      grep Blockcount | awk '{print $4}')
17410
17411         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17412 }
17413 run_test 228a "try to reuse idle OI blocks"
17414
17415 test_228b() {
17416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17417         remote_mds_nodsh && skip "remote MDS with nodsh"
17418         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17419
17420         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17421         local myDIR=$DIR/$tdir
17422
17423         mkdir -p $myDIR
17424         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17425         $LCTL set_param fail_loc=0x80001002
17426         createmany -o $myDIR/t- 10000
17427         $LCTL set_param fail_loc=0
17428         # The guard is current the largest FID holder
17429         touch $myDIR/guard
17430         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17431                     tr -d '[')
17432         local IDX=$(($SEQ % 64))
17433
17434         do_facet $SINGLEMDS sync
17435         # Make sure journal flushed.
17436         sleep 6
17437         local blk1=$(do_facet $SINGLEMDS \
17438                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17439                      grep Blockcount | awk '{print $4}')
17440
17441         # Remove old files, some OI blocks will become idle.
17442         unlinkmany $myDIR/t- 10000
17443
17444         # stop the MDT
17445         stop $SINGLEMDS || error "Fail to stop MDT."
17446         # remount the MDT
17447         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17448
17449         df $MOUNT || error "Fail to df."
17450         # Create new files, idle OI blocks should be reused.
17451         createmany -o $myDIR/t- 2000
17452         do_facet $SINGLEMDS sync
17453         # Make sure journal flushed.
17454         sleep 6
17455         local blk2=$(do_facet $SINGLEMDS \
17456                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17457                      grep Blockcount | awk '{print $4}')
17458
17459         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17460 }
17461 run_test 228b "idle OI blocks can be reused after MDT restart"
17462
17463 #LU-1881
17464 test_228c() {
17465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17466         remote_mds_nodsh && skip "remote MDS with nodsh"
17467         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17468
17469         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17470         local myDIR=$DIR/$tdir
17471
17472         mkdir -p $myDIR
17473         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17474         $LCTL set_param fail_loc=0x80001002
17475         # 20000 files can guarantee there are index nodes in the OI file
17476         createmany -o $myDIR/t- 20000
17477         $LCTL set_param fail_loc=0
17478         # The guard is current the largest FID holder
17479         touch $myDIR/guard
17480         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17481                     tr -d '[')
17482         local IDX=$(($SEQ % 64))
17483
17484         do_facet $SINGLEMDS sync
17485         # Make sure journal flushed.
17486         sleep 6
17487         local blk1=$(do_facet $SINGLEMDS \
17488                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17489                      grep Blockcount | awk '{print $4}')
17490
17491         # Remove old files, some OI blocks will become idle.
17492         unlinkmany $myDIR/t- 20000
17493         rm -f $myDIR/guard
17494         # The OI file should become empty now
17495
17496         # Create new files, idle OI blocks should be reused.
17497         createmany -o $myDIR/t- 2000
17498         do_facet $SINGLEMDS sync
17499         # Make sure journal flushed.
17500         sleep 6
17501         local blk2=$(do_facet $SINGLEMDS \
17502                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17503                      grep Blockcount | awk '{print $4}')
17504
17505         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17506 }
17507 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17508
17509 test_229() { # LU-2482, LU-3448
17510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17511         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17512         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17513                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17514
17515         rm -f $DIR/$tfile
17516
17517         # Create a file with a released layout and stripe count 2.
17518         $MULTIOP $DIR/$tfile H2c ||
17519                 error "failed to create file with released layout"
17520
17521         $LFS getstripe -v $DIR/$tfile
17522
17523         local pattern=$($LFS getstripe -L $DIR/$tfile)
17524         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17525
17526         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17527                 error "getstripe"
17528         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17529         stat $DIR/$tfile || error "failed to stat released file"
17530
17531         chown $RUNAS_ID $DIR/$tfile ||
17532                 error "chown $RUNAS_ID $DIR/$tfile failed"
17533
17534         chgrp $RUNAS_ID $DIR/$tfile ||
17535                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17536
17537         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17538         rm $DIR/$tfile || error "failed to remove released file"
17539 }
17540 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17541
17542 test_230a() {
17543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17544         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17545         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17546                 skip "Need MDS version at least 2.11.52"
17547
17548         local MDTIDX=1
17549
17550         test_mkdir $DIR/$tdir
17551         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17552         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17553         [ $mdt_idx -ne 0 ] &&
17554                 error "create local directory on wrong MDT $mdt_idx"
17555
17556         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17557                         error "create remote directory failed"
17558         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17559         [ $mdt_idx -ne $MDTIDX ] &&
17560                 error "create remote directory on wrong MDT $mdt_idx"
17561
17562         createmany -o $DIR/$tdir/test_230/t- 10 ||
17563                 error "create files on remote directory failed"
17564         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17565         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17566         rm -r $DIR/$tdir || error "unlink remote directory failed"
17567 }
17568 run_test 230a "Create remote directory and files under the remote directory"
17569
17570 test_230b() {
17571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17572         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17573         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17574                 skip "Need MDS version at least 2.11.52"
17575
17576         local MDTIDX=1
17577         local mdt_index
17578         local i
17579         local file
17580         local pid
17581         local stripe_count
17582         local migrate_dir=$DIR/$tdir/migrate_dir
17583         local other_dir=$DIR/$tdir/other_dir
17584
17585         test_mkdir $DIR/$tdir
17586         test_mkdir -i0 -c1 $migrate_dir
17587         test_mkdir -i0 -c1 $other_dir
17588         for ((i=0; i<10; i++)); do
17589                 mkdir -p $migrate_dir/dir_${i}
17590                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17591                         error "create files under remote dir failed $i"
17592         done
17593
17594         cp /etc/passwd $migrate_dir/$tfile
17595         cp /etc/passwd $other_dir/$tfile
17596         chattr +SAD $migrate_dir
17597         chattr +SAD $migrate_dir/$tfile
17598
17599         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17600         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17601         local old_dir_mode=$(stat -c%f $migrate_dir)
17602         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17603
17604         mkdir -p $migrate_dir/dir_default_stripe2
17605         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17606         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17607
17608         mkdir -p $other_dir
17609         ln $migrate_dir/$tfile $other_dir/luna
17610         ln $migrate_dir/$tfile $migrate_dir/sofia
17611         ln $other_dir/$tfile $migrate_dir/david
17612         ln -s $migrate_dir/$tfile $other_dir/zachary
17613         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17614         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17615
17616         local len
17617         local lnktgt
17618
17619         # inline symlink
17620         for len in 58 59 60; do
17621                 lnktgt=$(str_repeat 'l' $len)
17622                 touch $migrate_dir/$lnktgt
17623                 ln -s $lnktgt $migrate_dir/${len}char_ln
17624         done
17625
17626         # PATH_MAX
17627         for len in 4094 4095; do
17628                 lnktgt=$(str_repeat 'l' $len)
17629                 ln -s $lnktgt $migrate_dir/${len}char_ln
17630         done
17631
17632         # NAME_MAX
17633         for len in 254 255; do
17634                 touch $migrate_dir/$(str_repeat 'l' $len)
17635         done
17636
17637         $LFS migrate -m $MDTIDX $migrate_dir ||
17638                 error "fails on migrating remote dir to MDT1"
17639
17640         echo "migratate to MDT1, then checking.."
17641         for ((i = 0; i < 10; i++)); do
17642                 for file in $(find $migrate_dir/dir_${i}); do
17643                         mdt_index=$($LFS getstripe -m $file)
17644                         # broken symlink getstripe will fail
17645                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17646                                 error "$file is not on MDT${MDTIDX}"
17647                 done
17648         done
17649
17650         # the multiple link file should still in MDT0
17651         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17652         [ $mdt_index == 0 ] ||
17653                 error "$file is not on MDT${MDTIDX}"
17654
17655         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17656         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17657                 error " expect $old_dir_flag get $new_dir_flag"
17658
17659         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17660         [ "$old_file_flag" = "$new_file_flag" ] ||
17661                 error " expect $old_file_flag get $new_file_flag"
17662
17663         local new_dir_mode=$(stat -c%f $migrate_dir)
17664         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17665                 error "expect mode $old_dir_mode get $new_dir_mode"
17666
17667         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17668         [ "$old_file_mode" = "$new_file_mode" ] ||
17669                 error "expect mode $old_file_mode get $new_file_mode"
17670
17671         diff /etc/passwd $migrate_dir/$tfile ||
17672                 error "$tfile different after migration"
17673
17674         diff /etc/passwd $other_dir/luna ||
17675                 error "luna different after migration"
17676
17677         diff /etc/passwd $migrate_dir/sofia ||
17678                 error "sofia different after migration"
17679
17680         diff /etc/passwd $migrate_dir/david ||
17681                 error "david different after migration"
17682
17683         diff /etc/passwd $other_dir/zachary ||
17684                 error "zachary different after migration"
17685
17686         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17687                 error "${tfile}_ln different after migration"
17688
17689         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17690                 error "${tfile}_ln_other different after migration"
17691
17692         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17693         [ $stripe_count = 2 ] ||
17694                 error "dir strpe_count $d != 2 after migration."
17695
17696         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17697         [ $stripe_count = 2 ] ||
17698                 error "file strpe_count $d != 2 after migration."
17699
17700         #migrate back to MDT0
17701         MDTIDX=0
17702
17703         $LFS migrate -m $MDTIDX $migrate_dir ||
17704                 error "fails on migrating remote dir to MDT0"
17705
17706         echo "migrate back to MDT0, checking.."
17707         for file in $(find $migrate_dir); do
17708                 mdt_index=$($LFS getstripe -m $file)
17709                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17710                         error "$file is not on MDT${MDTIDX}"
17711         done
17712
17713         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17714         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17715                 error " expect $old_dir_flag get $new_dir_flag"
17716
17717         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17718         [ "$old_file_flag" = "$new_file_flag" ] ||
17719                 error " expect $old_file_flag get $new_file_flag"
17720
17721         local new_dir_mode=$(stat -c%f $migrate_dir)
17722         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17723                 error "expect mode $old_dir_mode get $new_dir_mode"
17724
17725         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17726         [ "$old_file_mode" = "$new_file_mode" ] ||
17727                 error "expect mode $old_file_mode get $new_file_mode"
17728
17729         diff /etc/passwd ${migrate_dir}/$tfile ||
17730                 error "$tfile different after migration"
17731
17732         diff /etc/passwd ${other_dir}/luna ||
17733                 error "luna different after migration"
17734
17735         diff /etc/passwd ${migrate_dir}/sofia ||
17736                 error "sofia different after migration"
17737
17738         diff /etc/passwd ${other_dir}/zachary ||
17739                 error "zachary different after migration"
17740
17741         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17742                 error "${tfile}_ln different after migration"
17743
17744         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17745                 error "${tfile}_ln_other different after migration"
17746
17747         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17748         [ $stripe_count = 2 ] ||
17749                 error "dir strpe_count $d != 2 after migration."
17750
17751         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17752         [ $stripe_count = 2 ] ||
17753                 error "file strpe_count $d != 2 after migration."
17754
17755         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17756 }
17757 run_test 230b "migrate directory"
17758
17759 test_230c() {
17760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17761         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17762         remote_mds_nodsh && skip "remote MDS with nodsh"
17763         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17764                 skip "Need MDS version at least 2.11.52"
17765
17766         local MDTIDX=1
17767         local total=3
17768         local mdt_index
17769         local file
17770         local migrate_dir=$DIR/$tdir/migrate_dir
17771
17772         #If migrating directory fails in the middle, all entries of
17773         #the directory is still accessiable.
17774         test_mkdir $DIR/$tdir
17775         test_mkdir -i0 -c1 $migrate_dir
17776         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17777         stat $migrate_dir
17778         createmany -o $migrate_dir/f $total ||
17779                 error "create files under ${migrate_dir} failed"
17780
17781         # fail after migrating top dir, and this will fail only once, so the
17782         # first sub file migration will fail (currently f3), others succeed.
17783         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17784         do_facet mds1 lctl set_param fail_loc=0x1801
17785         local t=$(ls $migrate_dir | wc -l)
17786         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17787                 error "migrate should fail"
17788         local u=$(ls $migrate_dir | wc -l)
17789         [ "$u" == "$t" ] || error "$u != $t during migration"
17790
17791         # add new dir/file should succeed
17792         mkdir $migrate_dir/dir ||
17793                 error "mkdir failed under migrating directory"
17794         touch $migrate_dir/file ||
17795                 error "create file failed under migrating directory"
17796
17797         # add file with existing name should fail
17798         for file in $migrate_dir/f*; do
17799                 stat $file > /dev/null || error "stat $file failed"
17800                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17801                         error "open(O_CREAT|O_EXCL) $file should fail"
17802                 $MULTIOP $file m && error "create $file should fail"
17803                 touch $DIR/$tdir/remote_dir/$tfile ||
17804                         error "touch $tfile failed"
17805                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17806                         error "link $file should fail"
17807                 mdt_index=$($LFS getstripe -m $file)
17808                 if [ $mdt_index == 0 ]; then
17809                         # file failed to migrate is not allowed to rename to
17810                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17811                                 error "rename to $file should fail"
17812                 else
17813                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17814                                 error "rename to $file failed"
17815                 fi
17816                 echo hello >> $file || error "write $file failed"
17817         done
17818
17819         # resume migration with different options should fail
17820         $LFS migrate -m 0 $migrate_dir &&
17821                 error "migrate -m 0 $migrate_dir should fail"
17822
17823         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17824                 error "migrate -c 2 $migrate_dir should fail"
17825
17826         # resume migration should succeed
17827         $LFS migrate -m $MDTIDX $migrate_dir ||
17828                 error "migrate $migrate_dir failed"
17829
17830         echo "Finish migration, then checking.."
17831         for file in $(find $migrate_dir); do
17832                 mdt_index=$($LFS getstripe -m $file)
17833                 [ $mdt_index == $MDTIDX ] ||
17834                         error "$file is not on MDT${MDTIDX}"
17835         done
17836
17837         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17838 }
17839 run_test 230c "check directory accessiblity if migration failed"
17840
17841 test_230d() {
17842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17843         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17844         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17845                 skip "Need MDS version at least 2.11.52"
17846         # LU-11235
17847         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17848
17849         local migrate_dir=$DIR/$tdir/migrate_dir
17850         local old_index
17851         local new_index
17852         local old_count
17853         local new_count
17854         local new_hash
17855         local mdt_index
17856         local i
17857         local j
17858
17859         old_index=$((RANDOM % MDSCOUNT))
17860         old_count=$((MDSCOUNT - old_index))
17861         new_index=$((RANDOM % MDSCOUNT))
17862         new_count=$((MDSCOUNT - new_index))
17863         new_hash=1 # for all_char
17864
17865         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17866         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17867
17868         test_mkdir $DIR/$tdir
17869         test_mkdir -i $old_index -c $old_count $migrate_dir
17870
17871         for ((i=0; i<100; i++)); do
17872                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17873                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17874                         error "create files under remote dir failed $i"
17875         done
17876
17877         echo -n "Migrate from MDT$old_index "
17878         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17879         echo -n "to MDT$new_index"
17880         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17881         echo
17882
17883         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17884         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17885                 error "migrate remote dir error"
17886
17887         echo "Finish migration, then checking.."
17888         for file in $(find $migrate_dir); do
17889                 mdt_index=$($LFS getstripe -m $file)
17890                 if [ $mdt_index -lt $new_index ] ||
17891                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17892                         error "$file is on MDT$mdt_index"
17893                 fi
17894         done
17895
17896         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17897 }
17898 run_test 230d "check migrate big directory"
17899
17900 test_230e() {
17901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17902         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17903         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17904                 skip "Need MDS version at least 2.11.52"
17905
17906         local i
17907         local j
17908         local a_fid
17909         local b_fid
17910
17911         mkdir -p $DIR/$tdir
17912         mkdir $DIR/$tdir/migrate_dir
17913         mkdir $DIR/$tdir/other_dir
17914         touch $DIR/$tdir/migrate_dir/a
17915         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17916         ls $DIR/$tdir/other_dir
17917
17918         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17919                 error "migrate dir fails"
17920
17921         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17922         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17923
17924         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17925         [ $mdt_index == 0 ] || error "a is not on MDT0"
17926
17927         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
17928                 error "migrate dir fails"
17929
17930         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
17931         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
17932
17933         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17934         [ $mdt_index == 1 ] || error "a is not on MDT1"
17935
17936         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
17937         [ $mdt_index == 1 ] || error "b is not on MDT1"
17938
17939         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17940         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
17941
17942         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
17943
17944         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17945 }
17946 run_test 230e "migrate mulitple local link files"
17947
17948 test_230f() {
17949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17950         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17951         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17952                 skip "Need MDS version at least 2.11.52"
17953
17954         local a_fid
17955         local ln_fid
17956
17957         mkdir -p $DIR/$tdir
17958         mkdir $DIR/$tdir/migrate_dir
17959         $LFS mkdir -i1 $DIR/$tdir/other_dir
17960         touch $DIR/$tdir/migrate_dir/a
17961         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
17962         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
17963         ls $DIR/$tdir/other_dir
17964
17965         # a should be migrated to MDT1, since no other links on MDT0
17966         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17967                 error "#1 migrate dir fails"
17968         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17969         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17970         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17971         [ $mdt_index == 1 ] || error "a is not on MDT1"
17972
17973         # a should stay on MDT1, because it is a mulitple link file
17974         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17975                 error "#2 migrate dir fails"
17976         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17977         [ $mdt_index == 1 ] || error "a is not on MDT1"
17978
17979         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17980                 error "#3 migrate dir fails"
17981
17982         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17983         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
17984         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
17985
17986         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
17987         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
17988
17989         # a should be migrated to MDT0, since no other links on MDT1
17990         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17991                 error "#4 migrate dir fails"
17992         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17993         [ $mdt_index == 0 ] || error "a is not on MDT0"
17994
17995         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17996 }
17997 run_test 230f "migrate mulitple remote link files"
17998
17999 test_230g() {
18000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18001         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18002         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18003                 skip "Need MDS version at least 2.11.52"
18004
18005         mkdir -p $DIR/$tdir/migrate_dir
18006
18007         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18008                 error "migrating dir to non-exist MDT succeeds"
18009         true
18010 }
18011 run_test 230g "migrate dir to non-exist MDT"
18012
18013 test_230h() {
18014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18015         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18016         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18017                 skip "Need MDS version at least 2.11.52"
18018
18019         local mdt_index
18020
18021         mkdir -p $DIR/$tdir/migrate_dir
18022
18023         $LFS migrate -m1 $DIR &&
18024                 error "migrating mountpoint1 should fail"
18025
18026         $LFS migrate -m1 $DIR/$tdir/.. &&
18027                 error "migrating mountpoint2 should fail"
18028
18029         # same as mv
18030         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18031                 error "migrating $tdir/migrate_dir/.. should fail"
18032
18033         true
18034 }
18035 run_test 230h "migrate .. and root"
18036
18037 test_230i() {
18038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18039         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18040         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18041                 skip "Need MDS version at least 2.11.52"
18042
18043         mkdir -p $DIR/$tdir/migrate_dir
18044
18045         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18046                 error "migration fails with a tailing slash"
18047
18048         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18049                 error "migration fails with two tailing slashes"
18050 }
18051 run_test 230i "lfs migrate -m tolerates trailing slashes"
18052
18053 test_230j() {
18054         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18055         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18056                 skip "Need MDS version at least 2.11.52"
18057
18058         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18059         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18060                 error "create $tfile failed"
18061         cat /etc/passwd > $DIR/$tdir/$tfile
18062
18063         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18064
18065         cmp /etc/passwd $DIR/$tdir/$tfile ||
18066                 error "DoM file mismatch after migration"
18067 }
18068 run_test 230j "DoM file data not changed after dir migration"
18069
18070 test_230k() {
18071         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18072         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18073                 skip "Need MDS version at least 2.11.56"
18074
18075         local total=20
18076         local files_on_starting_mdt=0
18077
18078         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18079         $LFS getdirstripe $DIR/$tdir
18080         for i in $(seq $total); do
18081                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18082                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18083                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18084         done
18085
18086         echo "$files_on_starting_mdt files on MDT0"
18087
18088         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18089         $LFS getdirstripe $DIR/$tdir
18090
18091         files_on_starting_mdt=0
18092         for i in $(seq $total); do
18093                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18094                         error "file $tfile.$i mismatch after migration"
18095                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18096                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18097         done
18098
18099         echo "$files_on_starting_mdt files on MDT1 after migration"
18100         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18101
18102         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18103         $LFS getdirstripe $DIR/$tdir
18104
18105         files_on_starting_mdt=0
18106         for i in $(seq $total); do
18107                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18108                         error "file $tfile.$i mismatch after 2nd migration"
18109                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18110                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18111         done
18112
18113         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18114         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18115
18116         true
18117 }
18118 run_test 230k "file data not changed after dir migration"
18119
18120 test_230l() {
18121         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18122         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18123                 skip "Need MDS version at least 2.11.56"
18124
18125         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18126         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18127                 error "create files under remote dir failed $i"
18128         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18129 }
18130 run_test 230l "readdir between MDTs won't crash"
18131
18132 test_230m() {
18133         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18134         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18135                 skip "Need MDS version at least 2.11.56"
18136
18137         local MDTIDX=1
18138         local mig_dir=$DIR/$tdir/migrate_dir
18139         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18140         local shortstr="b"
18141         local val
18142
18143         echo "Creating files and dirs with xattrs"
18144         test_mkdir $DIR/$tdir
18145         test_mkdir -i0 -c1 $mig_dir
18146         mkdir $mig_dir/dir
18147         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18148                 error "cannot set xattr attr1 on dir"
18149         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18150                 error "cannot set xattr attr2 on dir"
18151         touch $mig_dir/dir/f0
18152         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18153                 error "cannot set xattr attr1 on file"
18154         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18155                 error "cannot set xattr attr2 on file"
18156         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18157         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18158         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18159         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18160         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18161         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18162         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18163         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18164         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18165
18166         echo "Migrating to MDT1"
18167         $LFS migrate -m $MDTIDX $mig_dir ||
18168                 error "fails on migrating dir to MDT1"
18169
18170         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18171         echo "Checking xattrs"
18172         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18173         [ "$val" = $longstr ] ||
18174                 error "expecting xattr1 $longstr on dir, found $val"
18175         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18176         [ "$val" = $shortstr ] ||
18177                 error "expecting xattr2 $shortstr on dir, found $val"
18178         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18179         [ "$val" = $longstr ] ||
18180                 error "expecting xattr1 $longstr on file, found $val"
18181         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18182         [ "$val" = $shortstr ] ||
18183                 error "expecting xattr2 $shortstr on file, found $val"
18184 }
18185 run_test 230m "xattrs not changed after dir migration"
18186
18187 test_230n() {
18188         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18189         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18190                 skip "Need MDS version at least 2.13.53"
18191
18192         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18193         cat /etc/hosts > $DIR/$tdir/$tfile
18194         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18195         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18196
18197         cmp /etc/hosts $DIR/$tdir/$tfile ||
18198                 error "File data mismatch after migration"
18199 }
18200 run_test 230n "Dir migration with mirrored file"
18201
18202 test_230o() {
18203         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18204         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18205                 skip "Need MDS version at least 2.13.52"
18206
18207         local mdts=$(comma_list $(mdts_nodes))
18208         local timeout=100
18209
18210         local restripe_status
18211         local delta
18212         local i
18213         local j
18214
18215         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18216
18217         # in case "crush" hash type is not set
18218         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18219
18220         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18221                            mdt.*MDT0000.enable_dir_restripe)
18222         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18223         stack_trap "do_nodes $mdts $LCTL set_param \
18224                     mdt.*.enable_dir_restripe=$restripe_status"
18225
18226         mkdir $DIR/$tdir
18227         createmany -m $DIR/$tdir/f 100 ||
18228                 error "create files under remote dir failed $i"
18229         createmany -d $DIR/$tdir/d 100 ||
18230                 error "create dirs under remote dir failed $i"
18231
18232         for i in $(seq 2 $MDSCOUNT); do
18233                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18234                 $LFS setdirstripe -c $i $DIR/$tdir ||
18235                         error "split -c $i $tdir failed"
18236                 wait_update $HOSTNAME \
18237                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18238                         error "dir split not finished"
18239                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18240                         awk '/migrate/ {sum += $2} END { print sum }')
18241                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18242                 # delta is around total_files/stripe_count
18243                 [ $delta -lt $((200 /(i - 1))) ] ||
18244                         error "$delta files migrated"
18245         done
18246 }
18247 run_test 230o "dir split"
18248
18249 test_230p() {
18250         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18251         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18252                 skip "Need MDS version at least 2.13.52"
18253
18254         local mdts=$(comma_list $(mdts_nodes))
18255         local timeout=100
18256
18257         local restripe_status
18258         local delta
18259         local i
18260         local j
18261
18262         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18263
18264         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18265
18266         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18267                            mdt.*MDT0000.enable_dir_restripe)
18268         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18269         stack_trap "do_nodes $mdts $LCTL set_param \
18270                     mdt.*.enable_dir_restripe=$restripe_status"
18271
18272         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18273         createmany -m $DIR/$tdir/f 100 ||
18274                 error "create files under remote dir failed $i"
18275         createmany -d $DIR/$tdir/d 100 ||
18276                 error "create dirs under remote dir failed $i"
18277
18278         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18279                 local mdt_hash="crush"
18280
18281                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18282                 $LFS setdirstripe -c $i $DIR/$tdir ||
18283                         error "split -c $i $tdir failed"
18284                 [ $i -eq 1 ] && mdt_hash="none"
18285                 wait_update $HOSTNAME \
18286                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18287                         error "dir merge not finished"
18288                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18289                         awk '/migrate/ {sum += $2} END { print sum }')
18290                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18291                 # delta is around total_files/stripe_count
18292                 [ $delta -lt $((200 / i)) ] ||
18293                         error "$delta files migrated"
18294         done
18295 }
18296 run_test 230p "dir merge"
18297
18298 test_230q() {
18299         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18300         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18301                 skip "Need MDS version at least 2.13.52"
18302
18303         local mdts=$(comma_list $(mdts_nodes))
18304         local saved_threshold=$(do_facet mds1 \
18305                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18306         local saved_delta=$(do_facet mds1 \
18307                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18308         local threshold=100
18309         local delta=2
18310         local total=0
18311         local stripe_count=0
18312         local stripe_index
18313         local nr_files
18314
18315         stack_trap "do_nodes $mdts $LCTL set_param \
18316                     mdt.*.dir_split_count=$saved_threshold"
18317         stack_trap "do_nodes $mdts $LCTL set_param \
18318                     mdt.*.dir_split_delta=$saved_delta"
18319         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18320         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18321         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18322         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18323         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18324         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18325
18326         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18327         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18328
18329         while [ $stripe_count -lt $MDSCOUNT ]; do
18330                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18331                         error "create sub files failed"
18332                 stat $DIR/$tdir > /dev/null
18333                 total=$((total + threshold * 3 / 2))
18334                 stripe_count=$((stripe_count + delta))
18335                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18336
18337                 wait_update $HOSTNAME \
18338                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18339                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18340
18341                 wait_update $HOSTNAME \
18342                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18343                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18344
18345                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18346                            grep -w $stripe_index | wc -l)
18347                 echo "$nr_files files on MDT$stripe_index after split"
18348                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18349                         error "$nr_files files on MDT$stripe_index after split"
18350
18351                 nr_files=$(ls $DIR/$tdir | wc -w)
18352                 [ $nr_files -eq $total ] ||
18353                         error "total sub files $nr_files != $total"
18354         done
18355 }
18356 run_test 230q "dir auto split"
18357
18358 test_230r() {
18359         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18360         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18361         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18362                 skip "Need MDS version at least 2.13.54"
18363
18364         # maximum amount of local locks:
18365         # parent striped dir - 2 locks
18366         # new stripe in parent to migrate to - 1 lock
18367         # source and target - 2 locks
18368         # Total 5 locks for regular file
18369         mkdir -p $DIR/$tdir
18370         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18371         touch $DIR/$tdir/dir1/eee
18372
18373         # create 4 hardlink for 4 more locks
18374         # Total: 9 locks > RS_MAX_LOCKS (8)
18375         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18376         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18377         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18378         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18379         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18380         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18381         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18382         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18383
18384         cancel_lru_locks mdc
18385
18386         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18387                 error "migrate dir fails"
18388
18389         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18390 }
18391 run_test 230r "migrate with too many local locks"
18392
18393 test_231a()
18394 {
18395         # For simplicity this test assumes that max_pages_per_rpc
18396         # is the same across all OSCs
18397         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18398         local bulk_size=$((max_pages * PAGE_SIZE))
18399         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18400                                        head -n 1)
18401
18402         mkdir -p $DIR/$tdir
18403         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18404                 error "failed to set stripe with -S ${brw_size}M option"
18405
18406         # clear the OSC stats
18407         $LCTL set_param osc.*.stats=0 &>/dev/null
18408         stop_writeback
18409
18410         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18411         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18412                 oflag=direct &>/dev/null || error "dd failed"
18413
18414         sync; sleep 1; sync # just to be safe
18415         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18416         if [ x$nrpcs != "x1" ]; then
18417                 $LCTL get_param osc.*.stats
18418                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18419         fi
18420
18421         start_writeback
18422         # Drop the OSC cache, otherwise we will read from it
18423         cancel_lru_locks osc
18424
18425         # clear the OSC stats
18426         $LCTL set_param osc.*.stats=0 &>/dev/null
18427
18428         # Client reads $bulk_size.
18429         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18430                 iflag=direct &>/dev/null || error "dd failed"
18431
18432         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18433         if [ x$nrpcs != "x1" ]; then
18434                 $LCTL get_param osc.*.stats
18435                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18436         fi
18437 }
18438 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18439
18440 test_231b() {
18441         mkdir -p $DIR/$tdir
18442         local i
18443         for i in {0..1023}; do
18444                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18445                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18446                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18447         done
18448         sync
18449 }
18450 run_test 231b "must not assert on fully utilized OST request buffer"
18451
18452 test_232a() {
18453         mkdir -p $DIR/$tdir
18454         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18455
18456         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18457         do_facet ost1 $LCTL set_param fail_loc=0x31c
18458
18459         # ignore dd failure
18460         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18461
18462         do_facet ost1 $LCTL set_param fail_loc=0
18463         umount_client $MOUNT || error "umount failed"
18464         mount_client $MOUNT || error "mount failed"
18465         stop ost1 || error "cannot stop ost1"
18466         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18467 }
18468 run_test 232a "failed lock should not block umount"
18469
18470 test_232b() {
18471         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18472                 skip "Need MDS version at least 2.10.58"
18473
18474         mkdir -p $DIR/$tdir
18475         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18476         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18477         sync
18478         cancel_lru_locks osc
18479
18480         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18481         do_facet ost1 $LCTL set_param fail_loc=0x31c
18482
18483         # ignore failure
18484         $LFS data_version $DIR/$tdir/$tfile || true
18485
18486         do_facet ost1 $LCTL set_param fail_loc=0
18487         umount_client $MOUNT || error "umount failed"
18488         mount_client $MOUNT || error "mount failed"
18489         stop ost1 || error "cannot stop ost1"
18490         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18491 }
18492 run_test 232b "failed data version lock should not block umount"
18493
18494 test_233a() {
18495         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18496                 skip "Need MDS version at least 2.3.64"
18497         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18498
18499         local fid=$($LFS path2fid $MOUNT)
18500
18501         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18502                 error "cannot access $MOUNT using its FID '$fid'"
18503 }
18504 run_test 233a "checking that OBF of the FS root succeeds"
18505
18506 test_233b() {
18507         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18508                 skip "Need MDS version at least 2.5.90"
18509         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18510
18511         local fid=$($LFS path2fid $MOUNT/.lustre)
18512
18513         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18514                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18515
18516         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18517         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18518                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18519 }
18520 run_test 233b "checking that OBF of the FS .lustre succeeds"
18521
18522 test_234() {
18523         local p="$TMP/sanityN-$TESTNAME.parameters"
18524         save_lustre_params client "llite.*.xattr_cache" > $p
18525         lctl set_param llite.*.xattr_cache 1 ||
18526                 skip_env "xattr cache is not supported"
18527
18528         mkdir -p $DIR/$tdir || error "mkdir failed"
18529         touch $DIR/$tdir/$tfile || error "touch failed"
18530         # OBD_FAIL_LLITE_XATTR_ENOMEM
18531         $LCTL set_param fail_loc=0x1405
18532         getfattr -n user.attr $DIR/$tdir/$tfile &&
18533                 error "getfattr should have failed with ENOMEM"
18534         $LCTL set_param fail_loc=0x0
18535         rm -rf $DIR/$tdir
18536
18537         restore_lustre_params < $p
18538         rm -f $p
18539 }
18540 run_test 234 "xattr cache should not crash on ENOMEM"
18541
18542 test_235() {
18543         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18544                 skip "Need MDS version at least 2.4.52"
18545
18546         flock_deadlock $DIR/$tfile
18547         local RC=$?
18548         case $RC in
18549                 0)
18550                 ;;
18551                 124) error "process hangs on a deadlock"
18552                 ;;
18553                 *) error "error executing flock_deadlock $DIR/$tfile"
18554                 ;;
18555         esac
18556 }
18557 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18558
18559 #LU-2935
18560 test_236() {
18561         check_swap_layouts_support
18562
18563         local ref1=/etc/passwd
18564         local ref2=/etc/group
18565         local file1=$DIR/$tdir/f1
18566         local file2=$DIR/$tdir/f2
18567
18568         test_mkdir -c1 $DIR/$tdir
18569         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18570         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18571         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18572         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18573         local fd=$(free_fd)
18574         local cmd="exec $fd<>$file2"
18575         eval $cmd
18576         rm $file2
18577         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18578                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18579         cmd="exec $fd>&-"
18580         eval $cmd
18581         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18582
18583         #cleanup
18584         rm -rf $DIR/$tdir
18585 }
18586 run_test 236 "Layout swap on open unlinked file"
18587
18588 # LU-4659 linkea consistency
18589 test_238() {
18590         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18591                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18592                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18593                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18594
18595         touch $DIR/$tfile
18596         ln $DIR/$tfile $DIR/$tfile.lnk
18597         touch $DIR/$tfile.new
18598         mv $DIR/$tfile.new $DIR/$tfile
18599         local fid1=$($LFS path2fid $DIR/$tfile)
18600         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18601         local path1=$($LFS fid2path $FSNAME "$fid1")
18602         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18603         local path2=$($LFS fid2path $FSNAME "$fid2")
18604         [ $tfile.lnk == $path2 ] ||
18605                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18606         rm -f $DIR/$tfile*
18607 }
18608 run_test 238 "Verify linkea consistency"
18609
18610 test_239A() { # was test_239
18611         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18612                 skip "Need MDS version at least 2.5.60"
18613
18614         local list=$(comma_list $(mdts_nodes))
18615
18616         mkdir -p $DIR/$tdir
18617         createmany -o $DIR/$tdir/f- 5000
18618         unlinkmany $DIR/$tdir/f- 5000
18619         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18620                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18621         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18622                         osp.*MDT*.sync_in_flight" | calc_sum)
18623         [ "$changes" -eq 0 ] || error "$changes not synced"
18624 }
18625 run_test 239A "osp_sync test"
18626
18627 test_239a() { #LU-5297
18628         remote_mds_nodsh && skip "remote MDS with nodsh"
18629
18630         touch $DIR/$tfile
18631         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18632         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18633         chgrp $RUNAS_GID $DIR/$tfile
18634         wait_delete_completed
18635 }
18636 run_test 239a "process invalid osp sync record correctly"
18637
18638 test_239b() { #LU-5297
18639         remote_mds_nodsh && skip "remote MDS with nodsh"
18640
18641         touch $DIR/$tfile1
18642         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18643         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18644         chgrp $RUNAS_GID $DIR/$tfile1
18645         wait_delete_completed
18646         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18647         touch $DIR/$tfile2
18648         chgrp $RUNAS_GID $DIR/$tfile2
18649         wait_delete_completed
18650 }
18651 run_test 239b "process osp sync record with ENOMEM error correctly"
18652
18653 test_240() {
18654         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18655         remote_mds_nodsh && skip "remote MDS with nodsh"
18656
18657         mkdir -p $DIR/$tdir
18658
18659         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18660                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18661         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18662                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18663
18664         umount_client $MOUNT || error "umount failed"
18665         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18666         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18667         mount_client $MOUNT || error "failed to mount client"
18668
18669         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18670         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18671 }
18672 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18673
18674 test_241_bio() {
18675         local count=$1
18676         local bsize=$2
18677
18678         for LOOP in $(seq $count); do
18679                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18680                 cancel_lru_locks $OSC || true
18681         done
18682 }
18683
18684 test_241_dio() {
18685         local count=$1
18686         local bsize=$2
18687
18688         for LOOP in $(seq $1); do
18689                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18690                         2>/dev/null
18691         done
18692 }
18693
18694 test_241a() { # was test_241
18695         local bsize=$PAGE_SIZE
18696
18697         (( bsize < 40960 )) && bsize=40960
18698         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18699         ls -la $DIR/$tfile
18700         cancel_lru_locks $OSC
18701         test_241_bio 1000 $bsize &
18702         PID=$!
18703         test_241_dio 1000 $bsize
18704         wait $PID
18705 }
18706 run_test 241a "bio vs dio"
18707
18708 test_241b() {
18709         local bsize=$PAGE_SIZE
18710
18711         (( bsize < 40960 )) && bsize=40960
18712         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18713         ls -la $DIR/$tfile
18714         test_241_dio 1000 $bsize &
18715         PID=$!
18716         test_241_dio 1000 $bsize
18717         wait $PID
18718 }
18719 run_test 241b "dio vs dio"
18720
18721 test_242() {
18722         remote_mds_nodsh && skip "remote MDS with nodsh"
18723
18724         mkdir -p $DIR/$tdir
18725         touch $DIR/$tdir/$tfile
18726
18727         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18728         do_facet mds1 lctl set_param fail_loc=0x105
18729         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18730
18731         do_facet mds1 lctl set_param fail_loc=0
18732         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18733 }
18734 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18735
18736 test_243()
18737 {
18738         test_mkdir $DIR/$tdir
18739         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18740 }
18741 run_test 243 "various group lock tests"
18742
18743 test_244a()
18744 {
18745         test_mkdir $DIR/$tdir
18746         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18747         sendfile_grouplock $DIR/$tdir/$tfile || \
18748                 error "sendfile+grouplock failed"
18749         rm -rf $DIR/$tdir
18750 }
18751 run_test 244a "sendfile with group lock tests"
18752
18753 test_244b()
18754 {
18755         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18756
18757         local threads=50
18758         local size=$((1024*1024))
18759
18760         test_mkdir $DIR/$tdir
18761         for i in $(seq 1 $threads); do
18762                 local file=$DIR/$tdir/file_$((i / 10))
18763                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18764                 local pids[$i]=$!
18765         done
18766         for i in $(seq 1 $threads); do
18767                 wait ${pids[$i]}
18768         done
18769 }
18770 run_test 244b "multi-threaded write with group lock"
18771
18772 test_245() {
18773         local flagname="multi_mod_rpcs"
18774         local connect_data_name="max_mod_rpcs"
18775         local out
18776
18777         # check if multiple modify RPCs flag is set
18778         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18779                 grep "connect_flags:")
18780         echo "$out"
18781
18782         echo "$out" | grep -qw $flagname
18783         if [ $? -ne 0 ]; then
18784                 echo "connect flag $flagname is not set"
18785                 return
18786         fi
18787
18788         # check if multiple modify RPCs data is set
18789         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18790         echo "$out"
18791
18792         echo "$out" | grep -qw $connect_data_name ||
18793                 error "import should have connect data $connect_data_name"
18794 }
18795 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18796
18797 cleanup_247() {
18798         local submount=$1
18799
18800         trap 0
18801         umount_client $submount
18802         rmdir $submount
18803 }
18804
18805 test_247a() {
18806         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18807                 grep -q subtree ||
18808                 skip_env "Fileset feature is not supported"
18809
18810         local submount=${MOUNT}_$tdir
18811
18812         mkdir $MOUNT/$tdir
18813         mkdir -p $submount || error "mkdir $submount failed"
18814         FILESET="$FILESET/$tdir" mount_client $submount ||
18815                 error "mount $submount failed"
18816         trap "cleanup_247 $submount" EXIT
18817         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18818         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18819                 error "read $MOUNT/$tdir/$tfile failed"
18820         cleanup_247 $submount
18821 }
18822 run_test 247a "mount subdir as fileset"
18823
18824 test_247b() {
18825         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18826                 skip_env "Fileset feature is not supported"
18827
18828         local submount=${MOUNT}_$tdir
18829
18830         rm -rf $MOUNT/$tdir
18831         mkdir -p $submount || error "mkdir $submount failed"
18832         SKIP_FILESET=1
18833         FILESET="$FILESET/$tdir" mount_client $submount &&
18834                 error "mount $submount should fail"
18835         rmdir $submount
18836 }
18837 run_test 247b "mount subdir that dose not exist"
18838
18839 test_247c() {
18840         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18841                 skip_env "Fileset feature is not supported"
18842
18843         local submount=${MOUNT}_$tdir
18844
18845         mkdir -p $MOUNT/$tdir/dir1
18846         mkdir -p $submount || error "mkdir $submount failed"
18847         trap "cleanup_247 $submount" EXIT
18848         FILESET="$FILESET/$tdir" mount_client $submount ||
18849                 error "mount $submount failed"
18850         local fid=$($LFS path2fid $MOUNT/)
18851         $LFS fid2path $submount $fid && error "fid2path should fail"
18852         cleanup_247 $submount
18853 }
18854 run_test 247c "running fid2path outside subdirectory root"
18855
18856 test_247d() {
18857         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18858                 skip "Fileset feature is not supported"
18859
18860         local submount=${MOUNT}_$tdir
18861
18862         mkdir -p $MOUNT/$tdir/dir1
18863         mkdir -p $submount || error "mkdir $submount failed"
18864         FILESET="$FILESET/$tdir" mount_client $submount ||
18865                 error "mount $submount failed"
18866         trap "cleanup_247 $submount" EXIT
18867
18868         local td=$submount/dir1
18869         local fid=$($LFS path2fid $td)
18870         [ -z "$fid" ] && error "path2fid unable to get $td FID"
18871
18872         # check that we get the same pathname back
18873         local rootpath
18874         local found
18875         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
18876                 echo "$rootpath $fid"
18877                 found=$($LFS fid2path $rootpath "$fid")
18878                 [ -n "found" ] || error "fid2path should succeed"
18879                 [ "$found" == "$td" ] || error "fid2path $found != $td"
18880         done
18881         # check wrong root path format
18882         rootpath=$submount"_wrong"
18883         found=$($LFS fid2path $rootpath "$fid")
18884         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
18885
18886         cleanup_247 $submount
18887 }
18888 run_test 247d "running fid2path inside subdirectory root"
18889
18890 # LU-8037
18891 test_247e() {
18892         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18893                 grep -q subtree ||
18894                 skip "Fileset feature is not supported"
18895
18896         local submount=${MOUNT}_$tdir
18897
18898         mkdir $MOUNT/$tdir
18899         mkdir -p $submount || error "mkdir $submount failed"
18900         FILESET="$FILESET/.." mount_client $submount &&
18901                 error "mount $submount should fail"
18902         rmdir $submount
18903 }
18904 run_test 247e "mount .. as fileset"
18905
18906 test_247f() {
18907         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18908         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18909                 skip "Need at least version 2.13.52"
18910         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18911                 grep -q subtree ||
18912                 skip "Fileset feature is not supported"
18913
18914         mkdir $DIR/$tdir || error "mkdir $tdir failed"
18915         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
18916                 error "mkdir remote failed"
18917         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
18918         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
18919                 error "mkdir striped failed"
18920         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
18921
18922         local submount=${MOUNT}_$tdir
18923
18924         mkdir -p $submount || error "mkdir $submount failed"
18925
18926         local dir
18927         local fileset=$FILESET
18928
18929         for dir in $tdir/remote $tdir/remote/subdir \
18930                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
18931                 FILESET="$fileset/$dir" mount_client $submount ||
18932                         error "mount $dir failed"
18933                 umount_client $submount
18934         done
18935 }
18936 run_test 247f "mount striped or remote directory as fileset"
18937
18938 test_248a() {
18939         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
18940         [ -z "$fast_read_sav" ] && skip "no fast read support"
18941
18942         # create a large file for fast read verification
18943         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
18944
18945         # make sure the file is created correctly
18946         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
18947                 { rm -f $DIR/$tfile; skip "file creation error"; }
18948
18949         echo "Test 1: verify that fast read is 4 times faster on cache read"
18950
18951         # small read with fast read enabled
18952         $LCTL set_param -n llite.*.fast_read=1
18953         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18954                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18955                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18956         # small read with fast read disabled
18957         $LCTL set_param -n llite.*.fast_read=0
18958         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18959                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18960                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18961
18962         # verify that fast read is 4 times faster for cache read
18963         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
18964                 error_not_in_vm "fast read was not 4 times faster: " \
18965                            "$t_fast vs $t_slow"
18966
18967         echo "Test 2: verify the performance between big and small read"
18968         $LCTL set_param -n llite.*.fast_read=1
18969
18970         # 1k non-cache read
18971         cancel_lru_locks osc
18972         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18973                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18974                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18975
18976         # 1M non-cache read
18977         cancel_lru_locks osc
18978         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18979                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18980                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18981
18982         # verify that big IO is not 4 times faster than small IO
18983         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
18984                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
18985
18986         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
18987         rm -f $DIR/$tfile
18988 }
18989 run_test 248a "fast read verification"
18990
18991 test_248b() {
18992         # Default short_io_bytes=16384, try both smaller and larger sizes.
18993         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
18994         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
18995         echo "bs=53248 count=113 normal buffered write"
18996         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
18997                 error "dd of initial data file failed"
18998         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
18999
19000         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19001         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19002                 error "dd with sync normal writes failed"
19003         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19004
19005         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19006         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19007                 error "dd with sync small writes failed"
19008         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19009
19010         cancel_lru_locks osc
19011
19012         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19013         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19014         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19015         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19016                 iflag=direct || error "dd with O_DIRECT small read failed"
19017         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19018         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19019                 error "compare $TMP/$tfile.1 failed"
19020
19021         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19022         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19023
19024         # just to see what the maximum tunable value is, and test parsing
19025         echo "test invalid parameter 2MB"
19026         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19027                 error "too-large short_io_bytes allowed"
19028         echo "test maximum parameter 512KB"
19029         # if we can set a larger short_io_bytes, run test regardless of version
19030         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19031                 # older clients may not allow setting it this large, that's OK
19032                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19033                         skip "Need at least client version 2.13.50"
19034                 error "medium short_io_bytes failed"
19035         fi
19036         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19037         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19038
19039         echo "test large parameter 64KB"
19040         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19041         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19042
19043         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19044         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19045                 error "dd with sync large writes failed"
19046         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19047
19048         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19049         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19050         num=$((113 * 4096 / PAGE_SIZE))
19051         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19052         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19053                 error "dd with O_DIRECT large writes failed"
19054         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19055                 error "compare $DIR/$tfile.3 failed"
19056
19057         cancel_lru_locks osc
19058
19059         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19060         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19061                 error "dd with O_DIRECT large read failed"
19062         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19063                 error "compare $TMP/$tfile.2 failed"
19064
19065         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19066         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19067                 error "dd with O_DIRECT large read failed"
19068         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19069                 error "compare $TMP/$tfile.3 failed"
19070 }
19071 run_test 248b "test short_io read and write for both small and large sizes"
19072
19073 test_249() { # LU-7890
19074         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19075                 skip "Need at least version 2.8.54"
19076
19077         rm -f $DIR/$tfile
19078         $LFS setstripe -c 1 $DIR/$tfile
19079         # Offset 2T == 4k * 512M
19080         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19081                 error "dd to 2T offset failed"
19082 }
19083 run_test 249 "Write above 2T file size"
19084
19085 test_250() {
19086         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19087          && skip "no 16TB file size limit on ZFS"
19088
19089         $LFS setstripe -c 1 $DIR/$tfile
19090         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19091         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19092         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19093         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19094                 conv=notrunc,fsync && error "append succeeded"
19095         return 0
19096 }
19097 run_test 250 "Write above 16T limit"
19098
19099 test_251() {
19100         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19101
19102         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19103         #Skip once - writing the first stripe will succeed
19104         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19105         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19106                 error "short write happened"
19107
19108         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19109         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19110                 error "short read happened"
19111
19112         rm -f $DIR/$tfile
19113 }
19114 run_test 251 "Handling short read and write correctly"
19115
19116 test_252() {
19117         remote_mds_nodsh && skip "remote MDS with nodsh"
19118         remote_ost_nodsh && skip "remote OST with nodsh"
19119         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19120                 skip_env "ldiskfs only test"
19121         fi
19122
19123         local tgt
19124         local dev
19125         local out
19126         local uuid
19127         local num
19128         local gen
19129
19130         # check lr_reader on OST0000
19131         tgt=ost1
19132         dev=$(facet_device $tgt)
19133         out=$(do_facet $tgt $LR_READER $dev)
19134         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19135         echo "$out"
19136         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19137         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19138                 error "Invalid uuid returned by $LR_READER on target $tgt"
19139         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19140
19141         # check lr_reader -c on MDT0000
19142         tgt=mds1
19143         dev=$(facet_device $tgt)
19144         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19145                 skip "$LR_READER does not support additional options"
19146         fi
19147         out=$(do_facet $tgt $LR_READER -c $dev)
19148         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19149         echo "$out"
19150         num=$(echo "$out" | grep -c "mdtlov")
19151         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19152                 error "Invalid number of mdtlov clients returned by $LR_READER"
19153         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19154
19155         # check lr_reader -cr on MDT0000
19156         out=$(do_facet $tgt $LR_READER -cr $dev)
19157         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19158         echo "$out"
19159         echo "$out" | grep -q "^reply_data:$" ||
19160                 error "$LR_READER should have returned 'reply_data' section"
19161         num=$(echo "$out" | grep -c "client_generation")
19162         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19163 }
19164 run_test 252 "check lr_reader tool"
19165
19166 test_253() {
19167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19168         remote_mds_nodsh && skip "remote MDS with nodsh"
19169         remote_mgs_nodsh && skip "remote MGS with nodsh"
19170
19171         local ostidx=0
19172         local rc=0
19173         local ost_name=$(ostname_from_index $ostidx)
19174
19175         # on the mdt's osc
19176         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19177         do_facet $SINGLEMDS $LCTL get_param -n \
19178                 osp.$mdtosc_proc1.reserved_mb_high ||
19179                 skip  "remote MDS does not support reserved_mb_high"
19180
19181         rm -rf $DIR/$tdir
19182         wait_mds_ost_sync
19183         wait_delete_completed
19184         mkdir $DIR/$tdir
19185
19186         pool_add $TESTNAME || error "Pool creation failed"
19187         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19188
19189         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19190                 error "Setstripe failed"
19191
19192         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19193
19194         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19195                     grep "watermarks")
19196         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19197
19198         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19199                         osp.$mdtosc_proc1.prealloc_status)
19200         echo "prealloc_status $oa_status"
19201
19202         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19203                 error "File creation should fail"
19204
19205         #object allocation was stopped, but we still able to append files
19206         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19207                 oflag=append || error "Append failed"
19208
19209         rm -f $DIR/$tdir/$tfile.0
19210
19211         # For this test, we want to delete the files we created to go out of
19212         # space but leave the watermark, so we remain nearly out of space
19213         ost_watermarks_enospc_delete_files $tfile $ostidx
19214
19215         wait_delete_completed
19216
19217         sleep_maxage
19218
19219         for i in $(seq 10 12); do
19220                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19221                         2>/dev/null || error "File creation failed after rm"
19222         done
19223
19224         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19225                         osp.$mdtosc_proc1.prealloc_status)
19226         echo "prealloc_status $oa_status"
19227
19228         if (( oa_status != 0 )); then
19229                 error "Object allocation still disable after rm"
19230         fi
19231 }
19232 run_test 253 "Check object allocation limit"
19233
19234 test_254() {
19235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19236         remote_mds_nodsh && skip "remote MDS with nodsh"
19237         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19238                 skip "MDS does not support changelog_size"
19239
19240         local cl_user
19241         local MDT0=$(facet_svc $SINGLEMDS)
19242
19243         changelog_register || error "changelog_register failed"
19244
19245         changelog_clear 0 || error "changelog_clear failed"
19246
19247         local size1=$(do_facet $SINGLEMDS \
19248                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19249         echo "Changelog size $size1"
19250
19251         rm -rf $DIR/$tdir
19252         $LFS mkdir -i 0 $DIR/$tdir
19253         # change something
19254         mkdir -p $DIR/$tdir/pics/2008/zachy
19255         touch $DIR/$tdir/pics/2008/zachy/timestamp
19256         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19257         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19258         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19259         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19260         rm $DIR/$tdir/pics/desktop.jpg
19261
19262         local size2=$(do_facet $SINGLEMDS \
19263                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19264         echo "Changelog size after work $size2"
19265
19266         (( $size2 > $size1 )) ||
19267                 error "new Changelog size=$size2 less than old size=$size1"
19268 }
19269 run_test 254 "Check changelog size"
19270
19271 ladvise_no_type()
19272 {
19273         local type=$1
19274         local file=$2
19275
19276         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19277                 awk -F: '{print $2}' | grep $type > /dev/null
19278         if [ $? -ne 0 ]; then
19279                 return 0
19280         fi
19281         return 1
19282 }
19283
19284 ladvise_no_ioctl()
19285 {
19286         local file=$1
19287
19288         lfs ladvise -a willread $file > /dev/null 2>&1
19289         if [ $? -eq 0 ]; then
19290                 return 1
19291         fi
19292
19293         lfs ladvise -a willread $file 2>&1 |
19294                 grep "Inappropriate ioctl for device" > /dev/null
19295         if [ $? -eq 0 ]; then
19296                 return 0
19297         fi
19298         return 1
19299 }
19300
19301 percent() {
19302         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19303 }
19304
19305 # run a random read IO workload
19306 # usage: random_read_iops <filename> <filesize> <iosize>
19307 random_read_iops() {
19308         local file=$1
19309         local fsize=$2
19310         local iosize=${3:-4096}
19311
19312         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19313                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19314 }
19315
19316 drop_file_oss_cache() {
19317         local file="$1"
19318         local nodes="$2"
19319
19320         $LFS ladvise -a dontneed $file 2>/dev/null ||
19321                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19322 }
19323
19324 ladvise_willread_performance()
19325 {
19326         local repeat=10
19327         local average_origin=0
19328         local average_cache=0
19329         local average_ladvise=0
19330
19331         for ((i = 1; i <= $repeat; i++)); do
19332                 echo "Iter $i/$repeat: reading without willread hint"
19333                 cancel_lru_locks osc
19334                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19335                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19336                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19337                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19338
19339                 cancel_lru_locks osc
19340                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19341                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19342                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19343
19344                 cancel_lru_locks osc
19345                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19346                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19347                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19348                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19349                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19350         done
19351         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19352         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19353         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19354
19355         speedup_cache=$(percent $average_cache $average_origin)
19356         speedup_ladvise=$(percent $average_ladvise $average_origin)
19357
19358         echo "Average uncached read: $average_origin"
19359         echo "Average speedup with OSS cached read: " \
19360                 "$average_cache = +$speedup_cache%"
19361         echo "Average speedup with ladvise willread: " \
19362                 "$average_ladvise = +$speedup_ladvise%"
19363
19364         local lowest_speedup=20
19365         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19366                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19367                         "got $average_cache%. Skipping ladvise willread check."
19368                 return 0
19369         fi
19370
19371         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19372         # it is still good to run until then to exercise 'ladvise willread'
19373         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19374                 [ "$ost1_FSTYPE" = "zfs" ] &&
19375                 echo "osd-zfs does not support dontneed or drop_caches" &&
19376                 return 0
19377
19378         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19379         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19380                 error_not_in_vm "Speedup with willread is less than " \
19381                         "$lowest_speedup%, got $average_ladvise%"
19382 }
19383
19384 test_255a() {
19385         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19386                 skip "lustre < 2.8.54 does not support ladvise "
19387         remote_ost_nodsh && skip "remote OST with nodsh"
19388
19389         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19390
19391         ladvise_no_type willread $DIR/$tfile &&
19392                 skip "willread ladvise is not supported"
19393
19394         ladvise_no_ioctl $DIR/$tfile &&
19395                 skip "ladvise ioctl is not supported"
19396
19397         local size_mb=100
19398         local size=$((size_mb * 1048576))
19399         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19400                 error "dd to $DIR/$tfile failed"
19401
19402         lfs ladvise -a willread $DIR/$tfile ||
19403                 error "Ladvise failed with no range argument"
19404
19405         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19406                 error "Ladvise failed with no -l or -e argument"
19407
19408         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19409                 error "Ladvise failed with only -e argument"
19410
19411         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19412                 error "Ladvise failed with only -l argument"
19413
19414         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19415                 error "End offset should not be smaller than start offset"
19416
19417         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19418                 error "End offset should not be equal to start offset"
19419
19420         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19421                 error "Ladvise failed with overflowing -s argument"
19422
19423         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19424                 error "Ladvise failed with overflowing -e argument"
19425
19426         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19427                 error "Ladvise failed with overflowing -l argument"
19428
19429         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19430                 error "Ladvise succeeded with conflicting -l and -e arguments"
19431
19432         echo "Synchronous ladvise should wait"
19433         local delay=4
19434 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19435         do_nodes $(comma_list $(osts_nodes)) \
19436                 $LCTL set_param fail_val=$delay fail_loc=0x237
19437
19438         local start_ts=$SECONDS
19439         lfs ladvise -a willread $DIR/$tfile ||
19440                 error "Ladvise failed with no range argument"
19441         local end_ts=$SECONDS
19442         local inteval_ts=$((end_ts - start_ts))
19443
19444         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19445                 error "Synchronous advice didn't wait reply"
19446         fi
19447
19448         echo "Asynchronous ladvise shouldn't wait"
19449         local start_ts=$SECONDS
19450         lfs ladvise -a willread -b $DIR/$tfile ||
19451                 error "Ladvise failed with no range argument"
19452         local end_ts=$SECONDS
19453         local inteval_ts=$((end_ts - start_ts))
19454
19455         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19456                 error "Asynchronous advice blocked"
19457         fi
19458
19459         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19460         ladvise_willread_performance
19461 }
19462 run_test 255a "check 'lfs ladvise -a willread'"
19463
19464 facet_meminfo() {
19465         local facet=$1
19466         local info=$2
19467
19468         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19469 }
19470
19471 test_255b() {
19472         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19473                 skip "lustre < 2.8.54 does not support ladvise "
19474         remote_ost_nodsh && skip "remote OST with nodsh"
19475
19476         lfs setstripe -c 1 -i 0 $DIR/$tfile
19477
19478         ladvise_no_type dontneed $DIR/$tfile &&
19479                 skip "dontneed ladvise is not supported"
19480
19481         ladvise_no_ioctl $DIR/$tfile &&
19482                 skip "ladvise ioctl is not supported"
19483
19484         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19485                 [ "$ost1_FSTYPE" = "zfs" ] &&
19486                 skip "zfs-osd does not support 'ladvise dontneed'"
19487
19488         local size_mb=100
19489         local size=$((size_mb * 1048576))
19490         # In order to prevent disturbance of other processes, only check 3/4
19491         # of the memory usage
19492         local kibibytes=$((size_mb * 1024 * 3 / 4))
19493
19494         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19495                 error "dd to $DIR/$tfile failed"
19496
19497         #force write to complete before dropping OST cache & checking memory
19498         sync
19499
19500         local total=$(facet_meminfo ost1 MemTotal)
19501         echo "Total memory: $total KiB"
19502
19503         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19504         local before_read=$(facet_meminfo ost1 Cached)
19505         echo "Cache used before read: $before_read KiB"
19506
19507         lfs ladvise -a willread $DIR/$tfile ||
19508                 error "Ladvise willread failed"
19509         local after_read=$(facet_meminfo ost1 Cached)
19510         echo "Cache used after read: $after_read KiB"
19511
19512         lfs ladvise -a dontneed $DIR/$tfile ||
19513                 error "Ladvise dontneed again failed"
19514         local no_read=$(facet_meminfo ost1 Cached)
19515         echo "Cache used after dontneed ladvise: $no_read KiB"
19516
19517         if [ $total -lt $((before_read + kibibytes)) ]; then
19518                 echo "Memory is too small, abort checking"
19519                 return 0
19520         fi
19521
19522         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19523                 error "Ladvise willread should use more memory" \
19524                         "than $kibibytes KiB"
19525         fi
19526
19527         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19528                 error "Ladvise dontneed should release more memory" \
19529                         "than $kibibytes KiB"
19530         fi
19531 }
19532 run_test 255b "check 'lfs ladvise -a dontneed'"
19533
19534 test_255c() {
19535         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19536                 skip "lustre < 2.10.50 does not support lockahead"
19537
19538         local count
19539         local new_count
19540         local difference
19541         local i
19542         local rc
19543
19544         test_mkdir -p $DIR/$tdir
19545         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19546
19547         #test 10 returns only success/failure
19548         i=10
19549         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19550         rc=$?
19551         if [ $rc -eq 255 ]; then
19552                 error "Ladvise test${i} failed, ${rc}"
19553         fi
19554
19555         #test 11 counts lock enqueue requests, all others count new locks
19556         i=11
19557         count=$(do_facet ost1 \
19558                 $LCTL get_param -n ost.OSS.ost.stats)
19559         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19560
19561         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19562         rc=$?
19563         if [ $rc -eq 255 ]; then
19564                 error "Ladvise test${i} failed, ${rc}"
19565         fi
19566
19567         new_count=$(do_facet ost1 \
19568                 $LCTL get_param -n ost.OSS.ost.stats)
19569         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19570                    awk '{ print $2 }')
19571
19572         difference="$((new_count - count))"
19573         if [ $difference -ne $rc ]; then
19574                 error "Ladvise test${i}, bad enqueue count, returned " \
19575                       "${rc}, actual ${difference}"
19576         fi
19577
19578         for i in $(seq 12 21); do
19579                 # If we do not do this, we run the risk of having too many
19580                 # locks and starting lock cancellation while we are checking
19581                 # lock counts.
19582                 cancel_lru_locks osc
19583
19584                 count=$($LCTL get_param -n \
19585                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19586
19587                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19588                 rc=$?
19589                 if [ $rc -eq 255 ]; then
19590                         error "Ladvise test ${i} failed, ${rc}"
19591                 fi
19592
19593                 new_count=$($LCTL get_param -n \
19594                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19595                 difference="$((new_count - count))"
19596
19597                 # Test 15 output is divided by 100 to map down to valid return
19598                 if [ $i -eq 15 ]; then
19599                         rc="$((rc * 100))"
19600                 fi
19601
19602                 if [ $difference -ne $rc ]; then
19603                         error "Ladvise test ${i}, bad lock count, returned " \
19604                               "${rc}, actual ${difference}"
19605                 fi
19606         done
19607
19608         #test 22 returns only success/failure
19609         i=22
19610         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19611         rc=$?
19612         if [ $rc -eq 255 ]; then
19613                 error "Ladvise test${i} failed, ${rc}"
19614         fi
19615 }
19616 run_test 255c "suite of ladvise lockahead tests"
19617
19618 test_256() {
19619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19620         remote_mds_nodsh && skip "remote MDS with nodsh"
19621         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19622         changelog_users $SINGLEMDS | grep "^cl" &&
19623                 skip "active changelog user"
19624
19625         local cl_user
19626         local cat_sl
19627         local mdt_dev
19628
19629         mdt_dev=$(mdsdevname 1)
19630         echo $mdt_dev
19631
19632         changelog_register || error "changelog_register failed"
19633
19634         rm -rf $DIR/$tdir
19635         mkdir -p $DIR/$tdir
19636
19637         changelog_clear 0 || error "changelog_clear failed"
19638
19639         # change something
19640         touch $DIR/$tdir/{1..10}
19641
19642         # stop the MDT
19643         stop $SINGLEMDS || error "Fail to stop MDT"
19644
19645         # remount the MDT
19646
19647         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19648
19649         #after mount new plainllog is used
19650         touch $DIR/$tdir/{11..19}
19651         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19652         stack_trap "rm -f $tmpfile"
19653         cat_sl=$(do_facet $SINGLEMDS "sync; \
19654                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19655                  llog_reader $tmpfile | grep -c type=1064553b")
19656         do_facet $SINGLEMDS llog_reader $tmpfile
19657
19658         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19659
19660         changelog_clear 0 || error "changelog_clear failed"
19661
19662         cat_sl=$(do_facet $SINGLEMDS "sync; \
19663                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19664                  llog_reader $tmpfile | grep -c type=1064553b")
19665
19666         if (( cat_sl == 2 )); then
19667                 error "Empty plain llog was not deleted from changelog catalog"
19668         elif (( cat_sl != 1 )); then
19669                 error "Active plain llog shouldn't be deleted from catalog"
19670         fi
19671 }
19672 run_test 256 "Check llog delete for empty and not full state"
19673
19674 test_257() {
19675         remote_mds_nodsh && skip "remote MDS with nodsh"
19676         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19677                 skip "Need MDS version at least 2.8.55"
19678
19679         test_mkdir $DIR/$tdir
19680
19681         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19682                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19683         stat $DIR/$tdir
19684
19685 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19686         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19687         local facet=mds$((mdtidx + 1))
19688         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19689         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19690
19691         stop $facet || error "stop MDS failed"
19692         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19693                 error "start MDS fail"
19694         wait_recovery_complete $facet
19695 }
19696 run_test 257 "xattr locks are not lost"
19697
19698 # Verify we take the i_mutex when security requires it
19699 test_258a() {
19700 #define OBD_FAIL_IMUTEX_SEC 0x141c
19701         $LCTL set_param fail_loc=0x141c
19702         touch $DIR/$tfile
19703         chmod u+s $DIR/$tfile
19704         chmod a+rwx $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, failed to take i_mutex, rc=$?"
19709         fi
19710         rm -f $DIR/$tfile
19711 }
19712 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19713
19714 # Verify we do NOT take the i_mutex in the normal case
19715 test_258b() {
19716 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19717         $LCTL set_param fail_loc=0x141d
19718         touch $DIR/$tfile
19719         chmod a+rwx $DIR
19720         chmod a+rw $DIR/$tfile
19721         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19722         RC=$?
19723         if [ $RC -ne 0 ]; then
19724                 error "error, took i_mutex unnecessarily, rc=$?"
19725         fi
19726         rm -f $DIR/$tfile
19727
19728 }
19729 run_test 258b "verify i_mutex security behavior"
19730
19731 test_259() {
19732         local file=$DIR/$tfile
19733         local before
19734         local after
19735
19736         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19737
19738         stack_trap "rm -f $file" EXIT
19739
19740         wait_delete_completed
19741         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19742         echo "before: $before"
19743
19744         $LFS setstripe -i 0 -c 1 $file
19745         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19746         sync_all_data
19747         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19748         echo "after write: $after"
19749
19750 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19751         do_facet ost1 $LCTL set_param fail_loc=0x2301
19752         $TRUNCATE $file 0
19753         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19754         echo "after truncate: $after"
19755
19756         stop ost1
19757         do_facet ost1 $LCTL set_param fail_loc=0
19758         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19759         sleep 2
19760         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19761         echo "after restart: $after"
19762         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19763                 error "missing truncate?"
19764
19765         return 0
19766 }
19767 run_test 259 "crash at delayed truncate"
19768
19769 test_260() {
19770 #define OBD_FAIL_MDC_CLOSE               0x806
19771         $LCTL set_param fail_loc=0x80000806
19772         touch $DIR/$tfile
19773
19774 }
19775 run_test 260 "Check mdc_close fail"
19776
19777 ### Data-on-MDT sanity tests ###
19778 test_270a() {
19779         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19780                 skip "Need MDS version at least 2.10.55 for DoM"
19781
19782         # create DoM file
19783         local dom=$DIR/$tdir/dom_file
19784         local tmp=$DIR/$tdir/tmp_file
19785
19786         mkdir -p $DIR/$tdir
19787
19788         # basic checks for DoM component creation
19789         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19790                 error "Can set MDT layout to non-first entry"
19791
19792         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19793                 error "Can define multiple entries as MDT layout"
19794
19795         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19796
19797         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19798         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19799         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19800
19801         local mdtidx=$($LFS getstripe -m $dom)
19802         local mdtname=MDT$(printf %04x $mdtidx)
19803         local facet=mds$((mdtidx + 1))
19804         local space_check=1
19805
19806         # Skip free space checks with ZFS
19807         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19808
19809         # write
19810         sync
19811         local size_tmp=$((65536 * 3))
19812         local mdtfree1=$(do_facet $facet \
19813                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19814
19815         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19816         # check also direct IO along write
19817         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19818         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19819         sync
19820         cmp $tmp $dom || error "file data is different"
19821         [ $(stat -c%s $dom) == $size_tmp ] ||
19822                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19823         if [ $space_check == 1 ]; then
19824                 local mdtfree2=$(do_facet $facet \
19825                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19826
19827                 # increase in usage from by $size_tmp
19828                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19829                         error "MDT free space wrong after write: " \
19830                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19831         fi
19832
19833         # truncate
19834         local size_dom=10000
19835
19836         $TRUNCATE $dom $size_dom
19837         [ $(stat -c%s $dom) == $size_dom ] ||
19838                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19839         if [ $space_check == 1 ]; then
19840                 mdtfree1=$(do_facet $facet \
19841                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19842                 # decrease in usage from $size_tmp to new $size_dom
19843                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19844                   $(((size_tmp - size_dom) / 1024)) ] ||
19845                         error "MDT free space is wrong after truncate: " \
19846                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19847         fi
19848
19849         # append
19850         cat $tmp >> $dom
19851         sync
19852         size_dom=$((size_dom + size_tmp))
19853         [ $(stat -c%s $dom) == $size_dom ] ||
19854                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19855         if [ $space_check == 1 ]; then
19856                 mdtfree2=$(do_facet $facet \
19857                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19858                 # increase in usage by $size_tmp from previous
19859                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19860                         error "MDT free space is wrong after append: " \
19861                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19862         fi
19863
19864         # delete
19865         rm $dom
19866         if [ $space_check == 1 ]; then
19867                 mdtfree1=$(do_facet $facet \
19868                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19869                 # decrease in usage by $size_dom from previous
19870                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
19871                         error "MDT free space is wrong after removal: " \
19872                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
19873         fi
19874
19875         # combined striping
19876         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
19877                 error "Can't create DoM + OST striping"
19878
19879         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
19880         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19881         # check also direct IO along write
19882         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19883         sync
19884         cmp $tmp $dom || error "file data is different"
19885         [ $(stat -c%s $dom) == $size_tmp ] ||
19886                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19887         rm $dom $tmp
19888
19889         return 0
19890 }
19891 run_test 270a "DoM: basic functionality tests"
19892
19893 test_270b() {
19894         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19895                 skip "Need MDS version at least 2.10.55"
19896
19897         local dom=$DIR/$tdir/dom_file
19898         local max_size=1048576
19899
19900         mkdir -p $DIR/$tdir
19901         $LFS setstripe -E $max_size -L mdt $dom
19902
19903         # truncate over the limit
19904         $TRUNCATE $dom $(($max_size + 1)) &&
19905                 error "successful truncate over the maximum size"
19906         # write over the limit
19907         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
19908                 error "successful write over the maximum size"
19909         # append over the limit
19910         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
19911         echo "12345" >> $dom && error "successful append over the maximum size"
19912         rm $dom
19913
19914         return 0
19915 }
19916 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
19917
19918 test_270c() {
19919         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19920                 skip "Need MDS version at least 2.10.55"
19921
19922         mkdir -p $DIR/$tdir
19923         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19924
19925         # check files inherit DoM EA
19926         touch $DIR/$tdir/first
19927         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
19928                 error "bad pattern"
19929         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
19930                 error "bad stripe count"
19931         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
19932                 error "bad stripe size"
19933
19934         # check directory inherits DoM EA and uses it as default
19935         mkdir $DIR/$tdir/subdir
19936         touch $DIR/$tdir/subdir/second
19937         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
19938                 error "bad pattern in sub-directory"
19939         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
19940                 error "bad stripe count in sub-directory"
19941         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
19942                 error "bad stripe size in sub-directory"
19943         return 0
19944 }
19945 run_test 270c "DoM: DoM EA inheritance tests"
19946
19947 test_270d() {
19948         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19949                 skip "Need MDS version at least 2.10.55"
19950
19951         mkdir -p $DIR/$tdir
19952         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19953
19954         # inherit default DoM striping
19955         mkdir $DIR/$tdir/subdir
19956         touch $DIR/$tdir/subdir/f1
19957
19958         # change default directory striping
19959         $LFS setstripe -c 1 $DIR/$tdir/subdir
19960         touch $DIR/$tdir/subdir/f2
19961         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
19962                 error "wrong default striping in file 2"
19963         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
19964                 error "bad pattern in file 2"
19965         return 0
19966 }
19967 run_test 270d "DoM: change striping from DoM to RAID0"
19968
19969 test_270e() {
19970         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19971                 skip "Need MDS version at least 2.10.55"
19972
19973         mkdir -p $DIR/$tdir/dom
19974         mkdir -p $DIR/$tdir/norm
19975         DOMFILES=20
19976         NORMFILES=10
19977         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
19978         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
19979
19980         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
19981         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
19982
19983         # find DoM files by layout
19984         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
19985         [ $NUM -eq  $DOMFILES ] ||
19986                 error "lfs find -L: found $NUM, expected $DOMFILES"
19987         echo "Test 1: lfs find 20 DOM files by layout: OK"
19988
19989         # there should be 1 dir with default DOM striping
19990         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
19991         [ $NUM -eq  1 ] ||
19992                 error "lfs find -L: found $NUM, expected 1 dir"
19993         echo "Test 2: lfs find 1 DOM dir by layout: OK"
19994
19995         # find DoM files by stripe size
19996         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
19997         [ $NUM -eq  $DOMFILES ] ||
19998                 error "lfs find -S: found $NUM, expected $DOMFILES"
19999         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20000
20001         # find files by stripe offset except DoM files
20002         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20003         [ $NUM -eq  $NORMFILES ] ||
20004                 error "lfs find -i: found $NUM, expected $NORMFILES"
20005         echo "Test 5: lfs find no DOM files by stripe index: OK"
20006         return 0
20007 }
20008 run_test 270e "DoM: lfs find with DoM files test"
20009
20010 test_270f() {
20011         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20012                 skip "Need MDS version at least 2.10.55"
20013
20014         local mdtname=${FSNAME}-MDT0000-mdtlov
20015         local dom=$DIR/$tdir/dom_file
20016         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20017                                                 lod.$mdtname.dom_stripesize)
20018         local dom_limit=131072
20019
20020         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20021         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20022                                                 lod.$mdtname.dom_stripesize)
20023         [ ${dom_limit} -eq ${dom_current} ] ||
20024                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20025
20026         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20027         $LFS setstripe -d $DIR/$tdir
20028         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20029                 error "Can't set directory default striping"
20030
20031         # exceed maximum stripe size
20032         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20033                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20034         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20035                 error "Able to create DoM component size more than LOD limit"
20036
20037         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20038         dom_current=$(do_facet mds1 $LCTL get_param -n \
20039                                                 lod.$mdtname.dom_stripesize)
20040         [ 0 -eq ${dom_current} ] ||
20041                 error "Can't set zero DoM stripe limit"
20042         rm $dom
20043
20044         # attempt to create DoM file on server with disabled DoM should
20045         # remove DoM entry from layout and be succeed
20046         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20047                 error "Can't create DoM file (DoM is disabled)"
20048         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20049                 error "File has DoM component while DoM is disabled"
20050         rm $dom
20051
20052         # attempt to create DoM file with only DoM stripe should return error
20053         $LFS setstripe -E $dom_limit -L mdt $dom &&
20054                 error "Able to create DoM-only file while DoM is disabled"
20055
20056         # too low values to be aligned with smallest stripe size 64K
20057         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20058         dom_current=$(do_facet mds1 $LCTL get_param -n \
20059                                                 lod.$mdtname.dom_stripesize)
20060         [ 30000 -eq ${dom_current} ] &&
20061                 error "Can set too small DoM stripe limit"
20062
20063         # 64K is a minimal stripe size in Lustre, expect limit of that size
20064         [ 65536 -eq ${dom_current} ] ||
20065                 error "Limit is not set to 64K but ${dom_current}"
20066
20067         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20068         dom_current=$(do_facet mds1 $LCTL get_param -n \
20069                                                 lod.$mdtname.dom_stripesize)
20070         echo $dom_current
20071         [ 2147483648 -eq ${dom_current} ] &&
20072                 error "Can set too large DoM stripe limit"
20073
20074         do_facet mds1 $LCTL set_param -n \
20075                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20076         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20077                 error "Can't create DoM component size after limit change"
20078         do_facet mds1 $LCTL set_param -n \
20079                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20080         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20081                 error "Can't create DoM file after limit decrease"
20082         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20083                 error "Can create big DoM component after limit decrease"
20084         touch ${dom}_def ||
20085                 error "Can't create file with old default layout"
20086
20087         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20088         return 0
20089 }
20090 run_test 270f "DoM: maximum DoM stripe size checks"
20091
20092 test_270g() {
20093         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20094                 skip "Need MDS version at least 2.13.52"
20095         local dom=$DIR/$tdir/$tfile
20096
20097         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20098         local lodname=${FSNAME}-MDT0000-mdtlov
20099
20100         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20101         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20102         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20103         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20104
20105         local dom_limit=1024
20106         local dom_threshold="50%"
20107
20108         $LFS setstripe -d $DIR/$tdir
20109         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20110                 error "Can't set directory default striping"
20111
20112         do_facet mds1 $LCTL set_param -n \
20113                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20114         # set 0 threshold and create DOM file to change tunable stripesize
20115         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20116         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20117                 error "Failed to create $dom file"
20118         # now tunable dom_cur_stripesize should reach maximum
20119         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20120                                         lod.${lodname}.dom_stripesize_cur_kb)
20121         [[ $dom_current == $dom_limit ]] ||
20122                 error "Current DOM stripesize is not maximum"
20123         rm $dom
20124
20125         # set threshold for further tests
20126         do_facet mds1 $LCTL set_param -n \
20127                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20128         echo "DOM threshold is $dom_threshold free space"
20129         local dom_def
20130         local dom_set
20131         # Spoof bfree to exceed threshold
20132         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20133         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20134         for spfree in 40 20 0 15 30 55; do
20135                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20136                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20137                         error "Failed to create $dom file"
20138                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20139                                         lod.${lodname}.dom_stripesize_cur_kb)
20140                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20141                 [[ $dom_def != $dom_current ]] ||
20142                         error "Default stripe size was not changed"
20143                 if [[ $spfree > 0 ]] ; then
20144                         dom_set=$($LFS getstripe -S $dom)
20145                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20146                                 error "DOM component size is still old"
20147                 else
20148                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20149                                 error "DoM component is set with no free space"
20150                 fi
20151                 rm $dom
20152                 dom_current=$dom_def
20153         done
20154 }
20155 run_test 270g "DoM: default DoM stripe size depends on free space"
20156
20157 test_270h() {
20158         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20159                 skip "Need MDS version at least 2.13.53"
20160
20161         local mdtname=${FSNAME}-MDT0000-mdtlov
20162         local dom=$DIR/$tdir/$tfile
20163         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20164
20165         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20166         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20167
20168         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20169         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20170                 error "can't create OST file"
20171         # mirrored file with DOM entry in the second mirror
20172         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20173                 error "can't create mirror with DoM component"
20174
20175         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20176
20177         # DOM component in the middle and has other enries in the same mirror,
20178         # should succeed but lost DoM component
20179         $LFS setstripe --copy=${dom}_1 $dom ||
20180                 error "Can't create file from OST|DOM mirror layout"
20181         # check new file has no DoM layout after all
20182         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20183                 error "File has DoM component while DoM is disabled"
20184 }
20185 run_test 270h "DoM: DoM stripe removal when disabled on server"
20186
20187 test_271a() {
20188         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20189                 skip "Need MDS version at least 2.10.55"
20190
20191         local dom=$DIR/$tdir/dom
20192
20193         mkdir -p $DIR/$tdir
20194
20195         $LFS setstripe -E 1024K -L mdt $dom
20196
20197         lctl set_param -n mdc.*.stats=clear
20198         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20199         cat $dom > /dev/null
20200         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20201         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20202         ls $dom
20203         rm -f $dom
20204 }
20205 run_test 271a "DoM: data is cached for read after write"
20206
20207 test_271b() {
20208         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20209                 skip "Need MDS version at least 2.10.55"
20210
20211         local dom=$DIR/$tdir/dom
20212
20213         mkdir -p $DIR/$tdir
20214
20215         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20216
20217         lctl set_param -n mdc.*.stats=clear
20218         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20219         cancel_lru_locks mdc
20220         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20221         # second stat to check size is cached on client
20222         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20223         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20224         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20225         rm -f $dom
20226 }
20227 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20228
20229 test_271ba() {
20230         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20231                 skip "Need MDS version at least 2.10.55"
20232
20233         local dom=$DIR/$tdir/dom
20234
20235         mkdir -p $DIR/$tdir
20236
20237         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20238
20239         lctl set_param -n mdc.*.stats=clear
20240         lctl set_param -n osc.*.stats=clear
20241         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20242         cancel_lru_locks mdc
20243         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20244         # second stat to check size is cached on client
20245         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20246         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20247         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20248         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20249         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20250         rm -f $dom
20251 }
20252 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20253
20254
20255 get_mdc_stats() {
20256         local mdtidx=$1
20257         local param=$2
20258         local mdt=MDT$(printf %04x $mdtidx)
20259
20260         if [ -z $param ]; then
20261                 lctl get_param -n mdc.*$mdt*.stats
20262         else
20263                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20264         fi
20265 }
20266
20267 test_271c() {
20268         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20269                 skip "Need MDS version at least 2.10.55"
20270
20271         local dom=$DIR/$tdir/dom
20272
20273         mkdir -p $DIR/$tdir
20274
20275         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20276
20277         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20278         local facet=mds$((mdtidx + 1))
20279
20280         cancel_lru_locks mdc
20281         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20282         createmany -o $dom 1000
20283         lctl set_param -n mdc.*.stats=clear
20284         smalliomany -w $dom 1000 200
20285         get_mdc_stats $mdtidx
20286         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20287         # Each file has 1 open, 1 IO enqueues, total 2000
20288         # but now we have also +1 getxattr for security.capability, total 3000
20289         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20290         unlinkmany $dom 1000
20291
20292         cancel_lru_locks mdc
20293         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20294         createmany -o $dom 1000
20295         lctl set_param -n mdc.*.stats=clear
20296         smalliomany -w $dom 1000 200
20297         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20298         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20299         # for OPEN and IO lock.
20300         [ $((enq - enq_2)) -ge 1000 ] ||
20301                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20302         unlinkmany $dom 1000
20303         return 0
20304 }
20305 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20306
20307 cleanup_271def_tests() {
20308         trap 0
20309         rm -f $1
20310 }
20311
20312 test_271d() {
20313         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20314                 skip "Need MDS version at least 2.10.57"
20315
20316         local dom=$DIR/$tdir/dom
20317         local tmp=$TMP/$tfile
20318         trap "cleanup_271def_tests $tmp" EXIT
20319
20320         mkdir -p $DIR/$tdir
20321
20322         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20323
20324         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20325
20326         cancel_lru_locks mdc
20327         dd if=/dev/urandom of=$tmp bs=1000 count=1
20328         dd if=$tmp of=$dom bs=1000 count=1
20329         cancel_lru_locks mdc
20330
20331         cat /etc/hosts >> $tmp
20332         lctl set_param -n mdc.*.stats=clear
20333
20334         # append data to the same file it should update local page
20335         echo "Append to the same page"
20336         cat /etc/hosts >> $dom
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         cancel_lru_locks mdc
20349         lctl set_param -n mdc.*.stats=clear
20350
20351         echo "Open and read file"
20352         cat $dom > /dev/null
20353         local num=$(get_mdc_stats $mdtidx ost_read)
20354         local ra=$(get_mdc_stats $mdtidx req_active)
20355         local rw=$(get_mdc_stats $mdtidx req_waittime)
20356
20357         [ -z $num ] || error "$num READ RPC occured"
20358         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20359         echo "... DONE"
20360
20361         # compare content
20362         cmp $tmp $dom || error "file miscompare"
20363
20364         return 0
20365 }
20366 run_test 271d "DoM: read on open (1K file in reply buffer)"
20367
20368 test_271f() {
20369         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20370                 skip "Need MDS version at least 2.10.57"
20371
20372         local dom=$DIR/$tdir/dom
20373         local tmp=$TMP/$tfile
20374         trap "cleanup_271def_tests $tmp" EXIT
20375
20376         mkdir -p $DIR/$tdir
20377
20378         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20379
20380         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20381
20382         cancel_lru_locks mdc
20383         dd if=/dev/urandom of=$tmp bs=265000 count=1
20384         dd if=$tmp of=$dom bs=265000 count=1
20385         cancel_lru_locks mdc
20386         cat /etc/hosts >> $tmp
20387         lctl set_param -n mdc.*.stats=clear
20388
20389         echo "Append to the same page"
20390         cat /etc/hosts >> $dom
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 ] || error "$num READ RPC occured"
20396         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20397         echo "... DONE"
20398
20399         # compare content
20400         cmp $tmp $dom || error "file miscompare"
20401
20402         cancel_lru_locks mdc
20403         lctl set_param -n mdc.*.stats=clear
20404
20405         echo "Open and read file"
20406         cat $dom > /dev/null
20407         local num=$(get_mdc_stats $mdtidx ost_read)
20408         local ra=$(get_mdc_stats $mdtidx req_active)
20409         local rw=$(get_mdc_stats $mdtidx req_waittime)
20410
20411         [ -z $num ] && num=0
20412         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20413         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20414         echo "... DONE"
20415
20416         # compare content
20417         cmp $tmp $dom || error "file miscompare"
20418
20419         return 0
20420 }
20421 run_test 271f "DoM: read on open (200K file and read tail)"
20422
20423 test_271g() {
20424         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20425                 skip "Skipping due to old client or server version"
20426
20427         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20428         # to get layout
20429         $CHECKSTAT -t file $DIR1/$tfile
20430
20431         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20432         MULTIOP_PID=$!
20433         sleep 1
20434         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20435         $LCTL set_param fail_loc=0x80000314
20436         rm $DIR1/$tfile || error "Unlink fails"
20437         RC=$?
20438         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20439         [ $RC -eq 0 ] || error "Failed write to stale object"
20440 }
20441 run_test 271g "Discard DoM data vs client flush race"
20442
20443 test_272a() {
20444         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20445                 skip "Need MDS version at least 2.11.50"
20446
20447         local dom=$DIR/$tdir/dom
20448         mkdir -p $DIR/$tdir
20449
20450         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20451         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20452                 error "failed to write data into $dom"
20453         local old_md5=$(md5sum $dom)
20454
20455         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20456                 error "failed to migrate to the same DoM component"
20457
20458         local new_md5=$(md5sum $dom)
20459
20460         [ "$old_md5" == "$new_md5" ] ||
20461                 error "md5sum differ: $old_md5, $new_md5"
20462
20463         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20464                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20465 }
20466 run_test 272a "DoM migration: new layout with the same DOM component"
20467
20468 test_272b() {
20469         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20470                 skip "Need MDS version at least 2.11.50"
20471
20472         local dom=$DIR/$tdir/dom
20473         mkdir -p $DIR/$tdir
20474         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20475
20476         local mdtidx=$($LFS getstripe -m $dom)
20477         local mdtname=MDT$(printf %04x $mdtidx)
20478         local facet=mds$((mdtidx + 1))
20479
20480         local mdtfree1=$(do_facet $facet \
20481                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20482         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20483                 error "failed to write data into $dom"
20484         local old_md5=$(md5sum $dom)
20485         cancel_lru_locks mdc
20486         local mdtfree1=$(do_facet $facet \
20487                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20488
20489         $LFS migrate -c2 $dom ||
20490                 error "failed to migrate to the new composite layout"
20491         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20492                 error "MDT stripe was not removed"
20493
20494         cancel_lru_locks mdc
20495         local new_md5=$(md5sum $dom)
20496         [ "$old_md5" == "$new_md5" ] ||
20497                 error "$old_md5 != $new_md5"
20498
20499         # Skip free space checks with ZFS
20500         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20501                 local mdtfree2=$(do_facet $facet \
20502                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20503                 [ $mdtfree2 -gt $mdtfree1 ] ||
20504                         error "MDT space is not freed after migration"
20505         fi
20506         return 0
20507 }
20508 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20509
20510 test_272c() {
20511         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20512                 skip "Need MDS version at least 2.11.50"
20513
20514         local dom=$DIR/$tdir/$tfile
20515         mkdir -p $DIR/$tdir
20516         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20517
20518         local mdtidx=$($LFS getstripe -m $dom)
20519         local mdtname=MDT$(printf %04x $mdtidx)
20520         local facet=mds$((mdtidx + 1))
20521
20522         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20523                 error "failed to write data into $dom"
20524         local old_md5=$(md5sum $dom)
20525         cancel_lru_locks mdc
20526         local mdtfree1=$(do_facet $facet \
20527                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20528
20529         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20530                 error "failed to migrate to the new composite layout"
20531         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20532                 error "MDT stripe was not removed"
20533
20534         cancel_lru_locks mdc
20535         local new_md5=$(md5sum $dom)
20536         [ "$old_md5" == "$new_md5" ] ||
20537                 error "$old_md5 != $new_md5"
20538
20539         # Skip free space checks with ZFS
20540         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20541                 local mdtfree2=$(do_facet $facet \
20542                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20543                 [ $mdtfree2 -gt $mdtfree1 ] ||
20544                         error "MDS space is not freed after migration"
20545         fi
20546         return 0
20547 }
20548 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20549
20550 test_272d() {
20551         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20552                 skip "Need MDS version at least 2.12.55"
20553
20554         local dom=$DIR/$tdir/$tfile
20555         mkdir -p $DIR/$tdir
20556         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20557
20558         local mdtidx=$($LFS getstripe -m $dom)
20559         local mdtname=MDT$(printf %04x $mdtidx)
20560         local facet=mds$((mdtidx + 1))
20561
20562         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20563                 error "failed to write data into $dom"
20564         local old_md5=$(md5sum $dom)
20565         cancel_lru_locks mdc
20566         local mdtfree1=$(do_facet $facet \
20567                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20568
20569         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20570                 error "failed mirroring to the new composite layout"
20571         $LFS mirror resync $dom ||
20572                 error "failed mirror resync"
20573         $LFS mirror split --mirror-id 1 -d $dom ||
20574                 error "failed mirror split"
20575
20576         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20577                 error "MDT stripe was not removed"
20578
20579         cancel_lru_locks mdc
20580         local new_md5=$(md5sum $dom)
20581         [ "$old_md5" == "$new_md5" ] ||
20582                 error "$old_md5 != $new_md5"
20583
20584         # Skip free space checks with ZFS
20585         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20586                 local mdtfree2=$(do_facet $facet \
20587                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20588                 [ $mdtfree2 -gt $mdtfree1 ] ||
20589                         error "MDS space is not freed after DOM mirror deletion"
20590         fi
20591         return 0
20592 }
20593 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20594
20595 test_272e() {
20596         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20597                 skip "Need MDS version at least 2.12.55"
20598
20599         local dom=$DIR/$tdir/$tfile
20600         mkdir -p $DIR/$tdir
20601         $LFS setstripe -c 2 $dom
20602
20603         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20604                 error "failed to write data into $dom"
20605         local old_md5=$(md5sum $dom)
20606         cancel_lru_locks mdc
20607
20608         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20609                 error "failed mirroring to the DOM layout"
20610         $LFS mirror resync $dom ||
20611                 error "failed mirror resync"
20612         $LFS mirror split --mirror-id 1 -d $dom ||
20613                 error "failed mirror split"
20614
20615         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20616                 error "MDT stripe was not removed"
20617
20618         cancel_lru_locks mdc
20619         local new_md5=$(md5sum $dom)
20620         [ "$old_md5" == "$new_md5" ] ||
20621                 error "$old_md5 != $new_md5"
20622
20623         return 0
20624 }
20625 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20626
20627 test_272f() {
20628         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20629                 skip "Need MDS version at least 2.12.55"
20630
20631         local dom=$DIR/$tdir/$tfile
20632         mkdir -p $DIR/$tdir
20633         $LFS setstripe -c 2 $dom
20634
20635         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20636                 error "failed to write data into $dom"
20637         local old_md5=$(md5sum $dom)
20638         cancel_lru_locks mdc
20639
20640         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20641                 error "failed migrating to the DOM file"
20642
20643         cancel_lru_locks mdc
20644         local new_md5=$(md5sum $dom)
20645         [ "$old_md5" != "$new_md5" ] &&
20646                 error "$old_md5 != $new_md5"
20647
20648         return 0
20649 }
20650 run_test 272f "DoM migration: OST-striped file to DOM file"
20651
20652 test_273a() {
20653         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20654                 skip "Need MDS version at least 2.11.50"
20655
20656         # Layout swap cannot be done if either file has DOM component,
20657         # this will never be supported, migration should be used instead
20658
20659         local dom=$DIR/$tdir/$tfile
20660         mkdir -p $DIR/$tdir
20661
20662         $LFS setstripe -c2 ${dom}_plain
20663         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20664         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20665                 error "can swap layout with DoM component"
20666         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20667                 error "can swap layout with DoM component"
20668
20669         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20670         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20671                 error "can swap layout with DoM component"
20672         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20673                 error "can swap layout with DoM component"
20674         return 0
20675 }
20676 run_test 273a "DoM: layout swapping should fail with DOM"
20677
20678 test_275() {
20679         remote_ost_nodsh && skip "remote OST with nodsh"
20680         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20681                 skip "Need OST version >= 2.10.57"
20682
20683         local file=$DIR/$tfile
20684         local oss
20685
20686         oss=$(comma_list $(osts_nodes))
20687
20688         dd if=/dev/urandom of=$file bs=1M count=2 ||
20689                 error "failed to create a file"
20690         cancel_lru_locks osc
20691
20692         #lock 1
20693         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20694                 error "failed to read a file"
20695
20696 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20697         $LCTL set_param fail_loc=0x8000031f
20698
20699         cancel_lru_locks osc &
20700         sleep 1
20701
20702 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20703         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20704         #IO takes another lock, but matches the PENDING one
20705         #and places it to the IO RPC
20706         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20707                 error "failed to read a file with PENDING lock"
20708 }
20709 run_test 275 "Read on a canceled duplicate lock"
20710
20711 test_276() {
20712         remote_ost_nodsh && skip "remote OST with nodsh"
20713         local pid
20714
20715         do_facet ost1 "(while true; do \
20716                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20717                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20718         pid=$!
20719
20720         for LOOP in $(seq 20); do
20721                 stop ost1
20722                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20723         done
20724         kill -9 $pid
20725         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20726                 rm $TMP/sanity_276_pid"
20727 }
20728 run_test 276 "Race between mount and obd_statfs"
20729
20730 test_277() {
20731         $LCTL set_param ldlm.namespaces.*.lru_size=0
20732         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20733         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20734                         grep ^used_mb | awk '{print $2}')
20735         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20736         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20737                 oflag=direct conv=notrunc
20738         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20739                         grep ^used_mb | awk '{print $2}')
20740         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20741 }
20742 run_test 277 "Direct IO shall drop page cache"
20743
20744 test_278() {
20745         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20746         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20747         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20748                 skip "needs the same host for mdt1 mdt2" && return
20749
20750         local pid1
20751         local pid2
20752
20753 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20754         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20755         stop mds2 &
20756         pid2=$!
20757
20758         stop mds1
20759
20760         echo "Starting MDTs"
20761         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20762         wait $pid2
20763 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20764 #will return NULL
20765         do_facet mds2 $LCTL set_param fail_loc=0
20766
20767         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20768         wait_recovery_complete mds2
20769 }
20770 run_test 278 "Race starting MDS between MDTs stop/start"
20771
20772 test_280() {
20773         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20774                 skip "Need MGS version at least 2.13.52"
20775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20776         combined_mgs_mds || skip "needs combined MGS/MDT"
20777
20778         umount_client $MOUNT
20779 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20780         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20781
20782         mount_client $MOUNT &
20783         sleep 1
20784         stop mgs || error "stop mgs failed"
20785         #for a race mgs would crash
20786         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20787         mount_client $MOUNT || error "mount client failed"
20788 }
20789 run_test 280 "Race between MGS umount and client llog processing"
20790
20791 cleanup_test_300() {
20792         trap 0
20793         umask $SAVE_UMASK
20794 }
20795 test_striped_dir() {
20796         local mdt_index=$1
20797         local stripe_count
20798         local stripe_index
20799
20800         mkdir -p $DIR/$tdir
20801
20802         SAVE_UMASK=$(umask)
20803         trap cleanup_test_300 RETURN EXIT
20804
20805         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20806                                                 $DIR/$tdir/striped_dir ||
20807                 error "set striped dir error"
20808
20809         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20810         [ "$mode" = "755" ] || error "expect 755 got $mode"
20811
20812         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20813                 error "getdirstripe failed"
20814         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20815         if [ "$stripe_count" != "2" ]; then
20816                 error "1:stripe_count is $stripe_count, expect 2"
20817         fi
20818         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20819         if [ "$stripe_count" != "2" ]; then
20820                 error "2:stripe_count is $stripe_count, expect 2"
20821         fi
20822
20823         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20824         if [ "$stripe_index" != "$mdt_index" ]; then
20825                 error "stripe_index is $stripe_index, expect $mdt_index"
20826         fi
20827
20828         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20829                 error "nlink error after create striped dir"
20830
20831         mkdir $DIR/$tdir/striped_dir/a
20832         mkdir $DIR/$tdir/striped_dir/b
20833
20834         stat $DIR/$tdir/striped_dir/a ||
20835                 error "create dir under striped dir failed"
20836         stat $DIR/$tdir/striped_dir/b ||
20837                 error "create dir under striped dir failed"
20838
20839         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20840                 error "nlink error after mkdir"
20841
20842         rmdir $DIR/$tdir/striped_dir/a
20843         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20844                 error "nlink error after rmdir"
20845
20846         rmdir $DIR/$tdir/striped_dir/b
20847         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20848                 error "nlink error after rmdir"
20849
20850         chattr +i $DIR/$tdir/striped_dir
20851         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20852                 error "immutable flags not working under striped dir!"
20853         chattr -i $DIR/$tdir/striped_dir
20854
20855         rmdir $DIR/$tdir/striped_dir ||
20856                 error "rmdir striped dir error"
20857
20858         cleanup_test_300
20859
20860         true
20861 }
20862
20863 test_300a() {
20864         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20865                 skip "skipped for lustre < 2.7.0"
20866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20867         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20868
20869         test_striped_dir 0 || error "failed on striped dir on MDT0"
20870         test_striped_dir 1 || error "failed on striped dir on MDT0"
20871 }
20872 run_test 300a "basic striped dir sanity test"
20873
20874 test_300b() {
20875         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20876                 skip "skipped for lustre < 2.7.0"
20877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20878         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20879
20880         local i
20881         local mtime1
20882         local mtime2
20883         local mtime3
20884
20885         test_mkdir $DIR/$tdir || error "mkdir fail"
20886         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20887                 error "set striped dir error"
20888         for i in {0..9}; do
20889                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
20890                 sleep 1
20891                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
20892                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
20893                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
20894                 sleep 1
20895                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
20896                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
20897                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
20898         done
20899         true
20900 }
20901 run_test 300b "check ctime/mtime for striped dir"
20902
20903 test_300c() {
20904         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20905                 skip "skipped for lustre < 2.7.0"
20906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20907         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20908
20909         local file_count
20910
20911         mkdir -p $DIR/$tdir
20912         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
20913                 error "set striped dir error"
20914
20915         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
20916                 error "chown striped dir failed"
20917
20918         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
20919                 error "create 5k files failed"
20920
20921         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
20922
20923         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
20924
20925         rm -rf $DIR/$tdir
20926 }
20927 run_test 300c "chown && check ls under striped directory"
20928
20929 test_300d() {
20930         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20931                 skip "skipped for lustre < 2.7.0"
20932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20933         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20934
20935         local stripe_count
20936         local file
20937
20938         mkdir -p $DIR/$tdir
20939         $LFS setstripe -c 2 $DIR/$tdir
20940
20941         #local striped directory
20942         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20943                 error "set striped dir error"
20944         #look at the directories for debug purposes
20945         ls -l $DIR/$tdir
20946         $LFS getdirstripe $DIR/$tdir
20947         ls -l $DIR/$tdir/striped_dir
20948         $LFS getdirstripe $DIR/$tdir/striped_dir
20949         createmany -o $DIR/$tdir/striped_dir/f 10 ||
20950                 error "create 10 files failed"
20951
20952         #remote striped directory
20953         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
20954                 error "set striped dir error"
20955         #look at the directories for debug purposes
20956         ls -l $DIR/$tdir
20957         $LFS getdirstripe $DIR/$tdir
20958         ls -l $DIR/$tdir/remote_striped_dir
20959         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
20960         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
20961                 error "create 10 files failed"
20962
20963         for file in $(find $DIR/$tdir); do
20964                 stripe_count=$($LFS getstripe -c $file)
20965                 [ $stripe_count -eq 2 ] ||
20966                         error "wrong stripe $stripe_count for $file"
20967         done
20968
20969         rm -rf $DIR/$tdir
20970 }
20971 run_test 300d "check default stripe under striped directory"
20972
20973 test_300e() {
20974         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20975                 skip "Need MDS version at least 2.7.55"
20976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20977         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20978
20979         local stripe_count
20980         local file
20981
20982         mkdir -p $DIR/$tdir
20983
20984         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20985                 error "set striped dir error"
20986
20987         touch $DIR/$tdir/striped_dir/a
20988         touch $DIR/$tdir/striped_dir/b
20989         touch $DIR/$tdir/striped_dir/c
20990
20991         mkdir $DIR/$tdir/striped_dir/dir_a
20992         mkdir $DIR/$tdir/striped_dir/dir_b
20993         mkdir $DIR/$tdir/striped_dir/dir_c
20994
20995         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
20996                 error "set striped adir under striped dir error"
20997
20998         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
20999                 error "set striped bdir under striped dir error"
21000
21001         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21002                 error "set striped cdir under striped dir error"
21003
21004         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21005                 error "rename dir under striped dir fails"
21006
21007         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21008                 error "rename dir under different stripes fails"
21009
21010         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21011                 error "rename file under striped dir should succeed"
21012
21013         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21014                 error "rename dir under striped dir should succeed"
21015
21016         rm -rf $DIR/$tdir
21017 }
21018 run_test 300e "check rename under striped directory"
21019
21020 test_300f() {
21021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21022         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21023         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21024                 skip "Need MDS version at least 2.7.55"
21025
21026         local stripe_count
21027         local file
21028
21029         rm -rf $DIR/$tdir
21030         mkdir -p $DIR/$tdir
21031
21032         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21033                 error "set striped dir error"
21034
21035         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21036                 error "set striped dir error"
21037
21038         touch $DIR/$tdir/striped_dir/a
21039         mkdir $DIR/$tdir/striped_dir/dir_a
21040         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21041                 error "create striped dir under striped dir fails"
21042
21043         touch $DIR/$tdir/striped_dir1/b
21044         mkdir $DIR/$tdir/striped_dir1/dir_b
21045         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21046                 error "create striped dir under striped dir fails"
21047
21048         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21049                 error "rename dir under different striped dir should fail"
21050
21051         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21052                 error "rename striped dir under diff striped dir should fail"
21053
21054         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21055                 error "rename file under diff striped dirs fails"
21056
21057         rm -rf $DIR/$tdir
21058 }
21059 run_test 300f "check rename cross striped directory"
21060
21061 test_300_check_default_striped_dir()
21062 {
21063         local dirname=$1
21064         local default_count=$2
21065         local default_index=$3
21066         local stripe_count
21067         local stripe_index
21068         local dir_stripe_index
21069         local dir
21070
21071         echo "checking $dirname $default_count $default_index"
21072         $LFS setdirstripe -D -c $default_count -i $default_index \
21073                                 -t all_char $DIR/$tdir/$dirname ||
21074                 error "set default stripe on striped dir error"
21075         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21076         [ $stripe_count -eq $default_count ] ||
21077                 error "expect $default_count get $stripe_count for $dirname"
21078
21079         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21080         [ $stripe_index -eq $default_index ] ||
21081                 error "expect $default_index get $stripe_index for $dirname"
21082
21083         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21084                                                 error "create dirs failed"
21085
21086         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21087         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21088         for dir in $(find $DIR/$tdir/$dirname/*); do
21089                 stripe_count=$($LFS getdirstripe -c $dir)
21090                 [ $stripe_count -eq $default_count ] ||
21091                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21092                 error "stripe count $default_count != $stripe_count for $dir"
21093
21094                 stripe_index=$($LFS getdirstripe -i $dir)
21095                 [ $default_index -eq -1 ] ||
21096                         [ $stripe_index -eq $default_index ] ||
21097                         error "$stripe_index != $default_index for $dir"
21098
21099                 #check default stripe
21100                 stripe_count=$($LFS getdirstripe -D -c $dir)
21101                 [ $stripe_count -eq $default_count ] ||
21102                 error "default count $default_count != $stripe_count for $dir"
21103
21104                 stripe_index=$($LFS getdirstripe -D -i $dir)
21105                 [ $stripe_index -eq $default_index ] ||
21106                 error "default index $default_index != $stripe_index for $dir"
21107         done
21108         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21109 }
21110
21111 test_300g() {
21112         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21113         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21114                 skip "Need MDS version at least 2.7.55"
21115
21116         local dir
21117         local stripe_count
21118         local stripe_index
21119
21120         mkdir $DIR/$tdir
21121         mkdir $DIR/$tdir/normal_dir
21122
21123         #Checking when client cache stripe index
21124         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21125         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21126                 error "create striped_dir failed"
21127
21128         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21129                 error "create dir0 fails"
21130         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21131         [ $stripe_index -eq 0 ] ||
21132                 error "dir0 expect index 0 got $stripe_index"
21133
21134         mkdir $DIR/$tdir/striped_dir/dir1 ||
21135                 error "create dir1 fails"
21136         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21137         [ $stripe_index -eq 1 ] ||
21138                 error "dir1 expect index 1 got $stripe_index"
21139
21140         #check default stripe count/stripe index
21141         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21142         test_300_check_default_striped_dir normal_dir 1 0
21143         test_300_check_default_striped_dir normal_dir 2 1
21144         test_300_check_default_striped_dir normal_dir 2 -1
21145
21146         #delete default stripe information
21147         echo "delete default stripeEA"
21148         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21149                 error "set default stripe on striped dir error"
21150
21151         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21152         for dir in $(find $DIR/$tdir/normal_dir/*); do
21153                 stripe_count=$($LFS getdirstripe -c $dir)
21154                 [ $stripe_count -eq 0 ] ||
21155                         error "expect 1 get $stripe_count for $dir"
21156                 stripe_index=$($LFS getdirstripe -i $dir)
21157                 [ $stripe_index -eq 0 ] ||
21158                         error "expect 0 get $stripe_index for $dir"
21159         done
21160 }
21161 run_test 300g "check default striped directory for normal directory"
21162
21163 test_300h() {
21164         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21165         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21166                 skip "Need MDS version at least 2.7.55"
21167
21168         local dir
21169         local stripe_count
21170
21171         mkdir $DIR/$tdir
21172         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21173                 error "set striped dir error"
21174
21175         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21176         test_300_check_default_striped_dir striped_dir 1 0
21177         test_300_check_default_striped_dir striped_dir 2 1
21178         test_300_check_default_striped_dir striped_dir 2 -1
21179
21180         #delete default stripe information
21181         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21182                 error "set default stripe on striped dir error"
21183
21184         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21185         for dir in $(find $DIR/$tdir/striped_dir/*); do
21186                 stripe_count=$($LFS getdirstripe -c $dir)
21187                 [ $stripe_count -eq 0 ] ||
21188                         error "expect 1 get $stripe_count for $dir"
21189         done
21190 }
21191 run_test 300h "check default striped directory for striped directory"
21192
21193 test_300i() {
21194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21195         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21196         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21197                 skip "Need MDS version at least 2.7.55"
21198
21199         local stripe_count
21200         local file
21201
21202         mkdir $DIR/$tdir
21203
21204         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21205                 error "set striped dir error"
21206
21207         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21208                 error "create files under striped dir failed"
21209
21210         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21211                 error "set striped hashdir error"
21212
21213         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21214                 error "create dir0 under hash dir failed"
21215         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21216                 error "create dir1 under hash dir failed"
21217
21218         # unfortunately, we need to umount to clear dir layout cache for now
21219         # once we fully implement dir layout, we can drop this
21220         umount_client $MOUNT || error "umount failed"
21221         mount_client $MOUNT || error "mount failed"
21222
21223         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21224         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21225         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21226
21227         #set the stripe to be unknown hash type
21228         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21229         $LCTL set_param fail_loc=0x1901
21230         for ((i = 0; i < 10; i++)); do
21231                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21232                         error "stat f-$i failed"
21233                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21234         done
21235
21236         touch $DIR/$tdir/striped_dir/f0 &&
21237                 error "create under striped dir with unknown hash should fail"
21238
21239         $LCTL set_param fail_loc=0
21240
21241         umount_client $MOUNT || error "umount failed"
21242         mount_client $MOUNT || error "mount failed"
21243
21244         return 0
21245 }
21246 run_test 300i "client handle unknown hash type striped directory"
21247
21248 test_300j() {
21249         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21251         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21252                 skip "Need MDS version at least 2.7.55"
21253
21254         local stripe_count
21255         local file
21256
21257         mkdir $DIR/$tdir
21258
21259         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21260         $LCTL set_param fail_loc=0x1702
21261         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21262                 error "set striped dir error"
21263
21264         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21265                 error "create files under striped dir failed"
21266
21267         $LCTL set_param fail_loc=0
21268
21269         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21270
21271         return 0
21272 }
21273 run_test 300j "test large update record"
21274
21275 test_300k() {
21276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21277         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21278         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21279                 skip "Need MDS version at least 2.7.55"
21280
21281         # this test needs a huge transaction
21282         local kb
21283         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21284              osd*.$FSNAME-MDT0000.kbytestotal")
21285         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21286
21287         local stripe_count
21288         local file
21289
21290         mkdir $DIR/$tdir
21291
21292         #define OBD_FAIL_LARGE_STRIPE   0x1703
21293         $LCTL set_param fail_loc=0x1703
21294         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21295                 error "set striped dir error"
21296         $LCTL set_param fail_loc=0
21297
21298         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21299                 error "getstripeddir fails"
21300         rm -rf $DIR/$tdir/striped_dir ||
21301                 error "unlink striped dir fails"
21302
21303         return 0
21304 }
21305 run_test 300k "test large striped directory"
21306
21307 test_300l() {
21308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21309         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21310         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21311                 skip "Need MDS version at least 2.7.55"
21312
21313         local stripe_index
21314
21315         test_mkdir -p $DIR/$tdir/striped_dir
21316         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21317                         error "chown $RUNAS_ID failed"
21318         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21319                 error "set default striped dir failed"
21320
21321         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21322         $LCTL set_param fail_loc=0x80000158
21323         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21324
21325         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21326         [ $stripe_index -eq 1 ] ||
21327                 error "expect 1 get $stripe_index for $dir"
21328 }
21329 run_test 300l "non-root user to create dir under striped dir with stale layout"
21330
21331 test_300m() {
21332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21333         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21334         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21335                 skip "Need MDS version at least 2.7.55"
21336
21337         mkdir -p $DIR/$tdir/striped_dir
21338         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21339                 error "set default stripes dir error"
21340
21341         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21342
21343         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21344         [ $stripe_count -eq 0 ] ||
21345                         error "expect 0 get $stripe_count for a"
21346
21347         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21348                 error "set default stripes dir error"
21349
21350         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21351
21352         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21353         [ $stripe_count -eq 0 ] ||
21354                         error "expect 0 get $stripe_count for b"
21355
21356         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21357                 error "set default stripes dir error"
21358
21359         mkdir $DIR/$tdir/striped_dir/c &&
21360                 error "default stripe_index is invalid, mkdir c should fails"
21361
21362         rm -rf $DIR/$tdir || error "rmdir fails"
21363 }
21364 run_test 300m "setstriped directory on single MDT FS"
21365
21366 cleanup_300n() {
21367         local list=$(comma_list $(mdts_nodes))
21368
21369         trap 0
21370         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21371 }
21372
21373 test_300n() {
21374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21375         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21376         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21377                 skip "Need MDS version at least 2.7.55"
21378         remote_mds_nodsh && skip "remote MDS with nodsh"
21379
21380         local stripe_index
21381         local list=$(comma_list $(mdts_nodes))
21382
21383         trap cleanup_300n RETURN EXIT
21384         mkdir -p $DIR/$tdir
21385         chmod 777 $DIR/$tdir
21386         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21387                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21388                 error "create striped dir succeeds with gid=0"
21389
21390         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21391         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21392                 error "create striped dir fails with gid=-1"
21393
21394         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21395         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21396                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21397                 error "set default striped dir succeeds with gid=0"
21398
21399
21400         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21401         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21402                 error "set default striped dir fails with gid=-1"
21403
21404
21405         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21406         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21407                                         error "create test_dir fails"
21408         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21409                                         error "create test_dir1 fails"
21410         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21411                                         error "create test_dir2 fails"
21412         cleanup_300n
21413 }
21414 run_test 300n "non-root user to create dir under striped dir with default EA"
21415
21416 test_300o() {
21417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21418         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21419         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21420                 skip "Need MDS version at least 2.7.55"
21421
21422         local numfree1
21423         local numfree2
21424
21425         mkdir -p $DIR/$tdir
21426
21427         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21428         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21429         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21430                 skip "not enough free inodes $numfree1 $numfree2"
21431         fi
21432
21433         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21434         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21435         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21436                 skip "not enough free space $numfree1 $numfree2"
21437         fi
21438
21439         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21440                 error "setdirstripe fails"
21441
21442         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21443                 error "create dirs fails"
21444
21445         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21446         ls $DIR/$tdir/striped_dir > /dev/null ||
21447                 error "ls striped dir fails"
21448         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21449                 error "unlink big striped dir fails"
21450 }
21451 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21452
21453 test_300p() {
21454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21455         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21456         remote_mds_nodsh && skip "remote MDS with nodsh"
21457
21458         mkdir -p $DIR/$tdir
21459
21460         #define OBD_FAIL_OUT_ENOSPC     0x1704
21461         do_facet mds2 lctl set_param fail_loc=0x80001704
21462         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21463                  && error "create striped directory should fail"
21464
21465         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21466
21467         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21468         true
21469 }
21470 run_test 300p "create striped directory without space"
21471
21472 test_300q() {
21473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21474         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21475
21476         local fd=$(free_fd)
21477         local cmd="exec $fd<$tdir"
21478         cd $DIR
21479         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21480         eval $cmd
21481         cmd="exec $fd<&-"
21482         trap "eval $cmd" EXIT
21483         cd $tdir || error "cd $tdir fails"
21484         rmdir  ../$tdir || error "rmdir $tdir fails"
21485         mkdir local_dir && error "create dir succeeds"
21486         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21487         eval $cmd
21488         return 0
21489 }
21490 run_test 300q "create remote directory under orphan directory"
21491
21492 test_300r() {
21493         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21494                 skip "Need MDS version at least 2.7.55" && return
21495         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21496
21497         mkdir $DIR/$tdir
21498
21499         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21500                 error "set striped dir error"
21501
21502         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21503                 error "getstripeddir fails"
21504
21505         local stripe_count
21506         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21507                       awk '/lmv_stripe_count:/ { print $2 }')
21508
21509         [ $MDSCOUNT -ne $stripe_count ] &&
21510                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21511
21512         rm -rf $DIR/$tdir/striped_dir ||
21513                 error "unlink striped dir fails"
21514 }
21515 run_test 300r "test -1 striped directory"
21516
21517 prepare_remote_file() {
21518         mkdir $DIR/$tdir/src_dir ||
21519                 error "create remote source failed"
21520
21521         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21522                  error "cp to remote source failed"
21523         touch $DIR/$tdir/src_dir/a
21524
21525         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21526                 error "create remote target dir failed"
21527
21528         touch $DIR/$tdir/tgt_dir/b
21529
21530         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21531                 error "rename dir cross MDT failed!"
21532
21533         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21534                 error "src_child still exists after rename"
21535
21536         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21537                 error "missing file(a) after rename"
21538
21539         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21540                 error "diff after rename"
21541 }
21542
21543 test_310a() {
21544         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21546
21547         local remote_file=$DIR/$tdir/tgt_dir/b
21548
21549         mkdir -p $DIR/$tdir
21550
21551         prepare_remote_file || error "prepare remote file failed"
21552
21553         #open-unlink file
21554         $OPENUNLINK $remote_file $remote_file ||
21555                 error "openunlink $remote_file failed"
21556         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21557 }
21558 run_test 310a "open unlink remote file"
21559
21560 test_310b() {
21561         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
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 $DIR/$tfile Ouc || error "mulitop failed"
21572         $CHECKSTAT -t file $remote_file || error "check file failed"
21573 }
21574 run_test 310b "unlink remote file with multiple links while open"
21575
21576 test_310c() {
21577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21578         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21579
21580         local remote_file=$DIR/$tdir/tgt_dir/b
21581
21582         mkdir -p $DIR/$tdir
21583
21584         prepare_remote_file || error "prepare remote file failed"
21585
21586         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21587         multiop_bg_pause $remote_file O_uc ||
21588                         error "mulitop failed for remote file"
21589         MULTIPID=$!
21590         $MULTIOP $DIR/$tfile Ouc
21591         kill -USR1 $MULTIPID
21592         wait $MULTIPID
21593 }
21594 run_test 310c "open-unlink remote file with multiple links"
21595
21596 #LU-4825
21597 test_311() {
21598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21599         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21600         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21601                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21602         remote_mds_nodsh && skip "remote MDS with nodsh"
21603
21604         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21605         local mdts=$(comma_list $(mdts_nodes))
21606
21607         mkdir -p $DIR/$tdir
21608         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21609         createmany -o $DIR/$tdir/$tfile. 1000
21610
21611         # statfs data is not real time, let's just calculate it
21612         old_iused=$((old_iused + 1000))
21613
21614         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21615                         osp.*OST0000*MDT0000.create_count")
21616         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21617                                 osp.*OST0000*MDT0000.max_create_count")
21618         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21619
21620         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21621         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21622         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21623
21624         unlinkmany $DIR/$tdir/$tfile. 1000
21625
21626         do_nodes $mdts "$LCTL set_param -n \
21627                         osp.*OST0000*.max_create_count=$max_count"
21628         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21629                 do_nodes $mdts "$LCTL set_param -n \
21630                                 osp.*OST0000*.create_count=$count"
21631         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21632                         grep "=0" && error "create_count is zero"
21633
21634         local new_iused
21635         for i in $(seq 120); do
21636                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21637                 # system may be too busy to destroy all objs in time, use
21638                 # a somewhat small value to not fail autotest
21639                 [ $((old_iused - new_iused)) -gt 400 ] && break
21640                 sleep 1
21641         done
21642
21643         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21644         [ $((old_iused - new_iused)) -gt 400 ] ||
21645                 error "objs not destroyed after unlink"
21646 }
21647 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21648
21649 zfs_oid_to_objid()
21650 {
21651         local ost=$1
21652         local objid=$2
21653
21654         local vdevdir=$(dirname $(facet_vdevice $ost))
21655         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21656         local zfs_zapid=$(do_facet $ost $cmd |
21657                           grep -w "/O/0/d$((objid%32))" -C 5 |
21658                           awk '/Object/{getline; print $1}')
21659         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21660                           awk "/$objid = /"'{printf $3}')
21661
21662         echo $zfs_objid
21663 }
21664
21665 zfs_object_blksz() {
21666         local ost=$1
21667         local objid=$2
21668
21669         local vdevdir=$(dirname $(facet_vdevice $ost))
21670         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21671         local blksz=$(do_facet $ost $cmd $objid |
21672                       awk '/dblk/{getline; printf $4}')
21673
21674         case "${blksz: -1}" in
21675                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21676                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21677                 *) ;;
21678         esac
21679
21680         echo $blksz
21681 }
21682
21683 test_312() { # LU-4856
21684         remote_ost_nodsh && skip "remote OST with nodsh"
21685         [ "$ost1_FSTYPE" = "zfs" ] ||
21686                 skip_env "the test only applies to zfs"
21687
21688         local max_blksz=$(do_facet ost1 \
21689                           $ZFS get -p recordsize $(facet_device ost1) |
21690                           awk '!/VALUE/{print $3}')
21691
21692         # to make life a little bit easier
21693         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21694         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21695
21696         local tf=$DIR/$tdir/$tfile
21697         touch $tf
21698         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21699
21700         # Get ZFS object id
21701         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21702         # block size change by sequential overwrite
21703         local bs
21704
21705         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21706                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21707
21708                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21709                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21710         done
21711         rm -f $tf
21712
21713         # block size change by sequential append write
21714         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21715         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21716         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21717         local count
21718
21719         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21720                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21721                         oflag=sync conv=notrunc
21722
21723                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21724                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21725                         error "blksz error, actual $blksz, " \
21726                                 "expected: 2 * $count * $PAGE_SIZE"
21727         done
21728         rm -f $tf
21729
21730         # random write
21731         touch $tf
21732         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21733         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21734
21735         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21736         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21737         [ $blksz -eq $PAGE_SIZE ] ||
21738                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21739
21740         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21741         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21742         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21743
21744         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21745         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21746         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21747 }
21748 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21749
21750 test_313() {
21751         remote_ost_nodsh && skip "remote OST with nodsh"
21752
21753         local file=$DIR/$tfile
21754
21755         rm -f $file
21756         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21757
21758         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21759         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21760         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21761                 error "write should failed"
21762         do_facet ost1 "$LCTL set_param fail_loc=0"
21763         rm -f $file
21764 }
21765 run_test 313 "io should fail after last_rcvd update fail"
21766
21767 test_314() {
21768         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21769
21770         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21771         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21772         rm -f $DIR/$tfile
21773         wait_delete_completed
21774         do_facet ost1 "$LCTL set_param fail_loc=0"
21775 }
21776 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21777
21778 test_315() { # LU-618
21779         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21780
21781         local file=$DIR/$tfile
21782         rm -f $file
21783
21784         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21785                 error "multiop file write failed"
21786         $MULTIOP $file oO_RDONLY:r4063232_c &
21787         PID=$!
21788
21789         sleep 2
21790
21791         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21792         kill -USR1 $PID
21793
21794         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21795         rm -f $file
21796 }
21797 run_test 315 "read should be accounted"
21798
21799 test_316() {
21800         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21801         large_xattr_enabled || skip_env "ea_inode feature disabled"
21802
21803         rm -rf $DIR/$tdir/d
21804         mkdir -p $DIR/$tdir/d
21805         chown nobody $DIR/$tdir/d
21806         touch $DIR/$tdir/d/file
21807
21808         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21809 }
21810 run_test 316 "lfs mv"
21811
21812 test_317() {
21813         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21814                 skip "Need MDS version at least 2.11.53"
21815         if [ "$ost1_FSTYPE" == "zfs" ]; then
21816                 skip "LU-10370: no implementation for ZFS"
21817         fi
21818
21819         local trunc_sz
21820         local grant_blk_size
21821
21822         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21823                         awk '/grant_block_size:/ { print $2; exit; }')
21824         #
21825         # Create File of size 5M. Truncate it to below size's and verify
21826         # blocks count.
21827         #
21828         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21829                 error "Create file $DIR/$tfile failed"
21830         stack_trap "rm -f $DIR/$tfile" EXIT
21831
21832         for trunc_sz in 2097152 4097 4000 509 0; do
21833                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21834                         error "truncate $tfile to $trunc_sz failed"
21835                 local sz=$(stat --format=%s $DIR/$tfile)
21836                 local blk=$(stat --format=%b $DIR/$tfile)
21837                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21838                                      grant_blk_size) * 8))
21839
21840                 if [[ $blk -ne $trunc_blk ]]; then
21841                         $(which stat) $DIR/$tfile
21842                         error "Expected Block $trunc_blk got $blk for $tfile"
21843                 fi
21844
21845                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21846                         error "Expected Size $trunc_sz got $sz for $tfile"
21847         done
21848
21849         #
21850         # sparse file test
21851         # Create file with a hole and write actual two blocks. Block count
21852         # must be 16.
21853         #
21854         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21855                 conv=fsync || error "Create file : $DIR/$tfile"
21856
21857         # Calculate the final truncate size.
21858         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21859
21860         #
21861         # truncate to size $trunc_sz bytes. Strip the last block
21862         # The block count must drop to 8
21863         #
21864         $TRUNCATE $DIR/$tfile $trunc_sz ||
21865                 error "truncate $tfile to $trunc_sz failed"
21866
21867         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
21868         sz=$(stat --format=%s $DIR/$tfile)
21869         blk=$(stat --format=%b $DIR/$tfile)
21870
21871         if [[ $blk -ne $trunc_bsz ]]; then
21872                 $(which stat) $DIR/$tfile
21873                 error "Expected Block $trunc_bsz got $blk for $tfile"
21874         fi
21875
21876         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21877                 error "Expected Size $trunc_sz got $sz for $tfile"
21878 }
21879 run_test 317 "Verify blocks get correctly update after truncate"
21880
21881 test_318() {
21882         local old_max_active=$($LCTL get_param -n \
21883                             llite.*.max_read_ahead_async_active 2>/dev/null)
21884
21885         $LCTL set_param llite.*.max_read_ahead_async_active=256
21886         local max_active=$($LCTL get_param -n \
21887                            llite.*.max_read_ahead_async_active 2>/dev/null)
21888         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
21889
21890         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
21891                 error "set max_read_ahead_async_active should succeed"
21892
21893         $LCTL set_param llite.*.max_read_ahead_async_active=512
21894         max_active=$($LCTL get_param -n \
21895                      llite.*.max_read_ahead_async_active 2>/dev/null)
21896         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
21897
21898         # restore @max_active
21899         [ $old_max_active -ne 0 ] && $LCTL set_param \
21900                 llite.*.max_read_ahead_async_active=$old_max_active
21901
21902         local old_threshold=$($LCTL get_param -n \
21903                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21904         local max_per_file_mb=$($LCTL get_param -n \
21905                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
21906
21907         local invalid=$(($max_per_file_mb + 1))
21908         $LCTL set_param \
21909                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
21910                         && error "set $invalid should fail"
21911
21912         local valid=$(($invalid - 1))
21913         $LCTL set_param \
21914                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
21915                         error "set $valid should succeed"
21916         local threshold=$($LCTL get_param -n \
21917                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21918         [ $threshold -eq $valid ] || error \
21919                 "expect threshold $valid got $threshold"
21920         $LCTL set_param \
21921                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
21922 }
21923 run_test 318 "Verify async readahead tunables"
21924
21925 test_319() {
21926         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
21927
21928         local before=$(date +%s)
21929         local evict
21930         local mdir=$DIR/$tdir
21931         local file=$mdir/xxx
21932
21933         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
21934         touch $file
21935
21936 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
21937         $LCTL set_param fail_val=5 fail_loc=0x8000032c
21938         $LFS mv -m1 $file &
21939
21940         sleep 1
21941         dd if=$file of=/dev/null
21942         wait
21943         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
21944           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
21945
21946         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
21947 }
21948 run_test 319 "lost lease lock on migrate error"
21949
21950 test_398a() { # LU-4198
21951         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21952         $LCTL set_param ldlm.namespaces.*.lru_size=clear
21953
21954         # request a new lock on client
21955         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21956
21957         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21958         local lock_count=$($LCTL get_param -n \
21959                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21960         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
21961
21962         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
21963
21964         # no lock cached, should use lockless IO and not enqueue new lock
21965         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21966         lock_count=$($LCTL get_param -n \
21967                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21968         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
21969 }
21970 run_test 398a "direct IO should cancel lock otherwise lockless"
21971
21972 test_398b() { # LU-4198
21973         which fio || skip_env "no fio installed"
21974         $LFS setstripe -c -1 $DIR/$tfile
21975
21976         local size=12
21977         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
21978
21979         local njobs=4
21980         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
21981         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21982                 --numjobs=$njobs --fallocate=none \
21983                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21984                 --filename=$DIR/$tfile &
21985         bg_pid=$!
21986
21987         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
21988         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
21989                 --numjobs=$njobs --fallocate=none \
21990                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21991                 --filename=$DIR/$tfile || true
21992         wait $bg_pid
21993
21994         rm -rf $DIR/$tfile
21995 }
21996 run_test 398b "DIO and buffer IO race"
21997
21998 test_398c() { # LU-4198
21999         which fio || skip_env "no fio installed"
22000
22001         saved_debug=$($LCTL get_param -n debug)
22002         $LCTL set_param debug=0
22003
22004         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22005         ((size /= 1024)) # by megabytes
22006         ((size /= 2)) # write half of the OST at most
22007         [ $size -gt 40 ] && size=40 #reduce test time anyway
22008
22009         $LFS setstripe -c 1 $DIR/$tfile
22010
22011         # it seems like ldiskfs reserves more space than necessary if the
22012         # writing blocks are not mapped, so it extends the file firstly
22013         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22014         cancel_lru_locks osc
22015
22016         # clear and verify rpc_stats later
22017         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22018
22019         local njobs=4
22020         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22021         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22022                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22023                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22024                 --filename=$DIR/$tfile
22025         [ $? -eq 0 ] || error "fio write error"
22026
22027         [ $($LCTL get_param -n \
22028          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22029                 error "Locks were requested while doing AIO"
22030
22031         # get the percentage of 1-page I/O
22032         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22033                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22034                 awk '{print $7}')
22035         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22036
22037         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22038         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22039                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22040                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22041                 --filename=$DIR/$tfile
22042         [ $? -eq 0 ] || error "fio mixed read write error"
22043
22044         echo "AIO with large block size ${size}M"
22045         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22046                 --numjobs=1 --fallocate=none --ioengine=libaio \
22047                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22048                 --filename=$DIR/$tfile
22049         [ $? -eq 0 ] || error "fio large block size failed"
22050
22051         rm -rf $DIR/$tfile
22052         $LCTL set_param debug="$saved_debug"
22053 }
22054 run_test 398c "run fio to test AIO"
22055
22056 test_398d() { #  LU-13846
22057         test -f aiocp || skip_env "no aiocp installed"
22058         local aio_file=$DIR/aio_file
22059
22060         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22061
22062         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22063         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22064
22065         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22066
22067         # make sure we don't crash and fail properly
22068         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22069                 error "aio not aligned with PAGE SIZE should fail"
22070
22071         rm -rf $DIR/$tfile $aio_file
22072 }
22073 run_test 398d "run aiocp to verify block size > stripe size"
22074
22075 test_fake_rw() {
22076         local read_write=$1
22077         if [ "$read_write" = "write" ]; then
22078                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22079         elif [ "$read_write" = "read" ]; then
22080                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22081         else
22082                 error "argument error"
22083         fi
22084
22085         # turn off debug for performance testing
22086         local saved_debug=$($LCTL get_param -n debug)
22087         $LCTL set_param debug=0
22088
22089         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22090
22091         # get ost1 size - $FSNAME-OST0000
22092         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22093         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22094         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22095
22096         if [ "$read_write" = "read" ]; then
22097                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
22098         fi
22099
22100         local start_time=$(date +%s.%N)
22101         $dd_cmd bs=1M count=$blocks oflag=sync ||
22102                 error "real dd $read_write error"
22103         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22104
22105         if [ "$read_write" = "write" ]; then
22106                 rm -f $DIR/$tfile
22107         fi
22108
22109         # define OBD_FAIL_OST_FAKE_RW           0x238
22110         do_facet ost1 $LCTL set_param fail_loc=0x238
22111
22112         local start_time=$(date +%s.%N)
22113         $dd_cmd bs=1M count=$blocks oflag=sync ||
22114                 error "fake dd $read_write error"
22115         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22116
22117         if [ "$read_write" = "write" ]; then
22118                 # verify file size
22119                 cancel_lru_locks osc
22120                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22121                         error "$tfile size not $blocks MB"
22122         fi
22123         do_facet ost1 $LCTL set_param fail_loc=0
22124
22125         echo "fake $read_write $duration_fake vs. normal $read_write" \
22126                 "$duration in seconds"
22127         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22128                 error_not_in_vm "fake write is slower"
22129
22130         $LCTL set_param -n debug="$saved_debug"
22131         rm -f $DIR/$tfile
22132 }
22133 test_399a() { # LU-7655 for OST fake write
22134         remote_ost_nodsh && skip "remote OST with nodsh"
22135
22136         test_fake_rw write
22137 }
22138 run_test 399a "fake write should not be slower than normal write"
22139
22140 test_399b() { # LU-8726 for OST fake read
22141         remote_ost_nodsh && skip "remote OST with nodsh"
22142         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22143                 skip_env "ldiskfs only test"
22144         fi
22145
22146         test_fake_rw read
22147 }
22148 run_test 399b "fake read should not be slower than normal read"
22149
22150 test_400a() { # LU-1606, was conf-sanity test_74
22151         if ! which $CC > /dev/null 2>&1; then
22152                 skip_env "$CC is not installed"
22153         fi
22154
22155         local extra_flags=''
22156         local out=$TMP/$tfile
22157         local prefix=/usr/include/lustre
22158         local prog
22159
22160         # Oleg removes c files in his test rig so test if any c files exist
22161         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22162                 skip_env "Needed c test files are missing"
22163
22164         if ! [[ -d $prefix ]]; then
22165                 # Assume we're running in tree and fixup the include path.
22166                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22167                 extra_flags+=" -L$LUSTRE/utils/.lib"
22168         fi
22169
22170         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22171                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22172                         error "client api broken"
22173         done
22174         rm -f $out
22175 }
22176 run_test 400a "Lustre client api program can compile and link"
22177
22178 test_400b() { # LU-1606, LU-5011
22179         local header
22180         local out=$TMP/$tfile
22181         local prefix=/usr/include/linux/lustre
22182
22183         # We use a hard coded prefix so that this test will not fail
22184         # when run in tree. There are headers in lustre/include/lustre/
22185         # that are not packaged (like lustre_idl.h) and have more
22186         # complicated include dependencies (like config.h and lnet/types.h).
22187         # Since this test about correct packaging we just skip them when
22188         # they don't exist (see below) rather than try to fixup cppflags.
22189
22190         if ! which $CC > /dev/null 2>&1; then
22191                 skip_env "$CC is not installed"
22192         fi
22193
22194         for header in $prefix/*.h; do
22195                 if ! [[ -f "$header" ]]; then
22196                         continue
22197                 fi
22198
22199                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22200                         continue # lustre_ioctl.h is internal header
22201                 fi
22202
22203                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22204                         error "cannot compile '$header'"
22205         done
22206         rm -f $out
22207 }
22208 run_test 400b "packaged headers can be compiled"
22209
22210 test_401a() { #LU-7437
22211         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22212         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22213
22214         #count the number of parameters by "list_param -R"
22215         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22216         #count the number of parameters by listing proc files
22217         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22218         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22219         echo "proc_dirs='$proc_dirs'"
22220         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22221         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22222                       sort -u | wc -l)
22223
22224         [ $params -eq $procs ] ||
22225                 error "found $params parameters vs. $procs proc files"
22226
22227         # test the list_param -D option only returns directories
22228         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22229         #count the number of parameters by listing proc directories
22230         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22231                 sort -u | wc -l)
22232
22233         [ $params -eq $procs ] ||
22234                 error "found $params parameters vs. $procs proc files"
22235 }
22236 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22237
22238 test_401b() {
22239         # jobid_var may not allow arbitrary values, so use jobid_name
22240         # if available
22241         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22242                 local testname=jobid_name tmp='testing%p'
22243         else
22244                 local testname=jobid_var tmp=testing
22245         fi
22246
22247         local save=$($LCTL get_param -n $testname)
22248
22249         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22250                 error "no error returned when setting bad parameters"
22251
22252         local jobid_new=$($LCTL get_param -n foe $testname baz)
22253         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22254
22255         $LCTL set_param -n fog=bam $testname=$save bat=fog
22256         local jobid_old=$($LCTL get_param -n foe $testname bag)
22257         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22258 }
22259 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22260
22261 test_401c() {
22262         # jobid_var may not allow arbitrary values, so use jobid_name
22263         # if available
22264         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22265                 local testname=jobid_name
22266         else
22267                 local testname=jobid_var
22268         fi
22269
22270         local jobid_var_old=$($LCTL get_param -n $testname)
22271         local jobid_var_new
22272
22273         $LCTL set_param $testname= &&
22274                 error "no error returned for 'set_param a='"
22275
22276         jobid_var_new=$($LCTL get_param -n $testname)
22277         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22278                 error "$testname was changed by setting without value"
22279
22280         $LCTL set_param $testname &&
22281                 error "no error returned for 'set_param a'"
22282
22283         jobid_var_new=$($LCTL get_param -n $testname)
22284         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22285                 error "$testname was changed by setting without value"
22286 }
22287 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22288
22289 test_401d() {
22290         # jobid_var may not allow arbitrary values, so use jobid_name
22291         # if available
22292         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22293                 local testname=jobid_name new_value='foo=bar%p'
22294         else
22295                 local testname=jobid_var new_valuie=foo=bar
22296         fi
22297
22298         local jobid_var_old=$($LCTL get_param -n $testname)
22299         local jobid_var_new
22300
22301         $LCTL set_param $testname=$new_value ||
22302                 error "'set_param a=b' did not accept a value containing '='"
22303
22304         jobid_var_new=$($LCTL get_param -n $testname)
22305         [[ "$jobid_var_new" == "$new_value" ]] ||
22306                 error "'set_param a=b' failed on a value containing '='"
22307
22308         # Reset the $testname to test the other format
22309         $LCTL set_param $testname=$jobid_var_old
22310         jobid_var_new=$($LCTL get_param -n $testname)
22311         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22312                 error "failed to reset $testname"
22313
22314         $LCTL set_param $testname $new_value ||
22315                 error "'set_param a b' did not accept a value containing '='"
22316
22317         jobid_var_new=$($LCTL get_param -n $testname)
22318         [[ "$jobid_var_new" == "$new_value" ]] ||
22319                 error "'set_param a b' failed on a value containing '='"
22320
22321         $LCTL set_param $testname $jobid_var_old
22322         jobid_var_new=$($LCTL get_param -n $testname)
22323         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22324                 error "failed to reset $testname"
22325 }
22326 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22327
22328 test_402() {
22329         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22330         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22331                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22332         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22333                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22334                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22335         remote_mds_nodsh && skip "remote MDS with nodsh"
22336
22337         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22338 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22339         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22340         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22341                 echo "Touch failed - OK"
22342 }
22343 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22344
22345 test_403() {
22346         local file1=$DIR/$tfile.1
22347         local file2=$DIR/$tfile.2
22348         local tfile=$TMP/$tfile
22349
22350         rm -f $file1 $file2 $tfile
22351
22352         touch $file1
22353         ln $file1 $file2
22354
22355         # 30 sec OBD_TIMEOUT in ll_getattr()
22356         # right before populating st_nlink
22357         $LCTL set_param fail_loc=0x80001409
22358         stat -c %h $file1 > $tfile &
22359
22360         # create an alias, drop all locks and reclaim the dentry
22361         < $file2
22362         cancel_lru_locks mdc
22363         cancel_lru_locks osc
22364         sysctl -w vm.drop_caches=2
22365
22366         wait
22367
22368         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22369
22370         rm -f $tfile $file1 $file2
22371 }
22372 run_test 403 "i_nlink should not drop to zero due to aliasing"
22373
22374 test_404() { # LU-6601
22375         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22376                 skip "Need server version newer than 2.8.52"
22377         remote_mds_nodsh && skip "remote MDS with nodsh"
22378
22379         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22380                 awk '/osp .*-osc-MDT/ { print $4}')
22381
22382         local osp
22383         for osp in $mosps; do
22384                 echo "Deactivate: " $osp
22385                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22386                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22387                         awk -vp=$osp '$4 == p { print $2 }')
22388                 [ $stat = IN ] || {
22389                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22390                         error "deactivate error"
22391                 }
22392                 echo "Activate: " $osp
22393                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22394                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22395                         awk -vp=$osp '$4 == p { print $2 }')
22396                 [ $stat = UP ] || {
22397                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22398                         error "activate error"
22399                 }
22400         done
22401 }
22402 run_test 404 "validate manual {de}activated works properly for OSPs"
22403
22404 test_405() {
22405         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22406         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22407                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22408                         skip "Layout swap lock is not supported"
22409
22410         check_swap_layouts_support
22411         check_swap_layout_no_dom $DIR
22412
22413         test_mkdir $DIR/$tdir
22414         swap_lock_test -d $DIR/$tdir ||
22415                 error "One layout swap locked test failed"
22416 }
22417 run_test 405 "Various layout swap lock tests"
22418
22419 test_406() {
22420         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22421         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22422         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22424         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22425                 skip "Need MDS version at least 2.8.50"
22426
22427         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22428         local test_pool=$TESTNAME
22429
22430         pool_add $test_pool || error "pool_add failed"
22431         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22432                 error "pool_add_targets failed"
22433
22434         save_layout_restore_at_exit $MOUNT
22435
22436         # parent set default stripe count only, child will stripe from both
22437         # parent and fs default
22438         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22439                 error "setstripe $MOUNT failed"
22440         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22441         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22442         for i in $(seq 10); do
22443                 local f=$DIR/$tdir/$tfile.$i
22444                 touch $f || error "touch failed"
22445                 local count=$($LFS getstripe -c $f)
22446                 [ $count -eq $OSTCOUNT ] ||
22447                         error "$f stripe count $count != $OSTCOUNT"
22448                 local offset=$($LFS getstripe -i $f)
22449                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22450                 local size=$($LFS getstripe -S $f)
22451                 [ $size -eq $((def_stripe_size * 2)) ] ||
22452                         error "$f stripe size $size != $((def_stripe_size * 2))"
22453                 local pool=$($LFS getstripe -p $f)
22454                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22455         done
22456
22457         # change fs default striping, delete parent default striping, now child
22458         # will stripe from new fs default striping only
22459         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22460                 error "change $MOUNT default stripe failed"
22461         $LFS setstripe -c 0 $DIR/$tdir ||
22462                 error "delete $tdir default stripe failed"
22463         for i in $(seq 11 20); do
22464                 local f=$DIR/$tdir/$tfile.$i
22465                 touch $f || error "touch $f failed"
22466                 local count=$($LFS getstripe -c $f)
22467                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22468                 local offset=$($LFS getstripe -i $f)
22469                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22470                 local size=$($LFS getstripe -S $f)
22471                 [ $size -eq $def_stripe_size ] ||
22472                         error "$f stripe size $size != $def_stripe_size"
22473                 local pool=$($LFS getstripe -p $f)
22474                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22475         done
22476
22477         unlinkmany $DIR/$tdir/$tfile. 1 20
22478
22479         local f=$DIR/$tdir/$tfile
22480         pool_remove_all_targets $test_pool $f
22481         pool_remove $test_pool $f
22482 }
22483 run_test 406 "DNE support fs default striping"
22484
22485 test_407() {
22486         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22487         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22488                 skip "Need MDS version at least 2.8.55"
22489         remote_mds_nodsh && skip "remote MDS with nodsh"
22490
22491         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22492                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22493         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22494                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22495         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22496
22497         #define OBD_FAIL_DT_TXN_STOP    0x2019
22498         for idx in $(seq $MDSCOUNT); do
22499                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22500         done
22501         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22502         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22503                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22504         true
22505 }
22506 run_test 407 "transaction fail should cause operation fail"
22507
22508 test_408() {
22509         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22510
22511         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22512         lctl set_param fail_loc=0x8000040a
22513         # let ll_prepare_partial_page() fail
22514         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22515
22516         rm -f $DIR/$tfile
22517
22518         # create at least 100 unused inodes so that
22519         # shrink_icache_memory(0) should not return 0
22520         touch $DIR/$tfile-{0..100}
22521         rm -f $DIR/$tfile-{0..100}
22522         sync
22523
22524         echo 2 > /proc/sys/vm/drop_caches
22525 }
22526 run_test 408 "drop_caches should not hang due to page leaks"
22527
22528 test_409()
22529 {
22530         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22531
22532         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22533         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22534         touch $DIR/$tdir/guard || error "(2) Fail to create"
22535
22536         local PREFIX=$(str_repeat 'A' 128)
22537         echo "Create 1K hard links start at $(date)"
22538         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22539                 error "(3) Fail to hard link"
22540
22541         echo "Links count should be right although linkEA overflow"
22542         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22543         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22544         [ $linkcount -eq 1001 ] ||
22545                 error "(5) Unexpected hard links count: $linkcount"
22546
22547         echo "List all links start at $(date)"
22548         ls -l $DIR/$tdir/foo > /dev/null ||
22549                 error "(6) Fail to list $DIR/$tdir/foo"
22550
22551         echo "Unlink hard links start at $(date)"
22552         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22553                 error "(7) Fail to unlink"
22554         echo "Unlink hard links finished at $(date)"
22555 }
22556 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22557
22558 test_410()
22559 {
22560         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22561                 skip "Need client version at least 2.9.59"
22562         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22563                 skip "Need MODULES build"
22564
22565         # Create a file, and stat it from the kernel
22566         local testfile=$DIR/$tfile
22567         touch $testfile
22568
22569         local run_id=$RANDOM
22570         local my_ino=$(stat --format "%i" $testfile)
22571
22572         # Try to insert the module. This will always fail as the
22573         # module is designed to not be inserted.
22574         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22575             &> /dev/null
22576
22577         # Anything but success is a test failure
22578         dmesg | grep -q \
22579             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22580             error "no inode match"
22581 }
22582 run_test 410 "Test inode number returned from kernel thread"
22583
22584 cleanup_test411_cgroup() {
22585         trap 0
22586         rmdir "$1"
22587 }
22588
22589 test_411() {
22590         local cg_basedir=/sys/fs/cgroup/memory
22591         # LU-9966
22592         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22593                 skip "no setup for cgroup"
22594
22595         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22596                 error "test file creation failed"
22597         cancel_lru_locks osc
22598
22599         # Create a very small memory cgroup to force a slab allocation error
22600         local cgdir=$cg_basedir/osc_slab_alloc
22601         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22602         trap "cleanup_test411_cgroup $cgdir" EXIT
22603         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22604         echo 1M > $cgdir/memory.limit_in_bytes
22605
22606         # Should not LBUG, just be killed by oom-killer
22607         # dd will return 0 even allocation failure in some environment.
22608         # So don't check return value
22609         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22610         cleanup_test411_cgroup $cgdir
22611
22612         return 0
22613 }
22614 run_test 411 "Slab allocation error with cgroup does not LBUG"
22615
22616 test_412() {
22617         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22618         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22619                 skip "Need server version at least 2.10.55"
22620         fi
22621
22622         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22623                 error "mkdir failed"
22624         $LFS getdirstripe $DIR/$tdir
22625         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22626         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22627                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22628         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22629         [ $stripe_count -eq 2 ] ||
22630                 error "expect 2 get $stripe_count"
22631 }
22632 run_test 412 "mkdir on specific MDTs"
22633
22634 test_qos_mkdir() {
22635         local mkdir_cmd=$1
22636         local stripe_count=$2
22637         local mdts=$(comma_list $(mdts_nodes))
22638
22639         local testdir
22640         local lmv_qos_prio_free
22641         local lmv_qos_threshold_rr
22642         local lmv_qos_maxage
22643         local lod_qos_prio_free
22644         local lod_qos_threshold_rr
22645         local lod_qos_maxage
22646         local count
22647         local i
22648
22649         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22650         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22651         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22652                 head -n1)
22653         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22654         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22655         stack_trap "$LCTL set_param \
22656                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22657         stack_trap "$LCTL set_param \
22658                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22659         stack_trap "$LCTL set_param \
22660                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22661
22662         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22663                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22664         lod_qos_prio_free=${lod_qos_prio_free%%%}
22665         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22666                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22667         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22668         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22669                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22670         stack_trap "do_nodes $mdts $LCTL set_param \
22671                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22672         stack_trap "do_nodes $mdts $LCTL set_param \
22673                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22674                 EXIT
22675         stack_trap "do_nodes $mdts $LCTL set_param \
22676                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22677
22678         echo
22679         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22680
22681         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22682         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22683
22684         testdir=$DIR/$tdir-s$stripe_count/rr
22685
22686         for i in $(seq $((100 * MDSCOUNT))); do
22687                 eval $mkdir_cmd $testdir/subdir$i ||
22688                         error "$mkdir_cmd subdir$i failed"
22689         done
22690
22691         for i in $(seq $MDSCOUNT); do
22692                 count=$($LFS getdirstripe -i $testdir/* |
22693                                 grep ^$((i - 1))$ | wc -l)
22694                 echo "$count directories created on MDT$((i - 1))"
22695                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22696
22697                 if [ $stripe_count -gt 1 ]; then
22698                         count=$($LFS getdirstripe $testdir/* |
22699                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22700                         echo "$count stripes created on MDT$((i - 1))"
22701                         # deviation should < 5% of average
22702                         [ $count -lt $((95 * stripe_count)) ] ||
22703                         [ $count -gt $((105 * stripe_count)) ] &&
22704                                 error "stripes are not evenly distributed"
22705                 fi
22706         done
22707
22708         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22709         do_nodes $mdts $LCTL set_param \
22710                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22711
22712         echo
22713         echo "Check for uneven MDTs: "
22714
22715         local ffree
22716         local bavail
22717         local max
22718         local min
22719         local max_index
22720         local min_index
22721         local tmp
22722
22723         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22724         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22725         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22726
22727         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22728         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22729         max_index=0
22730         min_index=0
22731         for ((i = 1; i < ${#ffree[@]}; i++)); do
22732                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22733                 if [ $tmp -gt $max ]; then
22734                         max=$tmp
22735                         max_index=$i
22736                 fi
22737                 if [ $tmp -lt $min ]; then
22738                         min=$tmp
22739                         min_index=$i
22740                 fi
22741         done
22742
22743         [ ${ffree[min_index]} -eq 0 ] &&
22744                 skip "no free files in MDT$min_index"
22745         [ ${ffree[min_index]} -gt 100000000 ] &&
22746                 skip "too much free files in MDT$min_index"
22747
22748         # Check if we need to generate uneven MDTs
22749         local threshold=50
22750         local diff=$(((max - min) * 100 / min))
22751         local value="$(generate_string 1024)"
22752
22753         while [ $diff -lt $threshold ]; do
22754                 # generate uneven MDTs, create till $threshold% diff
22755                 echo -n "weight diff=$diff% must be > $threshold% ..."
22756                 count=$((${ffree[min_index]} / 10))
22757                 # 50 sec per 10000 files in vm
22758                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22759                         skip "$count files to create"
22760                 echo "Fill MDT$min_index with $count files"
22761                 [ -d $DIR/$tdir-MDT$min_index ] ||
22762                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22763                         error "mkdir $tdir-MDT$min_index failed"
22764                 for i in $(seq $count); do
22765                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22766                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22767                                 error "create f$j_$i failed"
22768                         setfattr -n user.413b -v $value \
22769                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22770                                 error "setfattr f$j_$i failed"
22771                 done
22772
22773                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22774                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22775                 max=$(((${ffree[max_index]} >> 8) * \
22776                         (${bavail[max_index]} * bsize >> 16)))
22777                 min=$(((${ffree[min_index]} >> 8) * \
22778                         (${bavail[min_index]} * bsize >> 16)))
22779                 diff=$(((max - min) * 100 / min))
22780         done
22781
22782         echo "MDT filesfree available: ${ffree[@]}"
22783         echo "MDT blocks available: ${bavail[@]}"
22784         echo "weight diff=$diff%"
22785
22786         echo
22787         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22788
22789         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22790         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22791         # decrease statfs age, so that it can be updated in time
22792         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22793         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22794
22795         sleep 1
22796
22797         testdir=$DIR/$tdir-s$stripe_count/qos
22798
22799         for i in $(seq $((100 * MDSCOUNT))); do
22800                 eval $mkdir_cmd $testdir/subdir$i ||
22801                         error "$mkdir_cmd subdir$i failed"
22802         done
22803
22804         for i in $(seq $MDSCOUNT); do
22805                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22806                         wc -l)
22807                 echo "$count directories created on MDT$((i - 1))"
22808
22809                 if [ $stripe_count -gt 1 ]; then
22810                         count=$($LFS getdirstripe $testdir/* |
22811                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22812                         echo "$count stripes created on MDT$((i - 1))"
22813                 fi
22814         done
22815
22816         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
22817         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22818
22819         # D-value should > 10% of averge
22820         [ $((max - min)) -lt 10 ] &&
22821                 error "subdirs shouldn't be evenly distributed"
22822
22823         # ditto
22824         if [ $stripe_count -gt 1 ]; then
22825                 max=$($LFS getdirstripe $testdir/* |
22826                         grep -P "^\s+$max_index\t" | wc -l)
22827                 min=$($LFS getdirstripe $testdir/* |
22828                         grep -P "^\s+$min_index\t" | wc -l)
22829                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22830                         error "stripes shouldn't be evenly distributed"|| true
22831         fi
22832 }
22833
22834 test_413a() {
22835         [ $MDSCOUNT -lt 2 ] &&
22836                 skip "We need at least 2 MDTs for this test"
22837
22838         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22839                 skip "Need server version at least 2.12.52"
22840
22841         local stripe_count
22842
22843         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22844                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22845                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22846                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22847                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22848         done
22849 }
22850 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22851
22852 test_413b() {
22853         [ $MDSCOUNT -lt 2 ] &&
22854                 skip "We need at least 2 MDTs for this test"
22855
22856         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22857                 skip "Need server version at least 2.12.52"
22858
22859         local stripe_count
22860
22861         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22862                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22863                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22864                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22865                 $LFS setdirstripe -D -c $stripe_count \
22866                         $DIR/$tdir-s$stripe_count/rr ||
22867                         error "setdirstripe failed"
22868                 $LFS setdirstripe -D -c $stripe_count \
22869                         $DIR/$tdir-s$stripe_count/qos ||
22870                         error "setdirstripe failed"
22871                 test_qos_mkdir "mkdir" $stripe_count
22872         done
22873 }
22874 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
22875
22876 test_414() {
22877 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
22878         $LCTL set_param fail_loc=0x80000521
22879         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
22880         rm -f $DIR/$tfile
22881 }
22882 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
22883
22884 test_415() {
22885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22886         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22887                 skip "Need server version at least 2.11.52"
22888
22889         # LU-11102
22890         local total
22891         local setattr_pid
22892         local start_time
22893         local end_time
22894         local duration
22895
22896         total=500
22897         # this test may be slow on ZFS
22898         [ "$mds1_FSTYPE" == "zfs" ] && total=100
22899
22900         # though this test is designed for striped directory, let's test normal
22901         # directory too since lock is always saved as CoS lock.
22902         test_mkdir $DIR/$tdir || error "mkdir $tdir"
22903         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
22904
22905         (
22906                 while true; do
22907                         touch $DIR/$tdir
22908                 done
22909         ) &
22910         setattr_pid=$!
22911
22912         start_time=$(date +%s)
22913         for i in $(seq $total); do
22914                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
22915                         > /dev/null
22916         done
22917         end_time=$(date +%s)
22918         duration=$((end_time - start_time))
22919
22920         kill -9 $setattr_pid
22921
22922         echo "rename $total files took $duration sec"
22923         [ $duration -lt 100 ] || error "rename took $duration sec"
22924 }
22925 run_test 415 "lock revoke is not missing"
22926
22927 test_416() {
22928         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22929                 skip "Need server version at least 2.11.55"
22930
22931         # define OBD_FAIL_OSD_TXN_START    0x19a
22932         do_facet mds1 lctl set_param fail_loc=0x19a
22933
22934         lfs mkdir -c $MDSCOUNT $DIR/$tdir
22935
22936         true
22937 }
22938 run_test 416 "transaction start failure won't cause system hung"
22939
22940 cleanup_417() {
22941         trap 0
22942         do_nodes $(comma_list $(mdts_nodes)) \
22943                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
22944         do_nodes $(comma_list $(mdts_nodes)) \
22945                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
22946         do_nodes $(comma_list $(mdts_nodes)) \
22947                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
22948 }
22949
22950 test_417() {
22951         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22952         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
22953                 skip "Need MDS version at least 2.11.56"
22954
22955         trap cleanup_417 RETURN EXIT
22956
22957         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
22958         do_nodes $(comma_list $(mdts_nodes)) \
22959                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
22960         $LFS migrate -m 0 $DIR/$tdir.1 &&
22961                 error "migrate dir $tdir.1 should fail"
22962
22963         do_nodes $(comma_list $(mdts_nodes)) \
22964                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
22965         $LFS mkdir -i 1 $DIR/$tdir.2 &&
22966                 error "create remote dir $tdir.2 should fail"
22967
22968         do_nodes $(comma_list $(mdts_nodes)) \
22969                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
22970         $LFS mkdir -c 2 $DIR/$tdir.3 &&
22971                 error "create striped dir $tdir.3 should fail"
22972         true
22973 }
22974 run_test 417 "disable remote dir, striped dir and dir migration"
22975
22976 # Checks that the outputs of df [-i] and lfs df [-i] match
22977 #
22978 # usage: check_lfs_df <blocks | inodes> <mountpoint>
22979 check_lfs_df() {
22980         local dir=$2
22981         local inodes
22982         local df_out
22983         local lfs_df_out
22984         local count
22985         local passed=false
22986
22987         # blocks or inodes
22988         [ "$1" == "blocks" ] && inodes= || inodes="-i"
22989
22990         for count in {1..100}; do
22991                 cancel_lru_locks
22992                 sync; sleep 0.2
22993
22994                 # read the lines of interest
22995                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
22996                         error "df $inodes $dir | tail -n +2 failed"
22997                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
22998                         error "lfs df $inodes $dir | grep summary: failed"
22999
23000                 # skip first substrings of each output as they are different
23001                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23002                 # compare the two outputs
23003                 passed=true
23004                 for i in {1..5}; do
23005                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23006                 done
23007                 $passed && break
23008         done
23009
23010         if ! $passed; then
23011                 df -P $inodes $dir
23012                 echo
23013                 lfs df $inodes $dir
23014                 error "df and lfs df $1 output mismatch: "      \
23015                       "df ${inodes}: ${df_out[*]}, "            \
23016                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23017         fi
23018 }
23019
23020 test_418() {
23021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23022
23023         local dir=$DIR/$tdir
23024         local numfiles=$((RANDOM % 4096 + 2))
23025         local numblocks=$((RANDOM % 256 + 1))
23026
23027         wait_delete_completed
23028         test_mkdir $dir
23029
23030         # check block output
23031         check_lfs_df blocks $dir
23032         # check inode output
23033         check_lfs_df inodes $dir
23034
23035         # create a single file and retest
23036         echo "Creating a single file and testing"
23037         createmany -o $dir/$tfile- 1 &>/dev/null ||
23038                 error "creating 1 file in $dir failed"
23039         check_lfs_df blocks $dir
23040         check_lfs_df inodes $dir
23041
23042         # create a random number of files
23043         echo "Creating $((numfiles - 1)) files and testing"
23044         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23045                 error "creating $((numfiles - 1)) files in $dir failed"
23046
23047         # write a random number of blocks to the first test file
23048         echo "Writing $numblocks 4K blocks and testing"
23049         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23050                 count=$numblocks &>/dev/null ||
23051                 error "dd to $dir/${tfile}-0 failed"
23052
23053         # retest
23054         check_lfs_df blocks $dir
23055         check_lfs_df inodes $dir
23056
23057         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23058                 error "unlinking $numfiles files in $dir failed"
23059 }
23060 run_test 418 "df and lfs df outputs match"
23061
23062 test_419()
23063 {
23064         local dir=$DIR/$tdir
23065
23066         mkdir -p $dir
23067         touch $dir/file
23068
23069         cancel_lru_locks mdc
23070
23071         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23072         $LCTL set_param fail_loc=0x1410
23073         cat $dir/file
23074         $LCTL set_param fail_loc=0
23075         rm -rf $dir
23076 }
23077 run_test 419 "Verify open file by name doesn't crash kernel"
23078
23079 test_420()
23080 {
23081         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23082                 skip "Need MDS version at least 2.12.53"
23083
23084         local SAVE_UMASK=$(umask)
23085         local dir=$DIR/$tdir
23086         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23087
23088         mkdir -p $dir
23089         umask 0000
23090         mkdir -m03777 $dir/testdir
23091         ls -dn $dir/testdir
23092         # Need to remove trailing '.' when SELinux is enabled
23093         local dirperms=$(ls -dn $dir/testdir |
23094                          awk '{ sub(/\.$/, "", $1); print $1}')
23095         [ $dirperms == "drwxrwsrwt" ] ||
23096                 error "incorrect perms on $dir/testdir"
23097
23098         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23099                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23100         ls -n $dir/testdir/testfile
23101         local fileperms=$(ls -n $dir/testdir/testfile |
23102                           awk '{ sub(/\.$/, "", $1); print $1}')
23103         [ $fileperms == "-rwxr-xr-x" ] ||
23104                 error "incorrect perms on $dir/testdir/testfile"
23105
23106         umask $SAVE_UMASK
23107 }
23108 run_test 420 "clear SGID bit on non-directories for non-members"
23109
23110 test_421a() {
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         cnt=$(ls -1 $DIR/$tdir | wc -l)
23121         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23122
23123         fid1=$(lfs path2fid $DIR/$tdir/f1)
23124         fid2=$(lfs path2fid $DIR/$tdir/f2)
23125         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23126
23127         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23128         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23129
23130         cnt=$(ls -1 $DIR/$tdir | wc -l)
23131         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23132
23133         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23134         createmany -o $DIR/$tdir/f 3
23135         cnt=$(ls -1 $DIR/$tdir | wc -l)
23136         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23137
23138         fid1=$(lfs path2fid $DIR/$tdir/f1)
23139         fid2=$(lfs path2fid $DIR/$tdir/f2)
23140         echo "remove using fsname $FSNAME"
23141         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23142
23143         cnt=$(ls -1 $DIR/$tdir | wc -l)
23144         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23145 }
23146 run_test 421a "simple rm by fid"
23147
23148 test_421b() {
23149         local cnt
23150         local FID1
23151         local FID2
23152
23153         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23154                 skip "Need MDS version at least 2.12.54"
23155
23156         test_mkdir $DIR/$tdir
23157         createmany -o $DIR/$tdir/f 3
23158         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23159         MULTIPID=$!
23160
23161         FID1=$(lfs path2fid $DIR/$tdir/f1)
23162         FID2=$(lfs path2fid $DIR/$tdir/f2)
23163         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23164
23165         kill -USR1 $MULTIPID
23166         wait
23167
23168         cnt=$(ls $DIR/$tdir | wc -l)
23169         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23170 }
23171 run_test 421b "rm by fid on open file"
23172
23173 test_421c() {
23174         local cnt
23175         local FIDS
23176
23177         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23178                 skip "Need MDS version at least 2.12.54"
23179
23180         test_mkdir $DIR/$tdir
23181         createmany -o $DIR/$tdir/f 3
23182         touch $DIR/$tdir/$tfile
23183         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23184         cnt=$(ls -1 $DIR/$tdir | wc -l)
23185         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23186
23187         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23188         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23189
23190         cnt=$(ls $DIR/$tdir | wc -l)
23191         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23192 }
23193 run_test 421c "rm by fid against hardlinked files"
23194
23195 test_421d() {
23196         local cnt
23197         local FIDS
23198
23199         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23200                 skip "Need MDS version at least 2.12.54"
23201
23202         test_mkdir $DIR/$tdir
23203         createmany -o $DIR/$tdir/f 4097
23204         cnt=$(ls -1 $DIR/$tdir | wc -l)
23205         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23206
23207         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23208         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23209
23210         cnt=$(ls $DIR/$tdir | wc -l)
23211         rm -rf $DIR/$tdir
23212         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23213 }
23214 run_test 421d "rmfid en masse"
23215
23216 test_421e() {
23217         local cnt
23218         local FID
23219
23220         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23221         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23222                 skip "Need MDS version at least 2.12.54"
23223
23224         mkdir -p $DIR/$tdir
23225         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23226         createmany -o $DIR/$tdir/striped_dir/f 512
23227         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23228         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23229
23230         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23231                 sed "s/[/][^:]*://g")
23232         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23233
23234         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23235         rm -rf $DIR/$tdir
23236         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23237 }
23238 run_test 421e "rmfid in DNE"
23239
23240 test_421f() {
23241         local cnt
23242         local FID
23243
23244         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23245                 skip "Need MDS version at least 2.12.54"
23246
23247         test_mkdir $DIR/$tdir
23248         touch $DIR/$tdir/f
23249         cnt=$(ls -1 $DIR/$tdir | wc -l)
23250         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23251
23252         FID=$(lfs path2fid $DIR/$tdir/f)
23253         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23254         # rmfid should fail
23255         cnt=$(ls -1 $DIR/$tdir | wc -l)
23256         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23257
23258         chmod a+rw $DIR/$tdir
23259         ls -la $DIR/$tdir
23260         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23261         # rmfid should fail
23262         cnt=$(ls -1 $DIR/$tdir | wc -l)
23263         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23264
23265         rm -f $DIR/$tdir/f
23266         $RUNAS touch $DIR/$tdir/f
23267         FID=$(lfs path2fid $DIR/$tdir/f)
23268         echo "rmfid as root"
23269         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23270         cnt=$(ls -1 $DIR/$tdir | wc -l)
23271         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23272
23273         rm -f $DIR/$tdir/f
23274         $RUNAS touch $DIR/$tdir/f
23275         cnt=$(ls -1 $DIR/$tdir | wc -l)
23276         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23277         FID=$(lfs path2fid $DIR/$tdir/f)
23278         # rmfid w/o user_fid2path mount option should fail
23279         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23280         cnt=$(ls -1 $DIR/$tdir | wc -l)
23281         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23282
23283         umount_client $MOUNT || error "failed to umount client"
23284         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23285                 error "failed to mount client'"
23286
23287         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23288         # rmfid should succeed
23289         cnt=$(ls -1 $DIR/$tdir | wc -l)
23290         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23291
23292         # rmfid shouldn't allow to remove files due to dir's permission
23293         chmod a+rwx $DIR/$tdir
23294         touch $DIR/$tdir/f
23295         ls -la $DIR/$tdir
23296         FID=$(lfs path2fid $DIR/$tdir/f)
23297         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23298
23299         umount_client $MOUNT || error "failed to umount client"
23300         mount_client $MOUNT "$MOUNT_OPTS" ||
23301                 error "failed to mount client'"
23302
23303 }
23304 run_test 421f "rmfid checks permissions"
23305
23306 test_421g() {
23307         local cnt
23308         local FIDS
23309
23310         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23311         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23312                 skip "Need MDS version at least 2.12.54"
23313
23314         mkdir -p $DIR/$tdir
23315         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23316         createmany -o $DIR/$tdir/striped_dir/f 512
23317         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23318         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23319
23320         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23321                 sed "s/[/][^:]*://g")
23322
23323         rm -f $DIR/$tdir/striped_dir/f1*
23324         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23325         removed=$((512 - cnt))
23326
23327         # few files have been just removed, so we expect
23328         # rmfid to fail on their fids
23329         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23330         [ $removed != $errors ] && error "$errors != $removed"
23331
23332         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23333         rm -rf $DIR/$tdir
23334         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23335 }
23336 run_test 421g "rmfid to return errors properly"
23337
23338 test_422() {
23339         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23340         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23341         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23342         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23343         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23344
23345         local amc=$(at_max_get client)
23346         local amo=$(at_max_get mds1)
23347         local timeout=`lctl get_param -n timeout`
23348
23349         at_max_set 0 client
23350         at_max_set 0 mds1
23351
23352 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23353         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23354                         fail_val=$(((2*timeout + 10)*1000))
23355         touch $DIR/$tdir/d3/file &
23356         sleep 2
23357 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23358         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23359                         fail_val=$((2*timeout + 5))
23360         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23361         local pid=$!
23362         sleep 1
23363         kill -9 $pid
23364         sleep $((2 * timeout))
23365         echo kill $pid
23366         kill -9 $pid
23367         lctl mark touch
23368         touch $DIR/$tdir/d2/file3
23369         touch $DIR/$tdir/d2/file4
23370         touch $DIR/$tdir/d2/file5
23371
23372         wait
23373         at_max_set $amc client
23374         at_max_set $amo mds1
23375
23376         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23377         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23378                 error "Watchdog is always throttled"
23379 }
23380 run_test 422 "kill a process with RPC in progress"
23381
23382 stat_test() {
23383     df -h $MOUNT &
23384     df -h $MOUNT &
23385     df -h $MOUNT &
23386     df -h $MOUNT &
23387     df -h $MOUNT &
23388     df -h $MOUNT &
23389 }
23390
23391 test_423() {
23392     local _stats
23393     # ensure statfs cache is expired
23394     sleep 2;
23395
23396     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23397     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23398
23399     return 0
23400 }
23401 run_test 423 "statfs should return a right data"
23402
23403 test_424() {
23404 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23405         $LCTL set_param fail_loc=0x80000522
23406         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23407         rm -f $DIR/$tfile
23408 }
23409 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23410
23411 test_425() {
23412         test_mkdir -c -1 $DIR/$tdir
23413         $LFS setstripe -c -1 $DIR/$tdir
23414
23415         lru_resize_disable "" 100
23416         stack_trap "lru_resize_enable" EXIT
23417
23418         sleep 5
23419
23420         for i in $(seq $((MDSCOUNT * 125))); do
23421                 local t=$DIR/$tdir/$tfile_$i
23422
23423                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
23424                         error_noexit "Create file $t"
23425         done
23426         stack_trap "rm -rf $DIR/$tdir" EXIT
23427
23428         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
23429                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
23430                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
23431
23432                 [ $lock_count -le $lru_size ] ||
23433                         error "osc lock count $lock_count > lru size $lru_size"
23434         done
23435
23436         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
23437                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
23438                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
23439
23440                 [ $lock_count -le $lru_size ] ||
23441                         error "mdc lock count $lock_count > lru size $lru_size"
23442         done
23443 }
23444 run_test 425 "lock count should not exceed lru size"
23445
23446 prep_801() {
23447         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23448         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23449                 skip "Need server version at least 2.9.55"
23450
23451         start_full_debug_logging
23452 }
23453
23454 post_801() {
23455         stop_full_debug_logging
23456 }
23457
23458 barrier_stat() {
23459         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23460                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23461                            awk '/The barrier for/ { print $7 }')
23462                 echo $st
23463         else
23464                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23465                 echo \'$st\'
23466         fi
23467 }
23468
23469 barrier_expired() {
23470         local expired
23471
23472         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23473                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23474                           awk '/will be expired/ { print $7 }')
23475         else
23476                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23477         fi
23478
23479         echo $expired
23480 }
23481
23482 test_801a() {
23483         prep_801
23484
23485         echo "Start barrier_freeze at: $(date)"
23486         #define OBD_FAIL_BARRIER_DELAY          0x2202
23487         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23488         # Do not reduce barrier time - See LU-11873
23489         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23490
23491         sleep 2
23492         local b_status=$(barrier_stat)
23493         echo "Got barrier status at: $(date)"
23494         [ "$b_status" = "'freezing_p1'" ] ||
23495                 error "(1) unexpected barrier status $b_status"
23496
23497         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23498         wait
23499         b_status=$(barrier_stat)
23500         [ "$b_status" = "'frozen'" ] ||
23501                 error "(2) unexpected barrier status $b_status"
23502
23503         local expired=$(barrier_expired)
23504         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23505         sleep $((expired + 3))
23506
23507         b_status=$(barrier_stat)
23508         [ "$b_status" = "'expired'" ] ||
23509                 error "(3) unexpected barrier status $b_status"
23510
23511         # Do not reduce barrier time - See LU-11873
23512         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23513                 error "(4) fail to freeze barrier"
23514
23515         b_status=$(barrier_stat)
23516         [ "$b_status" = "'frozen'" ] ||
23517                 error "(5) unexpected barrier status $b_status"
23518
23519         echo "Start barrier_thaw at: $(date)"
23520         #define OBD_FAIL_BARRIER_DELAY          0x2202
23521         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23522         do_facet mgs $LCTL barrier_thaw $FSNAME &
23523
23524         sleep 2
23525         b_status=$(barrier_stat)
23526         echo "Got barrier status at: $(date)"
23527         [ "$b_status" = "'thawing'" ] ||
23528                 error "(6) unexpected barrier status $b_status"
23529
23530         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23531         wait
23532         b_status=$(barrier_stat)
23533         [ "$b_status" = "'thawed'" ] ||
23534                 error "(7) unexpected barrier status $b_status"
23535
23536         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23537         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23538         do_facet mgs $LCTL barrier_freeze $FSNAME
23539
23540         b_status=$(barrier_stat)
23541         [ "$b_status" = "'failed'" ] ||
23542                 error "(8) unexpected barrier status $b_status"
23543
23544         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23545         do_facet mgs $LCTL barrier_thaw $FSNAME
23546
23547         post_801
23548 }
23549 run_test 801a "write barrier user interfaces and stat machine"
23550
23551 test_801b() {
23552         prep_801
23553
23554         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23555         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23556         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23557         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23558         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23559
23560         cancel_lru_locks mdc
23561
23562         # 180 seconds should be long enough
23563         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23564
23565         local b_status=$(barrier_stat)
23566         [ "$b_status" = "'frozen'" ] ||
23567                 error "(6) unexpected barrier status $b_status"
23568
23569         mkdir $DIR/$tdir/d0/d10 &
23570         mkdir_pid=$!
23571
23572         touch $DIR/$tdir/d1/f13 &
23573         touch_pid=$!
23574
23575         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23576         ln_pid=$!
23577
23578         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23579         mv_pid=$!
23580
23581         rm -f $DIR/$tdir/d4/f12 &
23582         rm_pid=$!
23583
23584         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
23585
23586         # To guarantee taht the 'stat' is not blocked
23587         b_status=$(barrier_stat)
23588         [ "$b_status" = "'frozen'" ] ||
23589                 error "(8) unexpected barrier status $b_status"
23590
23591         # let above commands to run at background
23592         sleep 5
23593
23594         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
23595         ps -p $touch_pid || error "(10) touch should be blocked"
23596         ps -p $ln_pid || error "(11) link should be blocked"
23597         ps -p $mv_pid || error "(12) rename should be blocked"
23598         ps -p $rm_pid || error "(13) unlink should be blocked"
23599
23600         b_status=$(barrier_stat)
23601         [ "$b_status" = "'frozen'" ] ||
23602                 error "(14) unexpected barrier status $b_status"
23603
23604         do_facet mgs $LCTL barrier_thaw $FSNAME
23605         b_status=$(barrier_stat)
23606         [ "$b_status" = "'thawed'" ] ||
23607                 error "(15) unexpected barrier status $b_status"
23608
23609         wait $mkdir_pid || error "(16) mkdir should succeed"
23610         wait $touch_pid || error "(17) touch should succeed"
23611         wait $ln_pid || error "(18) link should succeed"
23612         wait $mv_pid || error "(19) rename should succeed"
23613         wait $rm_pid || error "(20) unlink should succeed"
23614
23615         post_801
23616 }
23617 run_test 801b "modification will be blocked by write barrier"
23618
23619 test_801c() {
23620         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23621
23622         prep_801
23623
23624         stop mds2 || error "(1) Fail to stop mds2"
23625
23626         do_facet mgs $LCTL barrier_freeze $FSNAME 30
23627
23628         local b_status=$(barrier_stat)
23629         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
23630                 do_facet mgs $LCTL barrier_thaw $FSNAME
23631                 error "(2) unexpected barrier status $b_status"
23632         }
23633
23634         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23635                 error "(3) Fail to rescan barrier bitmap"
23636
23637         # Do not reduce barrier time - See LU-11873
23638         do_facet mgs $LCTL barrier_freeze $FSNAME 20
23639
23640         b_status=$(barrier_stat)
23641         [ "$b_status" = "'frozen'" ] ||
23642                 error "(4) unexpected barrier status $b_status"
23643
23644         do_facet mgs $LCTL barrier_thaw $FSNAME
23645         b_status=$(barrier_stat)
23646         [ "$b_status" = "'thawed'" ] ||
23647                 error "(5) unexpected barrier status $b_status"
23648
23649         local devname=$(mdsdevname 2)
23650
23651         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
23652
23653         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23654                 error "(7) Fail to rescan barrier bitmap"
23655
23656         post_801
23657 }
23658 run_test 801c "rescan barrier bitmap"
23659
23660 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
23661 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
23662 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
23663 saved_MOUNT_OPTS=$MOUNT_OPTS
23664
23665 cleanup_802a() {
23666         trap 0
23667
23668         stopall
23669         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
23670         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
23671         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
23672         MOUNT_OPTS=$saved_MOUNT_OPTS
23673         setupall
23674 }
23675
23676 test_802a() {
23677         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
23678         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23679         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23680                 skip "Need server version at least 2.9.55"
23681
23682         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
23683
23684         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23685
23686         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23687                 error "(2) Fail to copy"
23688
23689         trap cleanup_802a EXIT
23690
23691         # sync by force before remount as readonly
23692         sync; sync_all_data; sleep 3; sync_all_data
23693
23694         stopall
23695
23696         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
23697         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
23698         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
23699
23700         echo "Mount the server as read only"
23701         setupall server_only || error "(3) Fail to start servers"
23702
23703         echo "Mount client without ro should fail"
23704         mount_client $MOUNT &&
23705                 error "(4) Mount client without 'ro' should fail"
23706
23707         echo "Mount client with ro should succeed"
23708         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
23709         mount_client $MOUNT ||
23710                 error "(5) Mount client with 'ro' should succeed"
23711
23712         echo "Modify should be refused"
23713         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23714
23715         echo "Read should be allowed"
23716         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23717                 error "(7) Read should succeed under ro mode"
23718
23719         cleanup_802a
23720 }
23721 run_test 802a "simulate readonly device"
23722
23723 test_802b() {
23724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23725         remote_mds_nodsh && skip "remote MDS with nodsh"
23726
23727         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
23728                 skip "readonly option not available"
23729
23730         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
23731
23732         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23733                 error "(2) Fail to copy"
23734
23735         # write back all cached data before setting MDT to readonly
23736         cancel_lru_locks
23737         sync_all_data
23738
23739         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
23740         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
23741
23742         echo "Modify should be refused"
23743         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23744
23745         echo "Read should be allowed"
23746         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23747                 error "(7) Read should succeed under ro mode"
23748
23749         # disable readonly
23750         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
23751 }
23752 run_test 802b "be able to set MDTs to readonly"
23753
23754 test_803() {
23755         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23756         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23757                 skip "MDS needs to be newer than 2.10.54"
23758
23759         mkdir -p $DIR/$tdir
23760         # Create some objects on all MDTs to trigger related logs objects
23761         for idx in $(seq $MDSCOUNT); do
23762                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
23763                         $DIR/$tdir/dir${idx} ||
23764                         error "Fail to create $DIR/$tdir/dir${idx}"
23765         done
23766
23767         sync; sleep 3
23768         wait_delete_completed # ensure old test cleanups are finished
23769         echo "before create:"
23770         $LFS df -i $MOUNT
23771         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23772
23773         for i in {1..10}; do
23774                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
23775                         error "Fail to create $DIR/$tdir/foo$i"
23776         done
23777
23778         sync; sleep 3
23779         echo "after create:"
23780         $LFS df -i $MOUNT
23781         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23782
23783         # allow for an llog to be cleaned up during the test
23784         [ $after_used -ge $((before_used + 10 - 1)) ] ||
23785                 error "before ($before_used) + 10 > after ($after_used)"
23786
23787         for i in {1..10}; do
23788                 rm -rf $DIR/$tdir/foo$i ||
23789                         error "Fail to remove $DIR/$tdir/foo$i"
23790         done
23791
23792         sleep 3 # avoid MDT return cached statfs
23793         wait_delete_completed
23794         echo "after unlink:"
23795         $LFS df -i $MOUNT
23796         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23797
23798         # allow for an llog to be created during the test
23799         [ $after_used -le $((before_used + 1)) ] ||
23800                 error "after ($after_used) > before ($before_used) + 1"
23801 }
23802 run_test 803 "verify agent object for remote object"
23803
23804 test_804() {
23805         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23806         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23807                 skip "MDS needs to be newer than 2.10.54"
23808         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
23809
23810         mkdir -p $DIR/$tdir
23811         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
23812                 error "Fail to create $DIR/$tdir/dir0"
23813
23814         local fid=$($LFS path2fid $DIR/$tdir/dir0)
23815         local dev=$(mdsdevname 2)
23816
23817         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23818                 grep ${fid} || error "NOT found agent entry for dir0"
23819
23820         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
23821                 error "Fail to create $DIR/$tdir/dir1"
23822
23823         touch $DIR/$tdir/dir1/foo0 ||
23824                 error "Fail to create $DIR/$tdir/dir1/foo0"
23825         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
23826         local rc=0
23827
23828         for idx in $(seq $MDSCOUNT); do
23829                 dev=$(mdsdevname $idx)
23830                 do_facet mds${idx} \
23831                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23832                         grep ${fid} && rc=$idx
23833         done
23834
23835         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
23836                 error "Fail to rename foo0 to foo1"
23837         if [ $rc -eq 0 ]; then
23838                 for idx in $(seq $MDSCOUNT); do
23839                         dev=$(mdsdevname $idx)
23840                         do_facet mds${idx} \
23841                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23842                         grep ${fid} && rc=$idx
23843                 done
23844         fi
23845
23846         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
23847                 error "Fail to rename foo1 to foo2"
23848         if [ $rc -eq 0 ]; then
23849                 for idx in $(seq $MDSCOUNT); do
23850                         dev=$(mdsdevname $idx)
23851                         do_facet mds${idx} \
23852                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23853                         grep ${fid} && rc=$idx
23854                 done
23855         fi
23856
23857         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
23858
23859         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
23860                 error "Fail to link to $DIR/$tdir/dir1/foo2"
23861         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
23862                 error "Fail to rename foo2 to foo0"
23863         unlink $DIR/$tdir/dir1/foo0 ||
23864                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
23865         rm -rf $DIR/$tdir/dir0 ||
23866                 error "Fail to rm $DIR/$tdir/dir0"
23867
23868         for idx in $(seq $MDSCOUNT); do
23869                 dev=$(mdsdevname $idx)
23870                 rc=0
23871
23872                 stop mds${idx}
23873                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
23874                         rc=$?
23875                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
23876                         error "mount mds$idx failed"
23877                 df $MOUNT > /dev/null 2>&1
23878
23879                 # e2fsck should not return error
23880                 [ $rc -eq 0 ] ||
23881                         error "e2fsck detected error on MDT${idx}: rc=$rc"
23882         done
23883 }
23884 run_test 804 "verify agent entry for remote entry"
23885
23886 cleanup_805() {
23887         do_facet $SINGLEMDS zfs set quota=$old $fsset
23888         unlinkmany $DIR/$tdir/f- 1000000
23889         trap 0
23890 }
23891
23892 test_805() {
23893         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
23894         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
23895         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
23896                 skip "netfree not implemented before 0.7"
23897         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
23898                 skip "Need MDS version at least 2.10.57"
23899
23900         local fsset
23901         local freekb
23902         local usedkb
23903         local old
23904         local quota
23905         local pref="osd-zfs.$FSNAME-MDT0000."
23906
23907         # limit available space on MDS dataset to meet nospace issue
23908         # quickly. then ZFS 0.7.2 can use reserved space if asked
23909         # properly (using netfree flag in osd_declare_destroy()
23910         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
23911         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
23912                 gawk '{print $3}')
23913         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
23914         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
23915         let "usedkb=usedkb-freekb"
23916         let "freekb=freekb/2"
23917         if let "freekb > 5000"; then
23918                 let "freekb=5000"
23919         fi
23920         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
23921         trap cleanup_805 EXIT
23922         mkdir $DIR/$tdir
23923         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
23924                 error "Can't set PFL layout"
23925         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
23926         rm -rf $DIR/$tdir || error "not able to remove"
23927         do_facet $SINGLEMDS zfs set quota=$old $fsset
23928         trap 0
23929 }
23930 run_test 805 "ZFS can remove from full fs"
23931
23932 # Size-on-MDS test
23933 check_lsom_data()
23934 {
23935         local file=$1
23936         local size=$($LFS getsom -s $file)
23937         local expect=$(stat -c %s $file)
23938
23939         [[ $size == $expect ]] ||
23940                 error "$file expected size: $expect, got: $size"
23941
23942         local blocks=$($LFS getsom -b $file)
23943         expect=$(stat -c %b $file)
23944         [[ $blocks == $expect ]] ||
23945                 error "$file expected blocks: $expect, got: $blocks"
23946 }
23947
23948 check_lsom_size()
23949 {
23950         local size=$($LFS getsom -s $1)
23951         local expect=$2
23952
23953         [[ $size == $expect ]] ||
23954                 error "$file expected size: $expect, got: $size"
23955 }
23956
23957 test_806() {
23958         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23959                 skip "Need MDS version at least 2.11.52"
23960
23961         local bs=1048576
23962
23963         touch $DIR/$tfile || error "touch $tfile failed"
23964
23965         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23966         save_lustre_params client "llite.*.xattr_cache" > $save
23967         lctl set_param llite.*.xattr_cache=0
23968         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23969
23970         # single-threaded write
23971         echo "Test SOM for single-threaded write"
23972         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
23973                 error "write $tfile failed"
23974         check_lsom_size $DIR/$tfile $bs
23975
23976         local num=32
23977         local size=$(($num * $bs))
23978         local offset=0
23979         local i
23980
23981         echo "Test SOM for single client multi-threaded($num) write"
23982         $TRUNCATE $DIR/$tfile 0
23983         for ((i = 0; i < $num; i++)); do
23984                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23985                 local pids[$i]=$!
23986                 offset=$((offset + $bs))
23987         done
23988         for (( i=0; i < $num; i++ )); do
23989                 wait ${pids[$i]}
23990         done
23991         check_lsom_size $DIR/$tfile $size
23992
23993         $TRUNCATE $DIR/$tfile 0
23994         for ((i = 0; i < $num; i++)); do
23995                 offset=$((offset - $bs))
23996                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23997                 local pids[$i]=$!
23998         done
23999         for (( i=0; i < $num; i++ )); do
24000                 wait ${pids[$i]}
24001         done
24002         check_lsom_size $DIR/$tfile $size
24003
24004         # multi-client writes
24005         num=$(get_node_count ${CLIENTS//,/ })
24006         size=$(($num * $bs))
24007         offset=0
24008         i=0
24009
24010         echo "Test SOM for multi-client ($num) writes"
24011         $TRUNCATE $DIR/$tfile 0
24012         for client in ${CLIENTS//,/ }; do
24013                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24014                 local pids[$i]=$!
24015                 i=$((i + 1))
24016                 offset=$((offset + $bs))
24017         done
24018         for (( i=0; i < $num; i++ )); do
24019                 wait ${pids[$i]}
24020         done
24021         check_lsom_size $DIR/$tfile $offset
24022
24023         i=0
24024         $TRUNCATE $DIR/$tfile 0
24025         for client in ${CLIENTS//,/ }; do
24026                 offset=$((offset - $bs))
24027                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24028                 local pids[$i]=$!
24029                 i=$((i + 1))
24030         done
24031         for (( i=0; i < $num; i++ )); do
24032                 wait ${pids[$i]}
24033         done
24034         check_lsom_size $DIR/$tfile $size
24035
24036         # verify truncate
24037         echo "Test SOM for truncate"
24038         $TRUNCATE $DIR/$tfile 1048576
24039         check_lsom_size $DIR/$tfile 1048576
24040         $TRUNCATE $DIR/$tfile 1234
24041         check_lsom_size $DIR/$tfile 1234
24042
24043         # verify SOM blocks count
24044         echo "Verify SOM block count"
24045         $TRUNCATE $DIR/$tfile 0
24046         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24047                 error "failed to write file $tfile"
24048         check_lsom_data $DIR/$tfile
24049 }
24050 run_test 806 "Verify Lazy Size on MDS"
24051
24052 test_807() {
24053         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24054         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24055                 skip "Need MDS version at least 2.11.52"
24056
24057         # Registration step
24058         changelog_register || error "changelog_register failed"
24059         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24060         changelog_users $SINGLEMDS | grep -q $cl_user ||
24061                 error "User $cl_user not found in changelog_users"
24062
24063         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24064         save_lustre_params client "llite.*.xattr_cache" > $save
24065         lctl set_param llite.*.xattr_cache=0
24066         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24067
24068         rm -rf $DIR/$tdir || error "rm $tdir failed"
24069         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24070         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24071         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24072         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24073                 error "truncate $tdir/trunc failed"
24074
24075         local bs=1048576
24076         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24077                 error "write $tfile failed"
24078
24079         # multi-client wirtes
24080         local num=$(get_node_count ${CLIENTS//,/ })
24081         local offset=0
24082         local i=0
24083
24084         echo "Test SOM for multi-client ($num) writes"
24085         touch $DIR/$tfile || error "touch $tfile failed"
24086         $TRUNCATE $DIR/$tfile 0
24087         for client in ${CLIENTS//,/ }; do
24088                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24089                 local pids[$i]=$!
24090                 i=$((i + 1))
24091                 offset=$((offset + $bs))
24092         done
24093         for (( i=0; i < $num; i++ )); do
24094                 wait ${pids[$i]}
24095         done
24096
24097         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24098         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24099         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24100         check_lsom_data $DIR/$tdir/trunc
24101         check_lsom_data $DIR/$tdir/single_dd
24102         check_lsom_data $DIR/$tfile
24103
24104         rm -rf $DIR/$tdir
24105         # Deregistration step
24106         changelog_deregister || error "changelog_deregister failed"
24107 }
24108 run_test 807 "verify LSOM syncing tool"
24109
24110 check_som_nologged()
24111 {
24112         local lines=$($LFS changelog $FSNAME-MDT0000 |
24113                 grep 'x=trusted.som' | wc -l)
24114         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24115 }
24116
24117 test_808() {
24118         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24119                 skip "Need MDS version at least 2.11.55"
24120
24121         # Registration step
24122         changelog_register || error "changelog_register failed"
24123
24124         touch $DIR/$tfile || error "touch $tfile failed"
24125         check_som_nologged
24126
24127         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24128                 error "write $tfile failed"
24129         check_som_nologged
24130
24131         $TRUNCATE $DIR/$tfile 1234
24132         check_som_nologged
24133
24134         $TRUNCATE $DIR/$tfile 1048576
24135         check_som_nologged
24136
24137         # Deregistration step
24138         changelog_deregister || error "changelog_deregister failed"
24139 }
24140 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24141
24142 check_som_nodata()
24143 {
24144         $LFS getsom $1
24145         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24146 }
24147
24148 test_809() {
24149         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24150                 skip "Need MDS version at least 2.11.56"
24151
24152         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24153                 error "failed to create DoM-only file $DIR/$tfile"
24154         touch $DIR/$tfile || error "touch $tfile failed"
24155         check_som_nodata $DIR/$tfile
24156
24157         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24158                 error "write $tfile failed"
24159         check_som_nodata $DIR/$tfile
24160
24161         $TRUNCATE $DIR/$tfile 1234
24162         check_som_nodata $DIR/$tfile
24163
24164         $TRUNCATE $DIR/$tfile 4097
24165         check_som_nodata $DIR/$file
24166 }
24167 run_test 809 "Verify no SOM xattr store for DoM-only files"
24168
24169 test_810() {
24170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24171         $GSS && skip_env "could not run with gss"
24172         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24173                 skip "OST < 2.12.58 doesn't align checksum"
24174
24175         set_checksums 1
24176         stack_trap "set_checksums $ORIG_CSUM" EXIT
24177         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24178
24179         local csum
24180         local before
24181         local after
24182         for csum in $CKSUM_TYPES; do
24183                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24184                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24185                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24186                         eval set -- $i
24187                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24188                         before=$(md5sum $DIR/$tfile)
24189                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24190                         after=$(md5sum $DIR/$tfile)
24191                         [ "$before" == "$after" ] ||
24192                                 error "$csum: $before != $after bs=$1 seek=$2"
24193                 done
24194         done
24195 }
24196 run_test 810 "partial page writes on ZFS (LU-11663)"
24197
24198 test_812a() {
24199         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24200                 skip "OST < 2.12.51 doesn't support this fail_loc"
24201         [ "$SHARED_KEY" = true ] &&
24202                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24203
24204         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24205         # ensure ost1 is connected
24206         stat $DIR/$tfile >/dev/null || error "can't stat"
24207         wait_osc_import_state client ost1 FULL
24208         # no locks, no reqs to let the connection idle
24209         cancel_lru_locks osc
24210
24211         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24212 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24213         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24214         wait_osc_import_state client ost1 CONNECTING
24215         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24216
24217         stat $DIR/$tfile >/dev/null || error "can't stat file"
24218 }
24219 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24220
24221 test_812b() { # LU-12378
24222         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24223                 skip "OST < 2.12.51 doesn't support this fail_loc"
24224         [ "$SHARED_KEY" = true ] &&
24225                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24226
24227         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24228         # ensure ost1 is connected
24229         stat $DIR/$tfile >/dev/null || error "can't stat"
24230         wait_osc_import_state client ost1 FULL
24231         # no locks, no reqs to let the connection idle
24232         cancel_lru_locks osc
24233
24234         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24235 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24236         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24237         wait_osc_import_state client ost1 CONNECTING
24238         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24239
24240         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24241         wait_osc_import_state client ost1 IDLE
24242 }
24243 run_test 812b "do not drop no resend request for idle connect"
24244
24245 test_813() {
24246         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24247         [ -z "$file_heat_sav" ] && skip "no file heat support"
24248
24249         local readsample
24250         local writesample
24251         local readbyte
24252         local writebyte
24253         local readsample1
24254         local writesample1
24255         local readbyte1
24256         local writebyte1
24257
24258         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24259         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24260
24261         $LCTL set_param -n llite.*.file_heat=1
24262         echo "Turn on file heat"
24263         echo "Period second: $period_second, Decay percentage: $decay_pct"
24264
24265         echo "QQQQ" > $DIR/$tfile
24266         echo "QQQQ" > $DIR/$tfile
24267         echo "QQQQ" > $DIR/$tfile
24268         cat $DIR/$tfile > /dev/null
24269         cat $DIR/$tfile > /dev/null
24270         cat $DIR/$tfile > /dev/null
24271         cat $DIR/$tfile > /dev/null
24272
24273         local out=$($LFS heat_get $DIR/$tfile)
24274
24275         $LFS heat_get $DIR/$tfile
24276         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24277         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24278         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24279         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24280
24281         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24282         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24283         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24284         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24285
24286         sleep $((period_second + 3))
24287         echo "Sleep $((period_second + 3)) seconds..."
24288         # The recursion formula to calculate the heat of the file f is as
24289         # follow:
24290         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24291         # Where Hi is the heat value in the period between time points i*I and
24292         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24293         # to the weight of Ci.
24294         out=$($LFS heat_get $DIR/$tfile)
24295         $LFS heat_get $DIR/$tfile
24296         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24297         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24298         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24299         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24300
24301         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24302                 error "read sample ($readsample) is wrong"
24303         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24304                 error "write sample ($writesample) is wrong"
24305         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24306                 error "read bytes ($readbyte) is wrong"
24307         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24308                 error "write bytes ($writebyte) is wrong"
24309
24310         echo "QQQQ" > $DIR/$tfile
24311         echo "QQQQ" > $DIR/$tfile
24312         echo "QQQQ" > $DIR/$tfile
24313         cat $DIR/$tfile > /dev/null
24314         cat $DIR/$tfile > /dev/null
24315         cat $DIR/$tfile > /dev/null
24316         cat $DIR/$tfile > /dev/null
24317
24318         sleep $((period_second + 3))
24319         echo "Sleep $((period_second + 3)) seconds..."
24320
24321         out=$($LFS heat_get $DIR/$tfile)
24322         $LFS heat_get $DIR/$tfile
24323         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24324         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24325         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24326         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24327
24328         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24329                 4 * $decay_pct) / 100") -eq 1 ] ||
24330                 error "read sample ($readsample1) is wrong"
24331         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24332                 3 * $decay_pct) / 100") -eq 1 ] ||
24333                 error "write sample ($writesample1) is wrong"
24334         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24335                 20 * $decay_pct) / 100") -eq 1 ] ||
24336                 error "read bytes ($readbyte1) is wrong"
24337         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24338                 15 * $decay_pct) / 100") -eq 1 ] ||
24339                 error "write bytes ($writebyte1) is wrong"
24340
24341         echo "Turn off file heat for the file $DIR/$tfile"
24342         $LFS heat_set -o $DIR/$tfile
24343
24344         echo "QQQQ" > $DIR/$tfile
24345         echo "QQQQ" > $DIR/$tfile
24346         echo "QQQQ" > $DIR/$tfile
24347         cat $DIR/$tfile > /dev/null
24348         cat $DIR/$tfile > /dev/null
24349         cat $DIR/$tfile > /dev/null
24350         cat $DIR/$tfile > /dev/null
24351
24352         out=$($LFS heat_get $DIR/$tfile)
24353         $LFS heat_get $DIR/$tfile
24354         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24355         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24356         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24357         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24358
24359         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24360         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24361         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24362         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24363
24364         echo "Trun on file heat for the file $DIR/$tfile"
24365         $LFS heat_set -O $DIR/$tfile
24366
24367         echo "QQQQ" > $DIR/$tfile
24368         echo "QQQQ" > $DIR/$tfile
24369         echo "QQQQ" > $DIR/$tfile
24370         cat $DIR/$tfile > /dev/null
24371         cat $DIR/$tfile > /dev/null
24372         cat $DIR/$tfile > /dev/null
24373         cat $DIR/$tfile > /dev/null
24374
24375         out=$($LFS heat_get $DIR/$tfile)
24376         $LFS heat_get $DIR/$tfile
24377         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24378         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24379         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24380         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24381
24382         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24383         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24384         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24385         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24386
24387         $LFS heat_set -c $DIR/$tfile
24388         $LCTL set_param -n llite.*.file_heat=0
24389         echo "Turn off file heat support for the Lustre filesystem"
24390
24391         echo "QQQQ" > $DIR/$tfile
24392         echo "QQQQ" > $DIR/$tfile
24393         echo "QQQQ" > $DIR/$tfile
24394         cat $DIR/$tfile > /dev/null
24395         cat $DIR/$tfile > /dev/null
24396         cat $DIR/$tfile > /dev/null
24397         cat $DIR/$tfile > /dev/null
24398
24399         out=$($LFS heat_get $DIR/$tfile)
24400         $LFS heat_get $DIR/$tfile
24401         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24402         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24403         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24404         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24405
24406         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24407         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24408         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24409         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24410
24411         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24412         rm -f $DIR/$tfile
24413 }
24414 run_test 813 "File heat verfication"
24415
24416 test_814()
24417 {
24418         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24419         echo -n y >> $DIR/$tfile
24420         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24421         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24422 }
24423 run_test 814 "sparse cp works as expected (LU-12361)"
24424
24425 test_815()
24426 {
24427         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24428         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24429 }
24430 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24431
24432 test_816() {
24433         [ "$SHARED_KEY" = true ] &&
24434                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24435
24436         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24437         # ensure ost1 is connected
24438         stat $DIR/$tfile >/dev/null || error "can't stat"
24439         wait_osc_import_state client ost1 FULL
24440         # no locks, no reqs to let the connection idle
24441         cancel_lru_locks osc
24442         lru_resize_disable osc
24443         local before
24444         local now
24445         before=$($LCTL get_param -n \
24446                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24447
24448         wait_osc_import_state client ost1 IDLE
24449         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24450         now=$($LCTL get_param -n \
24451               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24452         [ $before == $now ] || error "lru_size changed $before != $now"
24453 }
24454 run_test 816 "do not reset lru_resize on idle reconnect"
24455
24456 cleanup_817() {
24457         umount $tmpdir
24458         exportfs -u localhost:$DIR/nfsexp
24459         rm -rf $DIR/nfsexp
24460 }
24461
24462 test_817() {
24463         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24464
24465         mkdir -p $DIR/nfsexp
24466         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24467                 error "failed to export nfs"
24468
24469         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24470         stack_trap cleanup_817 EXIT
24471
24472         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24473                 error "failed to mount nfs to $tmpdir"
24474
24475         cp /bin/true $tmpdir
24476         $DIR/nfsexp/true || error "failed to execute 'true' command"
24477 }
24478 run_test 817 "nfsd won't cache write lock for exec file"
24479
24480 test_818() {
24481         mkdir $DIR/$tdir
24482         $LFS setstripe -c1 -i0 $DIR/$tfile
24483         $LFS setstripe -c1 -i1 $DIR/$tfile
24484         stop $SINGLEMDS
24485         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24486         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24487         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24488                 error "start $SINGLEMDS failed"
24489         rm -rf $DIR/$tdir
24490 }
24491 run_test 818 "unlink with failed llog"
24492
24493 test_819a() {
24494         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24495         cancel_lru_locks osc
24496         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24497         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24498         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24499         rm -f $TDIR/$tfile
24500 }
24501 run_test 819a "too big niobuf in read"
24502
24503 test_819b() {
24504         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24505         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24506         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24507         cancel_lru_locks osc
24508         sleep 1
24509         rm -f $TDIR/$tfile
24510 }
24511 run_test 819b "too big niobuf in write"
24512
24513
24514 function test_820_start_ost() {
24515         sleep 5
24516
24517         for num in $(seq $OSTCOUNT); do
24518                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24519         done
24520 }
24521
24522 test_820() {
24523         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24524
24525         mkdir $DIR/$tdir
24526         umount_client $MOUNT || error "umount failed"
24527         for num in $(seq $OSTCOUNT); do
24528                 stop ost$num
24529         done
24530
24531         # mount client with no active OSTs
24532         # so that the client can't initialize max LOV EA size
24533         # from OSC notifications
24534         mount_client $MOUNT || error "mount failed"
24535         # delay OST starting to keep this 0 max EA size for a while
24536         test_820_start_ost &
24537
24538         # create a directory on MDS2
24539         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24540                 error "Failed to create directory"
24541         # open intent should update default EA size
24542         # see mdc_update_max_ea_from_body()
24543         # notice this is the very first RPC to MDS2
24544         cp /etc/services $DIR/$tdir/mds2 ||
24545                 error "Failed to copy files to mds$n"
24546 }
24547 run_test 820 "update max EA from open intent"
24548
24549 #
24550 # tests that do cleanup/setup should be run at the end
24551 #
24552
24553 test_900() {
24554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24555         local ls
24556
24557         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
24558         $LCTL set_param fail_loc=0x903
24559
24560         cancel_lru_locks MGC
24561
24562         FAIL_ON_ERROR=true cleanup
24563         FAIL_ON_ERROR=true setup
24564 }
24565 run_test 900 "umount should not race with any mgc requeue thread"
24566
24567 # LUS-6253/LU-11185
24568 test_901() {
24569         local oldc
24570         local newc
24571         local olds
24572         local news
24573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24574
24575         # some get_param have a bug to handle dot in param name
24576         cancel_lru_locks MGC
24577         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24578         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24579         umount_client $MOUNT || error "umount failed"
24580         mount_client $MOUNT || error "mount failed"
24581         cancel_lru_locks MGC
24582         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24583         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24584
24585         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
24586         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
24587
24588         return 0
24589 }
24590 run_test 901 "don't leak a mgc lock on client umount"
24591
24592 # LU-13377
24593 test_902() {
24594         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
24595                 skip "client does not have LU-13377 fix"
24596         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
24597         $LCTL set_param fail_loc=0x1415
24598         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24599         cancel_lru_locks osc
24600         rm -f $DIR/$tfile
24601 }
24602 run_test 902 "test short write doesn't hang lustre"
24603
24604 complete $SECONDS
24605 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
24606 check_and_cleanup_lustre
24607 if [ "$I_MOUNTED" != "yes" ]; then
24608         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
24609 fi
24610 exit_status