Whamcloud - gitweb
LU-13151 mdt: add parent FID to Changelog recordss
[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.14.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.14.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 }
4884 run_test 43A "execution of file opened for write should return -ETXTBSY"
4885
4886 test_43a() {
4887         test_mkdir $DIR/$tdir
4888         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4889         $DIR/$tdir/sleep 60 &
4890         SLEEP_PID=$!
4891         # Make sure exec of $tdir/sleep wins race with truncate
4892         sleep 1
4893         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4894         kill $SLEEP_PID
4895 }
4896 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4897
4898 test_43b() {
4899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4900
4901         test_mkdir $DIR/$tdir
4902         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4903         $DIR/$tdir/sleep 60 &
4904         SLEEP_PID=$!
4905         # Make sure exec of $tdir/sleep wins race with truncate
4906         sleep 1
4907         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4908         kill $SLEEP_PID
4909 }
4910 run_test 43b "truncate of file being executed should return -ETXTBSY"
4911
4912 test_43c() {
4913         local testdir="$DIR/$tdir"
4914         test_mkdir $testdir
4915         cp $SHELL $testdir/
4916         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4917                 ( cd $testdir && md5sum -c )
4918 }
4919 run_test 43c "md5sum of copy into lustre"
4920
4921 test_44A() { # was test_44
4922         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4923
4924         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4925         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4926 }
4927 run_test 44A "zero length read from a sparse stripe"
4928
4929 test_44a() {
4930         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4931                 awk '{ print $2 }')
4932         [ -z "$nstripe" ] && skip "can't get stripe info"
4933         [[ $nstripe -gt $OSTCOUNT ]] &&
4934                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4935
4936         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4937                 awk '{ print $2 }')
4938         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4939                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4940                         awk '{ print $2 }')
4941         fi
4942
4943         OFFSETS="0 $((stride/2)) $((stride-1))"
4944         for offset in $OFFSETS; do
4945                 for i in $(seq 0 $((nstripe-1))); do
4946                         local GLOBALOFFSETS=""
4947                         # size in Bytes
4948                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4949                         local myfn=$DIR/d44a-$size
4950                         echo "--------writing $myfn at $size"
4951                         ll_sparseness_write $myfn $size ||
4952                                 error "ll_sparseness_write"
4953                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4954                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4955                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4956
4957                         for j in $(seq 0 $((nstripe-1))); do
4958                                 # size in Bytes
4959                                 size=$((((j + $nstripe )*$stride + $offset)))
4960                                 ll_sparseness_write $myfn $size ||
4961                                         error "ll_sparseness_write"
4962                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4963                         done
4964                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4965                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4966                         rm -f $myfn
4967                 done
4968         done
4969 }
4970 run_test 44a "test sparse pwrite ==============================="
4971
4972 dirty_osc_total() {
4973         tot=0
4974         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4975                 tot=$(($tot + $d))
4976         done
4977         echo $tot
4978 }
4979 do_dirty_record() {
4980         before=`dirty_osc_total`
4981         echo executing "\"$*\""
4982         eval $*
4983         after=`dirty_osc_total`
4984         echo before $before, after $after
4985 }
4986 test_45() {
4987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4988
4989         f="$DIR/f45"
4990         # Obtain grants from OST if it supports it
4991         echo blah > ${f}_grant
4992         stop_writeback
4993         sync
4994         do_dirty_record "echo blah > $f"
4995         [[ $before -eq $after ]] && error "write wasn't cached"
4996         do_dirty_record "> $f"
4997         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4998         do_dirty_record "echo blah > $f"
4999         [[ $before -eq $after ]] && error "write wasn't cached"
5000         do_dirty_record "sync"
5001         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5002         do_dirty_record "echo blah > $f"
5003         [[ $before -eq $after ]] && error "write wasn't cached"
5004         do_dirty_record "cancel_lru_locks osc"
5005         [[ $before -gt $after ]] ||
5006                 error "lock cancellation didn't lower dirty count"
5007         start_writeback
5008 }
5009 run_test 45 "osc io page accounting ============================"
5010
5011 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5012 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5013 # objects offset and an assert hit when an rpc was built with 1023's mapped
5014 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5015 test_46() {
5016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5017
5018         f="$DIR/f46"
5019         stop_writeback
5020         sync
5021         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5022         sync
5023         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5024         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5025         sync
5026         start_writeback
5027 }
5028 run_test 46 "dirtying a previously written page ================"
5029
5030 # test_47 is removed "Device nodes check" is moved to test_28
5031
5032 test_48a() { # bug 2399
5033         [ "$mds1_FSTYPE" = "zfs" ] &&
5034         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5035                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5036
5037         test_mkdir $DIR/$tdir
5038         cd $DIR/$tdir
5039         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5040         test_mkdir $DIR/$tdir
5041         touch foo || error "'touch foo' failed after recreating cwd"
5042         test_mkdir bar
5043         touch .foo || error "'touch .foo' failed after recreating cwd"
5044         test_mkdir .bar
5045         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5046         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5047         cd . || error "'cd .' failed after recreating cwd"
5048         mkdir . && error "'mkdir .' worked after recreating cwd"
5049         rmdir . && error "'rmdir .' worked after recreating cwd"
5050         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5051         cd .. || error "'cd ..' failed after recreating cwd"
5052 }
5053 run_test 48a "Access renamed working dir (should return errors)="
5054
5055 test_48b() { # bug 2399
5056         rm -rf $DIR/$tdir
5057         test_mkdir $DIR/$tdir
5058         cd $DIR/$tdir
5059         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5060         touch foo && error "'touch foo' worked after removing cwd"
5061         mkdir foo && error "'mkdir foo' worked after removing cwd"
5062         touch .foo && error "'touch .foo' worked after removing cwd"
5063         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5064         ls . > /dev/null && error "'ls .' worked after removing cwd"
5065         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5066         mkdir . && error "'mkdir .' worked after removing cwd"
5067         rmdir . && error "'rmdir .' worked after removing cwd"
5068         ln -s . foo && error "'ln -s .' worked after removing cwd"
5069         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5070 }
5071 run_test 48b "Access removed working dir (should return errors)="
5072
5073 test_48c() { # bug 2350
5074         #lctl set_param debug=-1
5075         #set -vx
5076         rm -rf $DIR/$tdir
5077         test_mkdir -p $DIR/$tdir/dir
5078         cd $DIR/$tdir/dir
5079         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5080         $TRACE touch foo && error "touch foo worked after removing cwd"
5081         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5082         touch .foo && error "touch .foo worked after removing cwd"
5083         mkdir .foo && error "mkdir .foo worked after removing cwd"
5084         $TRACE ls . && error "'ls .' worked after removing cwd"
5085         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5086         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5087         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5088         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5089         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5090 }
5091 run_test 48c "Access removed working subdir (should return errors)"
5092
5093 test_48d() { # bug 2350
5094         #lctl set_param debug=-1
5095         #set -vx
5096         rm -rf $DIR/$tdir
5097         test_mkdir -p $DIR/$tdir/dir
5098         cd $DIR/$tdir/dir
5099         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5100         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5101         $TRACE touch foo && error "'touch foo' worked after removing parent"
5102         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5103         touch .foo && error "'touch .foo' worked after removing parent"
5104         mkdir .foo && error "mkdir .foo worked after removing parent"
5105         $TRACE ls . && error "'ls .' worked after removing parent"
5106         $TRACE ls .. && error "'ls ..' worked after removing parent"
5107         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5108         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5109         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5110         true
5111 }
5112 run_test 48d "Access removed parent subdir (should return errors)"
5113
5114 test_48e() { # bug 4134
5115         #lctl set_param debug=-1
5116         #set -vx
5117         rm -rf $DIR/$tdir
5118         test_mkdir -p $DIR/$tdir/dir
5119         cd $DIR/$tdir/dir
5120         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5121         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5122         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5123         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5124         # On a buggy kernel addition of "touch foo" after cd .. will
5125         # produce kernel oops in lookup_hash_it
5126         touch ../foo && error "'cd ..' worked after recreate parent"
5127         cd $DIR
5128         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5129 }
5130 run_test 48e "Access to recreated parent subdir (should return errors)"
5131
5132 test_49() { # LU-1030
5133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5134         remote_ost_nodsh && skip "remote OST with nodsh"
5135
5136         # get ost1 size - $FSNAME-OST0000
5137         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5138                 awk '{ print $4 }')
5139         # write 800M at maximum
5140         [[ $ost1_size -lt 2 ]] && ost1_size=2
5141         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5142
5143         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5144         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5145         local dd_pid=$!
5146
5147         # change max_pages_per_rpc while writing the file
5148         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5149         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5150         # loop until dd process exits
5151         while ps ax -opid | grep -wq $dd_pid; do
5152                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5153                 sleep $((RANDOM % 5 + 1))
5154         done
5155         # restore original max_pages_per_rpc
5156         $LCTL set_param $osc1_mppc=$orig_mppc
5157         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5158 }
5159 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5160
5161 test_50() {
5162         # bug 1485
5163         test_mkdir $DIR/$tdir
5164         cd $DIR/$tdir
5165         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5166 }
5167 run_test 50 "special situations: /proc symlinks  ==============="
5168
5169 test_51a() {    # was test_51
5170         # bug 1516 - create an empty entry right after ".." then split dir
5171         test_mkdir -c1 $DIR/$tdir
5172         touch $DIR/$tdir/foo
5173         $MCREATE $DIR/$tdir/bar
5174         rm $DIR/$tdir/foo
5175         createmany -m $DIR/$tdir/longfile 201
5176         FNUM=202
5177         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5178                 $MCREATE $DIR/$tdir/longfile$FNUM
5179                 FNUM=$(($FNUM + 1))
5180                 echo -n "+"
5181         done
5182         echo
5183         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5184 }
5185 run_test 51a "special situations: split htree with empty entry =="
5186
5187 cleanup_print_lfs_df () {
5188         trap 0
5189         $LFS df
5190         $LFS df -i
5191 }
5192
5193 test_51b() {
5194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5195
5196         local dir=$DIR/$tdir
5197         local nrdirs=$((65536 + 100))
5198
5199         # cleanup the directory
5200         rm -fr $dir
5201
5202         test_mkdir -c1 $dir
5203
5204         $LFS df
5205         $LFS df -i
5206         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5207         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5208         [[ $numfree -lt $nrdirs ]] &&
5209                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5210
5211         # need to check free space for the directories as well
5212         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5213         numfree=$(( blkfree / $(fs_inode_ksize) ))
5214         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5215
5216         trap cleanup_print_lfs_df EXIT
5217
5218         # create files
5219         createmany -d $dir/d $nrdirs || {
5220                 unlinkmany $dir/d $nrdirs
5221                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5222         }
5223
5224         # really created :
5225         nrdirs=$(ls -U $dir | wc -l)
5226
5227         # unlink all but 100 subdirectories, then check it still works
5228         local left=100
5229         local delete=$((nrdirs - left))
5230
5231         $LFS df
5232         $LFS df -i
5233
5234         # for ldiskfs the nlink count should be 1, but this is OSD specific
5235         # and so this is listed for informational purposes only
5236         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5237         unlinkmany -d $dir/d $delete ||
5238                 error "unlink of first $delete subdirs failed"
5239
5240         echo "nlink between: $(stat -c %h $dir)"
5241         local found=$(ls -U $dir | wc -l)
5242         [ $found -ne $left ] &&
5243                 error "can't find subdirs: found only $found, expected $left"
5244
5245         unlinkmany -d $dir/d $delete $left ||
5246                 error "unlink of second $left subdirs failed"
5247         # regardless of whether the backing filesystem tracks nlink accurately
5248         # or not, the nlink count shouldn't be more than "." and ".." here
5249         local after=$(stat -c %h $dir)
5250         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5251                 echo "nlink after: $after"
5252
5253         cleanup_print_lfs_df
5254 }
5255 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5256
5257 test_51d() {
5258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5259         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5260
5261         test_mkdir $DIR/$tdir
5262         createmany -o $DIR/$tdir/t- 1000
5263         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5264         for N in $(seq 0 $((OSTCOUNT - 1))); do
5265                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5266                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5267                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5268                         '($1 == '$N') { objs += 1 } \
5269                         END { printf("%0.0f", objs) }')
5270                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5271         done
5272         unlinkmany $DIR/$tdir/t- 1000
5273
5274         NLAST=0
5275         for N in $(seq 1 $((OSTCOUNT - 1))); do
5276                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5277                         error "OST $N has less objects vs OST $NLAST" \
5278                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5279                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5280                         error "OST $N has less objects vs OST $NLAST" \
5281                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5282
5283                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5284                         error "OST $N has less #0 objects vs OST $NLAST" \
5285                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5286                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5287                         error "OST $N has less #0 objects vs OST $NLAST" \
5288                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5289                 NLAST=$N
5290         done
5291         rm -f $TMP/$tfile
5292 }
5293 run_test 51d "check object distribution"
5294
5295 test_51e() {
5296         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5297                 skip_env "ldiskfs only test"
5298         fi
5299
5300         test_mkdir -c1 $DIR/$tdir
5301         test_mkdir -c1 $DIR/$tdir/d0
5302
5303         touch $DIR/$tdir/d0/foo
5304         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5305                 error "file exceed 65000 nlink limit!"
5306         unlinkmany $DIR/$tdir/d0/f- 65001
5307         return 0
5308 }
5309 run_test 51e "check file nlink limit"
5310
5311 test_51f() {
5312         test_mkdir $DIR/$tdir
5313
5314         local max=100000
5315         local ulimit_old=$(ulimit -n)
5316         local spare=20 # number of spare fd's for scripts/libraries, etc.
5317         local mdt=$($LFS getstripe -m $DIR/$tdir)
5318         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5319
5320         echo "MDT$mdt numfree=$numfree, max=$max"
5321         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5322         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5323                 while ! ulimit -n $((numfree + spare)); do
5324                         numfree=$((numfree * 3 / 4))
5325                 done
5326                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5327         else
5328                 echo "left ulimit at $ulimit_old"
5329         fi
5330
5331         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5332                 unlinkmany $DIR/$tdir/f $numfree
5333                 error "create+open $numfree files in $DIR/$tdir failed"
5334         }
5335         ulimit -n $ulimit_old
5336
5337         # if createmany exits at 120s there will be fewer than $numfree files
5338         unlinkmany $DIR/$tdir/f $numfree || true
5339 }
5340 run_test 51f "check many open files limit"
5341
5342 test_52a() {
5343         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5344         test_mkdir $DIR/$tdir
5345         touch $DIR/$tdir/foo
5346         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5347         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5348         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5349         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5350         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5351                                         error "link worked"
5352         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5353         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5354         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5355                                                      error "lsattr"
5356         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5357         cp -r $DIR/$tdir $TMP/
5358         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5359 }
5360 run_test 52a "append-only flag test (should return errors)"
5361
5362 test_52b() {
5363         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5364         test_mkdir $DIR/$tdir
5365         touch $DIR/$tdir/foo
5366         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5367         cat test > $DIR/$tdir/foo && error "cat test worked"
5368         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5369         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5370         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5371                                         error "link worked"
5372         echo foo >> $DIR/$tdir/foo && error "echo worked"
5373         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5374         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5375         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5376         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5377                                                         error "lsattr"
5378         chattr -i $DIR/$tdir/foo || error "chattr failed"
5379
5380         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5381 }
5382 run_test 52b "immutable flag test (should return errors) ======="
5383
5384 test_53() {
5385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5386         remote_mds_nodsh && skip "remote MDS with nodsh"
5387         remote_ost_nodsh && skip "remote OST with nodsh"
5388
5389         local param
5390         local param_seq
5391         local ostname
5392         local mds_last
5393         local mds_last_seq
5394         local ost_last
5395         local ost_last_seq
5396         local ost_last_id
5397         local ostnum
5398         local node
5399         local found=false
5400         local support_last_seq=true
5401
5402         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5403                 support_last_seq=false
5404
5405         # only test MDT0000
5406         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5407         local value
5408         for value in $(do_facet $SINGLEMDS \
5409                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5410                 param=$(echo ${value[0]} | cut -d "=" -f1)
5411                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5412
5413                 if $support_last_seq; then
5414                         param_seq=$(echo $param |
5415                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5416                         mds_last_seq=$(do_facet $SINGLEMDS \
5417                                        $LCTL get_param -n $param_seq)
5418                 fi
5419                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5420
5421                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5422                 node=$(facet_active_host ost$((ostnum+1)))
5423                 param="obdfilter.$ostname.last_id"
5424                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5425                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5426                         ost_last_id=$ost_last
5427
5428                         if $support_last_seq; then
5429                                 ost_last_id=$(echo $ost_last |
5430                                               awk -F':' '{print $2}' |
5431                                               sed -e "s/^0x//g")
5432                                 ost_last_seq=$(echo $ost_last |
5433                                                awk -F':' '{print $1}')
5434                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5435                         fi
5436
5437                         if [[ $ost_last_id != $mds_last ]]; then
5438                                 error "$ost_last_id != $mds_last"
5439                         else
5440                                 found=true
5441                                 break
5442                         fi
5443                 done
5444         done
5445         $found || error "can not match last_seq/last_id for $mdtosc"
5446         return 0
5447 }
5448 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5449
5450 test_54a() {
5451         perl -MSocket -e ';' || skip "no Socket perl module installed"
5452
5453         $SOCKETSERVER $DIR/socket ||
5454                 error "$SOCKETSERVER $DIR/socket failed: $?"
5455         $SOCKETCLIENT $DIR/socket ||
5456                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5457         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5458 }
5459 run_test 54a "unix domain socket test =========================="
5460
5461 test_54b() {
5462         f="$DIR/f54b"
5463         mknod $f c 1 3
5464         chmod 0666 $f
5465         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5466 }
5467 run_test 54b "char device works in lustre ======================"
5468
5469 find_loop_dev() {
5470         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5471         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5472         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5473
5474         for i in $(seq 3 7); do
5475                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5476                 LOOPDEV=$LOOPBASE$i
5477                 LOOPNUM=$i
5478                 break
5479         done
5480 }
5481
5482 cleanup_54c() {
5483         local rc=0
5484         loopdev="$DIR/loop54c"
5485
5486         trap 0
5487         $UMOUNT $DIR/$tdir || rc=$?
5488         losetup -d $loopdev || true
5489         losetup -d $LOOPDEV || true
5490         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5491         return $rc
5492 }
5493
5494 test_54c() {
5495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5496
5497         loopdev="$DIR/loop54c"
5498
5499         find_loop_dev
5500         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5501         trap cleanup_54c EXIT
5502         mknod $loopdev b 7 $LOOPNUM
5503         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5504         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5505         losetup $loopdev $DIR/$tfile ||
5506                 error "can't set up $loopdev for $DIR/$tfile"
5507         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5508         test_mkdir $DIR/$tdir
5509         mount -t ext2 $loopdev $DIR/$tdir ||
5510                 error "error mounting $loopdev on $DIR/$tdir"
5511         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5512                 error "dd write"
5513         df $DIR/$tdir
5514         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5515                 error "dd read"
5516         cleanup_54c
5517 }
5518 run_test 54c "block device works in lustre ====================="
5519
5520 test_54d() {
5521         f="$DIR/f54d"
5522         string="aaaaaa"
5523         mknod $f p
5524         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5525 }
5526 run_test 54d "fifo device works in lustre ======================"
5527
5528 test_54e() {
5529         f="$DIR/f54e"
5530         string="aaaaaa"
5531         cp -aL /dev/console $f
5532         echo $string > $f || error "echo $string to $f failed"
5533 }
5534 run_test 54e "console/tty device works in lustre ======================"
5535
5536 test_56a() {
5537         local numfiles=3
5538         local dir=$DIR/$tdir
5539
5540         rm -rf $dir
5541         test_mkdir -p $dir/dir
5542         for i in $(seq $numfiles); do
5543                 touch $dir/file$i
5544                 touch $dir/dir/file$i
5545         done
5546
5547         local numcomp=$($LFS getstripe --component-count $dir)
5548
5549         [[ $numcomp == 0 ]] && numcomp=1
5550
5551         # test lfs getstripe with --recursive
5552         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5553
5554         [[ $filenum -eq $((numfiles * 2)) ]] ||
5555                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5556         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5557         [[ $filenum -eq $numfiles ]] ||
5558                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5559         echo "$LFS getstripe showed obdidx or l_ost_idx"
5560
5561         # test lfs getstripe with file instead of dir
5562         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5563         [[ $filenum -eq 1 ]] ||
5564                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5565         echo "$LFS getstripe file1 passed"
5566
5567         #test lfs getstripe with --verbose
5568         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5569         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5570                 error "$LFS getstripe --verbose $dir: "\
5571                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5572         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5573                 error "$LFS getstripe $dir: showed lmm_magic"
5574
5575         #test lfs getstripe with -v prints lmm_fid
5576         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5577         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5578                 error "$LFS getstripe -v $dir: "\
5579                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5580         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5581                 error "$LFS getstripe $dir: showed lmm_fid by default"
5582         echo "$LFS getstripe --verbose passed"
5583
5584         #check for FID information
5585         local fid1=$($LFS getstripe --fid $dir/file1)
5586         local fid2=$($LFS getstripe --verbose $dir/file1 |
5587                      awk '/lmm_fid: / { print $2; exit; }')
5588         local fid3=$($LFS path2fid $dir/file1)
5589
5590         [ "$fid1" != "$fid2" ] &&
5591                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5592         [ "$fid1" != "$fid3" ] &&
5593                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5594         echo "$LFS getstripe --fid passed"
5595
5596         #test lfs getstripe with --obd
5597         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5598                 error "$LFS getstripe --obd wrong_uuid: should return error"
5599
5600         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5601
5602         local ostidx=1
5603         local obduuid=$(ostuuid_from_index $ostidx)
5604         local found=$($LFS getstripe -r --obd $obduuid $dir |
5605                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5606
5607         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5608         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5609                 ((filenum--))
5610         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5611                 ((filenum--))
5612
5613         [[ $found -eq $filenum ]] ||
5614                 error "$LFS getstripe --obd: found $found expect $filenum"
5615         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5616                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5617                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5618                 error "$LFS getstripe --obd: should not show file on other obd"
5619         echo "$LFS getstripe --obd passed"
5620 }
5621 run_test 56a "check $LFS getstripe"
5622
5623 test_56b() {
5624         local dir=$DIR/$tdir
5625         local numdirs=3
5626
5627         test_mkdir $dir
5628         for i in $(seq $numdirs); do
5629                 test_mkdir $dir/dir$i
5630         done
5631
5632         # test lfs getdirstripe default mode is non-recursion, which is
5633         # different from lfs getstripe
5634         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5635
5636         [[ $dircnt -eq 1 ]] ||
5637                 error "$LFS getdirstripe: found $dircnt, not 1"
5638         dircnt=$($LFS getdirstripe --recursive $dir |
5639                 grep -c lmv_stripe_count)
5640         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5641                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5642 }
5643 run_test 56b "check $LFS getdirstripe"
5644
5645 test_56c() {
5646         remote_ost_nodsh && skip "remote OST with nodsh"
5647
5648         local ost_idx=0
5649         local ost_name=$(ostname_from_index $ost_idx)
5650         local old_status=$(ost_dev_status $ost_idx)
5651         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5652
5653         [[ -z "$old_status" ]] ||
5654                 skip_env "OST $ost_name is in $old_status status"
5655
5656         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5657         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5658                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5659         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5660                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5661                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5662         fi
5663
5664         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5665                 error "$LFS df -v showing inactive devices"
5666         sleep_maxage
5667
5668         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5669
5670         [[ "$new_status" =~ "D" ]] ||
5671                 error "$ost_name status is '$new_status', missing 'D'"
5672         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5673                 [[ "$new_status" =~ "N" ]] ||
5674                         error "$ost_name status is '$new_status', missing 'N'"
5675         fi
5676         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5677                 [[ "$new_status" =~ "f" ]] ||
5678                         error "$ost_name status is '$new_status', missing 'f'"
5679         fi
5680
5681         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5682         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5683                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5684         [[ -z "$p" ]] && restore_lustre_params < $p || true
5685         sleep_maxage
5686
5687         new_status=$(ost_dev_status $ost_idx)
5688         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5689                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5690         # can't check 'f' as devices may actually be on flash
5691 }
5692 run_test 56c "check 'lfs df' showing device status"
5693
5694 test_56d() {
5695         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5696         local osts=$($LFS df -v $MOUNT | grep -c OST)
5697
5698         $LFS df $MOUNT
5699
5700         (( mdts == MDSCOUNT )) ||
5701                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5702         (( osts == OSTCOUNT )) ||
5703                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5704 }
5705 run_test 56d "'lfs df -v' prints only configured devices"
5706
5707 NUMFILES=3
5708 NUMDIRS=3
5709 setup_56() {
5710         local local_tdir="$1"
5711         local local_numfiles="$2"
5712         local local_numdirs="$3"
5713         local dir_params="$4"
5714         local dir_stripe_params="$5"
5715
5716         if [ ! -d "$local_tdir" ] ; then
5717                 test_mkdir -p $dir_stripe_params $local_tdir
5718                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5719                 for i in $(seq $local_numfiles) ; do
5720                         touch $local_tdir/file$i
5721                 done
5722                 for i in $(seq $local_numdirs) ; do
5723                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5724                         for j in $(seq $local_numfiles) ; do
5725                                 touch $local_tdir/dir$i/file$j
5726                         done
5727                 done
5728         fi
5729 }
5730
5731 setup_56_special() {
5732         local local_tdir=$1
5733         local local_numfiles=$2
5734         local local_numdirs=$3
5735
5736         setup_56 $local_tdir $local_numfiles $local_numdirs
5737
5738         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5739                 for i in $(seq $local_numfiles) ; do
5740                         mknod $local_tdir/loop${i}b b 7 $i
5741                         mknod $local_tdir/null${i}c c 1 3
5742                         ln -s $local_tdir/file1 $local_tdir/link${i}
5743                 done
5744                 for i in $(seq $local_numdirs) ; do
5745                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5746                         mknod $local_tdir/dir$i/null${i}c c 1 3
5747                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5748                 done
5749         fi
5750 }
5751
5752 test_56g() {
5753         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5754         local expected=$(($NUMDIRS + 2))
5755
5756         setup_56 $dir $NUMFILES $NUMDIRS
5757
5758         # test lfs find with -name
5759         for i in $(seq $NUMFILES) ; do
5760                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5761
5762                 [ $nums -eq $expected ] ||
5763                         error "lfs find -name '*$i' $dir wrong: "\
5764                               "found $nums, expected $expected"
5765         done
5766 }
5767 run_test 56g "check lfs find -name"
5768
5769 test_56h() {
5770         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5771         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5772
5773         setup_56 $dir $NUMFILES $NUMDIRS
5774
5775         # test lfs find with ! -name
5776         for i in $(seq $NUMFILES) ; do
5777                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5778
5779                 [ $nums -eq $expected ] ||
5780                         error "lfs find ! -name '*$i' $dir wrong: "\
5781                               "found $nums, expected $expected"
5782         done
5783 }
5784 run_test 56h "check lfs find ! -name"
5785
5786 test_56i() {
5787         local dir=$DIR/$tdir
5788
5789         test_mkdir $dir
5790
5791         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5792         local out=$($cmd)
5793
5794         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5795 }
5796 run_test 56i "check 'lfs find -ost UUID' skips directories"
5797
5798 test_56j() {
5799         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5800
5801         setup_56_special $dir $NUMFILES $NUMDIRS
5802
5803         local expected=$((NUMDIRS + 1))
5804         local cmd="$LFS find -type d $dir"
5805         local nums=$($cmd | wc -l)
5806
5807         [ $nums -eq $expected ] ||
5808                 error "'$cmd' wrong: found $nums, expected $expected"
5809 }
5810 run_test 56j "check lfs find -type d"
5811
5812 test_56k() {
5813         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5814
5815         setup_56_special $dir $NUMFILES $NUMDIRS
5816
5817         local expected=$(((NUMDIRS + 1) * NUMFILES))
5818         local cmd="$LFS find -type f $dir"
5819         local nums=$($cmd | wc -l)
5820
5821         [ $nums -eq $expected ] ||
5822                 error "'$cmd' wrong: found $nums, expected $expected"
5823 }
5824 run_test 56k "check lfs find -type f"
5825
5826 test_56l() {
5827         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5828
5829         setup_56_special $dir $NUMFILES $NUMDIRS
5830
5831         local expected=$((NUMDIRS + NUMFILES))
5832         local cmd="$LFS find -type b $dir"
5833         local nums=$($cmd | wc -l)
5834
5835         [ $nums -eq $expected ] ||
5836                 error "'$cmd' wrong: found $nums, expected $expected"
5837 }
5838 run_test 56l "check lfs find -type b"
5839
5840 test_56m() {
5841         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5842
5843         setup_56_special $dir $NUMFILES $NUMDIRS
5844
5845         local expected=$((NUMDIRS + NUMFILES))
5846         local cmd="$LFS find -type c $dir"
5847         local nums=$($cmd | wc -l)
5848         [ $nums -eq $expected ] ||
5849                 error "'$cmd' wrong: found $nums, expected $expected"
5850 }
5851 run_test 56m "check lfs find -type c"
5852
5853 test_56n() {
5854         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5855         setup_56_special $dir $NUMFILES $NUMDIRS
5856
5857         local expected=$((NUMDIRS + NUMFILES))
5858         local cmd="$LFS find -type l $dir"
5859         local nums=$($cmd | wc -l)
5860
5861         [ $nums -eq $expected ] ||
5862                 error "'$cmd' wrong: found $nums, expected $expected"
5863 }
5864 run_test 56n "check lfs find -type l"
5865
5866 test_56o() {
5867         local dir=$DIR/$tdir
5868
5869         setup_56 $dir $NUMFILES $NUMDIRS
5870         utime $dir/file1 > /dev/null || error "utime (1)"
5871         utime $dir/file2 > /dev/null || error "utime (2)"
5872         utime $dir/dir1 > /dev/null || error "utime (3)"
5873         utime $dir/dir2 > /dev/null || error "utime (4)"
5874         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5875         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5876
5877         local expected=4
5878         local nums=$($LFS find -mtime +0 $dir | wc -l)
5879
5880         [ $nums -eq $expected ] ||
5881                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5882
5883         expected=12
5884         cmd="$LFS find -mtime 0 $dir"
5885         nums=$($cmd | wc -l)
5886         [ $nums -eq $expected ] ||
5887                 error "'$cmd' wrong: found $nums, expected $expected"
5888 }
5889 run_test 56o "check lfs find -mtime for old files"
5890
5891 test_56ob() {
5892         local dir=$DIR/$tdir
5893         local expected=1
5894         local count=0
5895
5896         # just to make sure there is something that won't be found
5897         test_mkdir $dir
5898         touch $dir/$tfile.now
5899
5900         for age in year week day hour min; do
5901                 count=$((count + 1))
5902
5903                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5904                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5905                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5906
5907                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5908                 local nums=$($cmd | wc -l)
5909                 [ $nums -eq $expected ] ||
5910                         error "'$cmd' wrong: found $nums, expected $expected"
5911
5912                 cmd="$LFS find $dir -atime $count${age:0:1}"
5913                 nums=$($cmd | wc -l)
5914                 [ $nums -eq $expected ] ||
5915                         error "'$cmd' wrong: found $nums, expected $expected"
5916         done
5917
5918         sleep 2
5919         cmd="$LFS find $dir -ctime +1s -type f"
5920         nums=$($cmd | wc -l)
5921         (( $nums == $count * 2 + 1)) ||
5922                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
5923 }
5924 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5925
5926 test_newerXY_base() {
5927         local x=$1
5928         local y=$2
5929         local dir=$DIR/$tdir
5930         local ref
5931         local negref
5932
5933         if [ $y == "t" ]; then
5934                 if [ $x == "b" ]; then
5935                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5936                 else
5937                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5938                 fi
5939         else
5940                 ref=$DIR/$tfile.newer.$x$y
5941                 touch $ref || error "touch $ref failed"
5942         fi
5943         sleep 2
5944         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5945         sleep 2
5946         if [ $y == "t" ]; then
5947                 if [ $x == "b" ]; then
5948                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5949                 else
5950                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5951                 fi
5952         else
5953                 negref=$DIR/$tfile.negnewer.$x$y
5954                 touch $negref || error "touch $negref failed"
5955         fi
5956
5957         local cmd="$LFS find $dir -newer$x$y $ref"
5958         local nums=$(eval $cmd | wc -l)
5959         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5960
5961         [ $nums -eq $expected ] ||
5962                 error "'$cmd' wrong: found $nums, expected $expected"
5963
5964         cmd="$LFS find $dir ! -newer$x$y $negref"
5965         nums=$(eval $cmd | wc -l)
5966         [ $nums -eq $expected ] ||
5967                 error "'$cmd' wrong: found $nums, expected $expected"
5968
5969         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
5970         nums=$(eval $cmd | wc -l)
5971         [ $nums -eq $expected ] ||
5972                 error "'$cmd' wrong: found $nums, expected $expected"
5973
5974         rm -rf $DIR/*
5975 }
5976
5977 test_56oc() {
5978         test_newerXY_base "b" "t"
5979         test_newerXY_base "a" "a"
5980         test_newerXY_base "a" "m"
5981         test_newerXY_base "a" "c"
5982         test_newerXY_base "m" "a"
5983         test_newerXY_base "m" "m"
5984         test_newerXY_base "m" "c"
5985         test_newerXY_base "c" "a"
5986         test_newerXY_base "c" "m"
5987         test_newerXY_base "c" "c"
5988         test_newerXY_base "b" "b"
5989         test_newerXY_base "a" "t"
5990         test_newerXY_base "m" "t"
5991         test_newerXY_base "c" "t"
5992         test_newerXY_base "b" "t"
5993 }
5994 run_test 56oc "check lfs find -newerXY work"
5995
5996 btime_supported() {
5997         local dir=$DIR/$tdir
5998         local rc
5999
6000         mkdir -p $dir
6001         touch $dir/$tfile
6002         $LFS find $dir -btime -1d -type f
6003         rc=$?
6004         rm -rf $dir
6005         return $rc
6006 }
6007
6008 test_56od() {
6009         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6010                 ! btime_supported && skip "btime unsupported on MDS"
6011
6012         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6013                 ! btime_supported && skip "btime unsupported on clients"
6014
6015         local dir=$DIR/$tdir
6016         local ref=$DIR/$tfile.ref
6017         local negref=$DIR/$tfile.negref
6018
6019         mkdir $dir || error "mkdir $dir failed"
6020         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6021         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6022         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6023         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6024         touch $ref || error "touch $ref failed"
6025         # sleep 3 seconds at least
6026         sleep 3
6027
6028         local before=$(do_facet mds1 date +%s)
6029         local skew=$(($(date +%s) - before + 1))
6030
6031         if (( skew < 0 && skew > -5 )); then
6032                 sleep $((0 - skew + 1))
6033                 skew=0
6034         fi
6035
6036         # Set the dir stripe params to limit files all on MDT0,
6037         # otherwise we need to calc the max clock skew between
6038         # the client and MDTs.
6039         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6040         sleep 2
6041         touch $negref || error "touch $negref failed"
6042
6043         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6044         local nums=$($cmd | wc -l)
6045         local expected=$(((NUMFILES + 1) * NUMDIRS))
6046
6047         [ $nums -eq $expected ] ||
6048                 error "'$cmd' wrong: found $nums, expected $expected"
6049
6050         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6051         nums=$($cmd | wc -l)
6052         expected=$((NUMFILES + 1))
6053         [ $nums -eq $expected ] ||
6054                 error "'$cmd' wrong: found $nums, expected $expected"
6055
6056         [ $skew -lt 0 ] && return
6057
6058         local after=$(do_facet mds1 date +%s)
6059         local age=$((after - before + 1 + skew))
6060
6061         cmd="$LFS find $dir -btime -${age}s -type f"
6062         nums=$($cmd | wc -l)
6063         expected=$(((NUMFILES + 1) * NUMDIRS))
6064
6065         echo "Clock skew between client and server: $skew, age:$age"
6066         [ $nums -eq $expected ] ||
6067                 error "'$cmd' wrong: found $nums, expected $expected"
6068
6069         expected=$(($NUMDIRS + 1))
6070         cmd="$LFS find $dir -btime -${age}s -type d"
6071         nums=$($cmd | wc -l)
6072         [ $nums -eq $expected ] ||
6073                 error "'$cmd' wrong: found $nums, expected $expected"
6074         rm -f $ref $negref || error "Failed to remove $ref $negref"
6075 }
6076 run_test 56od "check lfs find -btime with units"
6077
6078 test_56p() {
6079         [ $RUNAS_ID -eq $UID ] &&
6080                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6081
6082         local dir=$DIR/$tdir
6083
6084         setup_56 $dir $NUMFILES $NUMDIRS
6085         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6086
6087         local expected=$NUMFILES
6088         local cmd="$LFS find -uid $RUNAS_ID $dir"
6089         local nums=$($cmd | wc -l)
6090
6091         [ $nums -eq $expected ] ||
6092                 error "'$cmd' wrong: found $nums, expected $expected"
6093
6094         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6095         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6096         nums=$($cmd | wc -l)
6097         [ $nums -eq $expected ] ||
6098                 error "'$cmd' wrong: found $nums, expected $expected"
6099 }
6100 run_test 56p "check lfs find -uid and ! -uid"
6101
6102 test_56q() {
6103         [ $RUNAS_ID -eq $UID ] &&
6104                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6105
6106         local dir=$DIR/$tdir
6107
6108         setup_56 $dir $NUMFILES $NUMDIRS
6109         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6110
6111         local expected=$NUMFILES
6112         local cmd="$LFS find -gid $RUNAS_GID $dir"
6113         local nums=$($cmd | wc -l)
6114
6115         [ $nums -eq $expected ] ||
6116                 error "'$cmd' wrong: found $nums, expected $expected"
6117
6118         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6119         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6120         nums=$($cmd | wc -l)
6121         [ $nums -eq $expected ] ||
6122                 error "'$cmd' wrong: found $nums, expected $expected"
6123 }
6124 run_test 56q "check lfs find -gid and ! -gid"
6125
6126 test_56r() {
6127         local dir=$DIR/$tdir
6128
6129         setup_56 $dir $NUMFILES $NUMDIRS
6130
6131         local expected=12
6132         local cmd="$LFS find -size 0 -type f -lazy $dir"
6133         local nums=$($cmd | wc -l)
6134
6135         [ $nums -eq $expected ] ||
6136                 error "'$cmd' wrong: found $nums, expected $expected"
6137         cmd="$LFS find -size 0 -type f $dir"
6138         nums=$($cmd | wc -l)
6139         [ $nums -eq $expected ] ||
6140                 error "'$cmd' wrong: found $nums, expected $expected"
6141
6142         expected=0
6143         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6144         nums=$($cmd | wc -l)
6145         [ $nums -eq $expected ] ||
6146                 error "'$cmd' wrong: found $nums, expected $expected"
6147         cmd="$LFS find ! -size 0 -type f $dir"
6148         nums=$($cmd | wc -l)
6149         [ $nums -eq $expected ] ||
6150                 error "'$cmd' wrong: found $nums, expected $expected"
6151
6152         echo "test" > $dir/$tfile
6153         echo "test2" > $dir/$tfile.2 && sync
6154         expected=1
6155         cmd="$LFS find -size 5 -type f -lazy $dir"
6156         nums=$($cmd | wc -l)
6157         [ $nums -eq $expected ] ||
6158                 error "'$cmd' wrong: found $nums, expected $expected"
6159         cmd="$LFS find -size 5 -type f $dir"
6160         nums=$($cmd | wc -l)
6161         [ $nums -eq $expected ] ||
6162                 error "'$cmd' wrong: found $nums, expected $expected"
6163
6164         expected=1
6165         cmd="$LFS find -size +5 -type f -lazy $dir"
6166         nums=$($cmd | wc -l)
6167         [ $nums -eq $expected ] ||
6168                 error "'$cmd' wrong: found $nums, expected $expected"
6169         cmd="$LFS find -size +5 -type f $dir"
6170         nums=$($cmd | wc -l)
6171         [ $nums -eq $expected ] ||
6172                 error "'$cmd' wrong: found $nums, expected $expected"
6173
6174         expected=2
6175         cmd="$LFS find -size +0 -type f -lazy $dir"
6176         nums=$($cmd | wc -l)
6177         [ $nums -eq $expected ] ||
6178                 error "'$cmd' wrong: found $nums, expected $expected"
6179         cmd="$LFS find -size +0 -type f $dir"
6180         nums=$($cmd | wc -l)
6181         [ $nums -eq $expected ] ||
6182                 error "'$cmd' wrong: found $nums, expected $expected"
6183
6184         expected=2
6185         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6186         nums=$($cmd | wc -l)
6187         [ $nums -eq $expected ] ||
6188                 error "'$cmd' wrong: found $nums, expected $expected"
6189         cmd="$LFS find ! -size -5 -type f $dir"
6190         nums=$($cmd | wc -l)
6191         [ $nums -eq $expected ] ||
6192                 error "'$cmd' wrong: found $nums, expected $expected"
6193
6194         expected=12
6195         cmd="$LFS find -size -5 -type f -lazy $dir"
6196         nums=$($cmd | wc -l)
6197         [ $nums -eq $expected ] ||
6198                 error "'$cmd' wrong: found $nums, expected $expected"
6199         cmd="$LFS find -size -5 -type f $dir"
6200         nums=$($cmd | wc -l)
6201         [ $nums -eq $expected ] ||
6202                 error "'$cmd' wrong: found $nums, expected $expected"
6203 }
6204 run_test 56r "check lfs find -size works"
6205
6206 test_56ra_sub() {
6207         local expected=$1
6208         local glimpses=$2
6209         local cmd="$3"
6210
6211         cancel_lru_locks $OSC
6212
6213         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6214         local nums=$($cmd | wc -l)
6215
6216         [ $nums -eq $expected ] ||
6217                 error "'$cmd' wrong: found $nums, expected $expected"
6218
6219         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6220
6221         if (( rpcs_before + glimpses != rpcs_after )); then
6222                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6223                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6224
6225                 if [[ $glimpses == 0 ]]; then
6226                         error "'$cmd' should not send glimpse RPCs to OST"
6227                 else
6228                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6229                 fi
6230         fi
6231 }
6232
6233 test_56ra() {
6234         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6235                 skip "MDS < 2.12.58 doesn't return LSOM data"
6236         local dir=$DIR/$tdir
6237
6238         [[ $OSC == "mdc" ]] && skip "DoM files" && return
6239
6240         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6241         # open and close all files to ensure LSOM is updated
6242         cancel_lru_locks $OSC
6243         find $dir -type f | xargs cat > /dev/null
6244
6245         #   expect_found  glimpse_rpcs  command_to_run
6246         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6247         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6248         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6249         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6250
6251         echo "test" > $dir/$tfile
6252         echo "test2" > $dir/$tfile.2 && sync
6253         cancel_lru_locks $OSC
6254         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6255
6256         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6257         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6258         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6259         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6260
6261         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6262         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6263         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6264         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6265         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6266         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6267 }
6268 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6269
6270 test_56rb() {
6271         local dir=$DIR/$tdir
6272         local tmp=$TMP/$tfile.log
6273         local mdt_idx;
6274
6275         test_mkdir -p $dir || error "failed to mkdir $dir"
6276         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6277                 error "failed to setstripe $dir/$tfile"
6278         mdt_idx=$($LFS getdirstripe -i $dir)
6279         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6280
6281         stack_trap "rm -f $tmp" EXIT
6282         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6283         ! grep -q obd_uuid $tmp ||
6284                 error "failed to find --size +100K --ost 0 $dir"
6285         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6286         ! grep -q obd_uuid $tmp ||
6287                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6288 }
6289 run_test 56rb "check lfs find --size --ost/--mdt works"
6290
6291 test_56s() { # LU-611 #LU-9369
6292         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6293
6294         local dir=$DIR/$tdir
6295         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6296
6297         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6298         for i in $(seq $NUMDIRS); do
6299                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6300         done
6301
6302         local expected=$NUMDIRS
6303         local cmd="$LFS find -c $OSTCOUNT $dir"
6304         local nums=$($cmd | wc -l)
6305
6306         [ $nums -eq $expected ] || {
6307                 $LFS getstripe -R $dir
6308                 error "'$cmd' wrong: found $nums, expected $expected"
6309         }
6310
6311         expected=$((NUMDIRS + onestripe))
6312         cmd="$LFS find -stripe-count +0 -type f $dir"
6313         nums=$($cmd | wc -l)
6314         [ $nums -eq $expected ] || {
6315                 $LFS getstripe -R $dir
6316                 error "'$cmd' wrong: found $nums, expected $expected"
6317         }
6318
6319         expected=$onestripe
6320         cmd="$LFS find -stripe-count 1 -type f $dir"
6321         nums=$($cmd | wc -l)
6322         [ $nums -eq $expected ] || {
6323                 $LFS getstripe -R $dir
6324                 error "'$cmd' wrong: found $nums, expected $expected"
6325         }
6326
6327         cmd="$LFS find -stripe-count -2 -type f $dir"
6328         nums=$($cmd | wc -l)
6329         [ $nums -eq $expected ] || {
6330                 $LFS getstripe -R $dir
6331                 error "'$cmd' wrong: found $nums, expected $expected"
6332         }
6333
6334         expected=0
6335         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -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 run_test 56s "check lfs find -stripe-count works"
6343
6344 test_56t() { # LU-611 #LU-9369
6345         local dir=$DIR/$tdir
6346
6347         setup_56 $dir 0 $NUMDIRS
6348         for i in $(seq $NUMDIRS); do
6349                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6350         done
6351
6352         local expected=$NUMDIRS
6353         local cmd="$LFS find -S 8M $dir"
6354         local nums=$($cmd | wc -l)
6355
6356         [ $nums -eq $expected ] || {
6357                 $LFS getstripe -R $dir
6358                 error "'$cmd' wrong: found $nums, expected $expected"
6359         }
6360         rm -rf $dir
6361
6362         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6363
6364         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6365
6366         expected=$(((NUMDIRS + 1) * NUMFILES))
6367         cmd="$LFS find -stripe-size 512k -type f $dir"
6368         nums=$($cmd | wc -l)
6369         [ $nums -eq $expected ] ||
6370                 error "'$cmd' wrong: found $nums, expected $expected"
6371
6372         cmd="$LFS find -stripe-size +320k -type f $dir"
6373         nums=$($cmd | wc -l)
6374         [ $nums -eq $expected ] ||
6375                 error "'$cmd' wrong: found $nums, expected $expected"
6376
6377         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6378         cmd="$LFS find -stripe-size +200k -type f $dir"
6379         nums=$($cmd | wc -l)
6380         [ $nums -eq $expected ] ||
6381                 error "'$cmd' wrong: found $nums, expected $expected"
6382
6383         cmd="$LFS find -stripe-size -640k -type f $dir"
6384         nums=$($cmd | wc -l)
6385         [ $nums -eq $expected ] ||
6386                 error "'$cmd' wrong: found $nums, expected $expected"
6387
6388         expected=4
6389         cmd="$LFS find -stripe-size 256k -type f $dir"
6390         nums=$($cmd | wc -l)
6391         [ $nums -eq $expected ] ||
6392                 error "'$cmd' wrong: found $nums, expected $expected"
6393
6394         cmd="$LFS find -stripe-size -320k -type f $dir"
6395         nums=$($cmd | wc -l)
6396         [ $nums -eq $expected ] ||
6397                 error "'$cmd' wrong: found $nums, expected $expected"
6398
6399         expected=0
6400         cmd="$LFS find -stripe-size 1024k -type f $dir"
6401         nums=$($cmd | wc -l)
6402         [ $nums -eq $expected ] ||
6403                 error "'$cmd' wrong: found $nums, expected $expected"
6404 }
6405 run_test 56t "check lfs find -stripe-size works"
6406
6407 test_56u() { # LU-611
6408         local dir=$DIR/$tdir
6409
6410         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6411
6412         if [[ $OSTCOUNT -gt 1 ]]; then
6413                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6414                 onestripe=4
6415         else
6416                 onestripe=0
6417         fi
6418
6419         local expected=$(((NUMDIRS + 1) * NUMFILES))
6420         local cmd="$LFS find -stripe-index 0 -type f $dir"
6421         local nums=$($cmd | wc -l)
6422
6423         [ $nums -eq $expected ] ||
6424                 error "'$cmd' wrong: found $nums, expected $expected"
6425
6426         expected=$onestripe
6427         cmd="$LFS find -stripe-index 1 -type f $dir"
6428         nums=$($cmd | wc -l)
6429         [ $nums -eq $expected ] ||
6430                 error "'$cmd' wrong: found $nums, expected $expected"
6431
6432         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6433         nums=$($cmd | wc -l)
6434         [ $nums -eq $expected ] ||
6435                 error "'$cmd' wrong: found $nums, expected $expected"
6436
6437         expected=0
6438         # This should produce an error and not return any files
6439         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6440         nums=$($cmd 2>/dev/null | wc -l)
6441         [ $nums -eq $expected ] ||
6442                 error "'$cmd' wrong: found $nums, expected $expected"
6443
6444         if [[ $OSTCOUNT -gt 1 ]]; then
6445                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6446                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6447                 nums=$($cmd | wc -l)
6448                 [ $nums -eq $expected ] ||
6449                         error "'$cmd' wrong: found $nums, expected $expected"
6450         fi
6451 }
6452 run_test 56u "check lfs find -stripe-index works"
6453
6454 test_56v() {
6455         local mdt_idx=0
6456         local dir=$DIR/$tdir
6457
6458         setup_56 $dir $NUMFILES $NUMDIRS
6459
6460         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6461         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6462
6463         for file in $($LFS find -m $UUID $dir); do
6464                 file_midx=$($LFS getstripe -m $file)
6465                 [ $file_midx -eq $mdt_idx ] ||
6466                         error "lfs find -m $UUID != getstripe -m $file_midx"
6467         done
6468 }
6469 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6470
6471 test_56w() {
6472         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6474
6475         local dir=$DIR/$tdir
6476
6477         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6478
6479         local stripe_size=$($LFS getstripe -S -d $dir) ||
6480                 error "$LFS getstripe -S -d $dir failed"
6481         stripe_size=${stripe_size%% *}
6482
6483         local file_size=$((stripe_size * OSTCOUNT))
6484         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6485         local required_space=$((file_num * file_size))
6486         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6487                            head -n1)
6488         [[ $free_space -le $((required_space / 1024)) ]] &&
6489                 skip_env "need $required_space, have $free_space kbytes"
6490
6491         local dd_bs=65536
6492         local dd_count=$((file_size / dd_bs))
6493
6494         # write data into the files
6495         local i
6496         local j
6497         local file
6498
6499         for i in $(seq $NUMFILES); do
6500                 file=$dir/file$i
6501                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6502                         error "write data into $file failed"
6503         done
6504         for i in $(seq $NUMDIRS); do
6505                 for j in $(seq $NUMFILES); do
6506                         file=$dir/dir$i/file$j
6507                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6508                                 error "write data into $file failed"
6509                 done
6510         done
6511
6512         # $LFS_MIGRATE will fail if hard link migration is unsupported
6513         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6514                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6515                         error "creating links to $dir/dir1/file1 failed"
6516         fi
6517
6518         local expected=-1
6519
6520         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6521
6522         # lfs_migrate file
6523         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6524
6525         echo "$cmd"
6526         eval $cmd || error "$cmd failed"
6527
6528         check_stripe_count $dir/file1 $expected
6529
6530         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6531         then
6532                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6533                 # OST 1 if it is on OST 0. This file is small enough to
6534                 # be on only one stripe.
6535                 file=$dir/migr_1_ost
6536                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6537                         error "write data into $file failed"
6538                 local obdidx=$($LFS getstripe -i $file)
6539                 local oldmd5=$(md5sum $file)
6540                 local newobdidx=0
6541
6542                 [[ $obdidx -eq 0 ]] && newobdidx=1
6543                 cmd="$LFS migrate -i $newobdidx $file"
6544                 echo $cmd
6545                 eval $cmd || error "$cmd failed"
6546
6547                 local realobdix=$($LFS getstripe -i $file)
6548                 local newmd5=$(md5sum $file)
6549
6550                 [[ $newobdidx -ne $realobdix ]] &&
6551                         error "new OST is different (was=$obdidx, "\
6552                               "wanted=$newobdidx, got=$realobdix)"
6553                 [[ "$oldmd5" != "$newmd5" ]] &&
6554                         error "md5sum differ: $oldmd5, $newmd5"
6555         fi
6556
6557         # lfs_migrate dir
6558         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6559         echo "$cmd"
6560         eval $cmd || error "$cmd failed"
6561
6562         for j in $(seq $NUMFILES); do
6563                 check_stripe_count $dir/dir1/file$j $expected
6564         done
6565
6566         # lfs_migrate works with lfs find
6567         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6568              $LFS_MIGRATE -y -c $expected"
6569         echo "$cmd"
6570         eval $cmd || error "$cmd failed"
6571
6572         for i in $(seq 2 $NUMFILES); do
6573                 check_stripe_count $dir/file$i $expected
6574         done
6575         for i in $(seq 2 $NUMDIRS); do
6576                 for j in $(seq $NUMFILES); do
6577                 check_stripe_count $dir/dir$i/file$j $expected
6578                 done
6579         done
6580 }
6581 run_test 56w "check lfs_migrate -c stripe_count works"
6582
6583 test_56wb() {
6584         local file1=$DIR/$tdir/file1
6585         local create_pool=false
6586         local initial_pool=$($LFS getstripe -p $DIR)
6587         local pool_list=()
6588         local pool=""
6589
6590         echo -n "Creating test dir..."
6591         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6592         echo "done."
6593
6594         echo -n "Creating test file..."
6595         touch $file1 || error "cannot create file"
6596         echo "done."
6597
6598         echo -n "Detecting existing pools..."
6599         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6600
6601         if [ ${#pool_list[@]} -gt 0 ]; then
6602                 echo "${pool_list[@]}"
6603                 for thispool in "${pool_list[@]}"; do
6604                         if [[ -z "$initial_pool" ||
6605                               "$initial_pool" != "$thispool" ]]; then
6606                                 pool="$thispool"
6607                                 echo "Using existing pool '$pool'"
6608                                 break
6609                         fi
6610                 done
6611         else
6612                 echo "none detected."
6613         fi
6614         if [ -z "$pool" ]; then
6615                 pool=${POOL:-testpool}
6616                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6617                 echo -n "Creating pool '$pool'..."
6618                 create_pool=true
6619                 pool_add $pool &> /dev/null ||
6620                         error "pool_add failed"
6621                 echo "done."
6622
6623                 echo -n "Adding target to pool..."
6624                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6625                         error "pool_add_targets failed"
6626                 echo "done."
6627         fi
6628
6629         echo -n "Setting pool using -p option..."
6630         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6631                 error "migrate failed rc = $?"
6632         echo "done."
6633
6634         echo -n "Verifying test file is in pool after migrating..."
6635         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6636                 error "file was not migrated to pool $pool"
6637         echo "done."
6638
6639         echo -n "Removing test file from pool '$pool'..."
6640         # "lfs migrate $file" won't remove the file from the pool
6641         # until some striping information is changed.
6642         $LFS migrate -c 1 $file1 &> /dev/null ||
6643                 error "cannot remove from pool"
6644         [ "$($LFS getstripe -p $file1)" ] &&
6645                 error "pool still set"
6646         echo "done."
6647
6648         echo -n "Setting pool using --pool option..."
6649         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6650                 error "migrate failed rc = $?"
6651         echo "done."
6652
6653         # Clean up
6654         rm -f $file1
6655         if $create_pool; then
6656                 destroy_test_pools 2> /dev/null ||
6657                         error "destroy test pools failed"
6658         fi
6659 }
6660 run_test 56wb "check lfs_migrate pool support"
6661
6662 test_56wc() {
6663         local file1="$DIR/$tdir/file1"
6664         local parent_ssize
6665         local parent_scount
6666         local cur_ssize
6667         local cur_scount
6668         local orig_ssize
6669
6670         echo -n "Creating test dir..."
6671         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6672         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6673                 error "cannot set stripe by '-S 1M -c 1'"
6674         echo "done"
6675
6676         echo -n "Setting initial stripe for test file..."
6677         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6678                 error "cannot set stripe"
6679         cur_ssize=$($LFS getstripe -S "$file1")
6680         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6681         echo "done."
6682
6683         # File currently set to -S 512K -c 1
6684
6685         # Ensure -c and -S options are rejected when -R is set
6686         echo -n "Verifying incompatible options are detected..."
6687         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6688                 error "incompatible -c and -R options not detected"
6689         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6690                 error "incompatible -S and -R options not detected"
6691         echo "done."
6692
6693         # Ensure unrecognized options are passed through to 'lfs migrate'
6694         echo -n "Verifying -S option is passed through to lfs migrate..."
6695         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6696                 error "migration failed"
6697         cur_ssize=$($LFS getstripe -S "$file1")
6698         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6699         echo "done."
6700
6701         # File currently set to -S 1M -c 1
6702
6703         # Ensure long options are supported
6704         echo -n "Verifying long options supported..."
6705         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6706                 error "long option without argument not supported"
6707         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6708                 error "long option with argument not supported"
6709         cur_ssize=$($LFS getstripe -S "$file1")
6710         [ $cur_ssize -eq 524288 ] ||
6711                 error "migrate --stripe-size $cur_ssize != 524288"
6712         echo "done."
6713
6714         # File currently set to -S 512K -c 1
6715
6716         if [ "$OSTCOUNT" -gt 1 ]; then
6717                 echo -n "Verifying explicit stripe count can be set..."
6718                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6719                         error "migrate failed"
6720                 cur_scount=$($LFS getstripe -c "$file1")
6721                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6722                 echo "done."
6723         fi
6724
6725         # File currently set to -S 512K -c 1 or -S 512K -c 2
6726
6727         # Ensure parent striping is used if -R is set, and no stripe
6728         # count or size is specified
6729         echo -n "Setting stripe for parent directory..."
6730         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6731                 error "cannot set stripe '-S 2M -c 1'"
6732         echo "done."
6733
6734         echo -n "Verifying restripe option uses parent stripe settings..."
6735         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6736         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6737         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6738                 error "migrate failed"
6739         cur_ssize=$($LFS getstripe -S "$file1")
6740         [ $cur_ssize -eq $parent_ssize ] ||
6741                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6742         cur_scount=$($LFS getstripe -c "$file1")
6743         [ $cur_scount -eq $parent_scount ] ||
6744                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6745         echo "done."
6746
6747         # File currently set to -S 1M -c 1
6748
6749         # Ensure striping is preserved if -R is not set, and no stripe
6750         # count or size is specified
6751         echo -n "Verifying striping size preserved when not specified..."
6752         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6753         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6754                 error "cannot set stripe on parent directory"
6755         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6756                 error "migrate failed"
6757         cur_ssize=$($LFS getstripe -S "$file1")
6758         [ $cur_ssize -eq $orig_ssize ] ||
6759                 error "migrate by default $cur_ssize != $orig_ssize"
6760         echo "done."
6761
6762         # Ensure file name properly detected when final option has no argument
6763         echo -n "Verifying file name properly detected..."
6764         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6765                 error "file name interpreted as option argument"
6766         echo "done."
6767
6768         # Clean up
6769         rm -f "$file1"
6770 }
6771 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6772
6773 test_56wd() {
6774         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6775
6776         local file1=$DIR/$tdir/file1
6777
6778         echo -n "Creating test dir..."
6779         test_mkdir $DIR/$tdir || error "cannot create dir"
6780         echo "done."
6781
6782         echo -n "Creating test file..."
6783         touch $file1
6784         echo "done."
6785
6786         # Ensure 'lfs migrate' will fail by using a non-existent option,
6787         # and make sure rsync is not called to recover
6788         echo -n "Make sure --no-rsync option works..."
6789         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6790                 grep -q 'refusing to fall back to rsync' ||
6791                 error "rsync was called with --no-rsync set"
6792         echo "done."
6793
6794         # Ensure rsync is called without trying 'lfs migrate' first
6795         echo -n "Make sure --rsync option works..."
6796         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6797                 grep -q 'falling back to rsync' &&
6798                 error "lfs migrate was called with --rsync set"
6799         echo "done."
6800
6801         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6802         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6803                 grep -q 'at the same time' ||
6804                 error "--rsync and --no-rsync accepted concurrently"
6805         echo "done."
6806
6807         # Clean up
6808         rm -f $file1
6809 }
6810 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6811
6812 test_56we() {
6813         local td=$DIR/$tdir
6814         local tf=$td/$tfile
6815
6816         test_mkdir $td || error "cannot create $td"
6817         touch $tf || error "cannot touch $tf"
6818
6819         echo -n "Make sure --non-direct|-D works..."
6820         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6821                 grep -q "lfs migrate --non-direct" ||
6822                 error "--non-direct option cannot work correctly"
6823         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6824                 grep -q "lfs migrate -D" ||
6825                 error "-D option cannot work correctly"
6826         echo "done."
6827 }
6828 run_test 56we "check lfs_migrate --non-direct|-D support"
6829
6830 test_56x() {
6831         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6832         check_swap_layouts_support
6833
6834         local dir=$DIR/$tdir
6835         local ref1=/etc/passwd
6836         local file1=$dir/file1
6837
6838         test_mkdir $dir || error "creating dir $dir"
6839         $LFS setstripe -c 2 $file1
6840         cp $ref1 $file1
6841         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6842         stripe=$($LFS getstripe -c $file1)
6843         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6844         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6845
6846         # clean up
6847         rm -f $file1
6848 }
6849 run_test 56x "lfs migration support"
6850
6851 test_56xa() {
6852         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6853         check_swap_layouts_support
6854
6855         local dir=$DIR/$tdir/$testnum
6856
6857         test_mkdir -p $dir
6858
6859         local ref1=/etc/passwd
6860         local file1=$dir/file1
6861
6862         $LFS setstripe -c 2 $file1
6863         cp $ref1 $file1
6864         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6865
6866         local stripe=$($LFS getstripe -c $file1)
6867
6868         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6869         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6870
6871         # clean up
6872         rm -f $file1
6873 }
6874 run_test 56xa "lfs migration --block support"
6875
6876 check_migrate_links() {
6877         local dir="$1"
6878         local file1="$dir/file1"
6879         local begin="$2"
6880         local count="$3"
6881         local runas="$4"
6882         local total_count=$(($begin + $count - 1))
6883         local symlink_count=10
6884         local uniq_count=10
6885
6886         if [ ! -f "$file1" ]; then
6887                 echo -n "creating initial file..."
6888                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6889                         error "cannot setstripe initial file"
6890                 echo "done"
6891
6892                 echo -n "creating symlinks..."
6893                 for s in $(seq 1 $symlink_count); do
6894                         ln -s "$file1" "$dir/slink$s" ||
6895                                 error "cannot create symlinks"
6896                 done
6897                 echo "done"
6898
6899                 echo -n "creating nonlinked files..."
6900                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6901                         error "cannot create nonlinked files"
6902                 echo "done"
6903         fi
6904
6905         # create hard links
6906         if [ ! -f "$dir/file$total_count" ]; then
6907                 echo -n "creating hard links $begin:$total_count..."
6908                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6909                         /dev/null || error "cannot create hard links"
6910                 echo "done"
6911         fi
6912
6913         echo -n "checking number of hard links listed in xattrs..."
6914         local fid=$($LFS getstripe -F "$file1")
6915         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6916
6917         echo "${#paths[*]}"
6918         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6919                         skip "hard link list has unexpected size, skipping test"
6920         fi
6921         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6922                         error "link names should exceed xattrs size"
6923         fi
6924
6925         echo -n "migrating files..."
6926         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6927         local rc=$?
6928         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6929         echo "done"
6930
6931         # make sure all links have been properly migrated
6932         echo -n "verifying files..."
6933         fid=$($LFS getstripe -F "$file1") ||
6934                 error "cannot get fid for file $file1"
6935         for i in $(seq 2 $total_count); do
6936                 local fid2=$($LFS getstripe -F $dir/file$i)
6937
6938                 [ "$fid2" == "$fid" ] ||
6939                         error "migrated hard link has mismatched FID"
6940         done
6941
6942         # make sure hard links were properly detected, and migration was
6943         # performed only once for the entire link set; nonlinked files should
6944         # also be migrated
6945         local actual=$(grep -c 'done' <<< "$migrate_out")
6946         local expected=$(($uniq_count + 1))
6947
6948         [ "$actual" -eq  "$expected" ] ||
6949                 error "hard links individually migrated ($actual != $expected)"
6950
6951         # make sure the correct number of hard links are present
6952         local hardlinks=$(stat -c '%h' "$file1")
6953
6954         [ $hardlinks -eq $total_count ] ||
6955                 error "num hard links $hardlinks != $total_count"
6956         echo "done"
6957
6958         return 0
6959 }
6960
6961 test_56xb() {
6962         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6963                 skip "Need MDS version at least 2.10.55"
6964
6965         local dir="$DIR/$tdir"
6966
6967         test_mkdir "$dir" || error "cannot create dir $dir"
6968
6969         echo "testing lfs migrate mode when all links fit within xattrs"
6970         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6971
6972         echo "testing rsync mode when all links fit within xattrs"
6973         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6974
6975         echo "testing lfs migrate mode when all links do not fit within xattrs"
6976         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6977
6978         echo "testing rsync mode when all links do not fit within xattrs"
6979         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6980
6981         chown -R $RUNAS_ID $dir
6982         echo "testing non-root lfs migrate mode when not all links are in xattr"
6983         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
6984
6985         # clean up
6986         rm -rf $dir
6987 }
6988 run_test 56xb "lfs migration hard link support"
6989
6990 test_56xc() {
6991         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6992
6993         local dir="$DIR/$tdir"
6994
6995         test_mkdir "$dir" || error "cannot create dir $dir"
6996
6997         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6998         echo -n "Setting initial stripe for 20MB test file..."
6999         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7000                 error "cannot setstripe 20MB file"
7001         echo "done"
7002         echo -n "Sizing 20MB test file..."
7003         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7004         echo "done"
7005         echo -n "Verifying small file autostripe count is 1..."
7006         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7007                 error "cannot migrate 20MB file"
7008         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7009                 error "cannot get stripe for $dir/20mb"
7010         [ $stripe_count -eq 1 ] ||
7011                 error "unexpected stripe count $stripe_count for 20MB file"
7012         rm -f "$dir/20mb"
7013         echo "done"
7014
7015         # Test 2: File is small enough to fit within the available space on
7016         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7017         # have at least an additional 1KB for each desired stripe for test 3
7018         echo -n "Setting stripe for 1GB test file..."
7019         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7020         echo "done"
7021         echo -n "Sizing 1GB test file..."
7022         # File size is 1GB + 3KB
7023         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7024         echo "done"
7025
7026         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7027         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7028         if (( avail > 524288 * OSTCOUNT )); then
7029                 echo -n "Migrating 1GB file..."
7030                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7031                         error "cannot migrate 1GB file"
7032                 echo "done"
7033                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7034                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7035                         error "cannot getstripe for 1GB file"
7036                 [ $stripe_count -eq 2 ] ||
7037                         error "unexpected stripe count $stripe_count != 2"
7038                 echo "done"
7039         fi
7040
7041         # Test 3: File is too large to fit within the available space on
7042         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7043         if [ $OSTCOUNT -ge 3 ]; then
7044                 # The required available space is calculated as
7045                 # file size (1GB + 3KB) / OST count (3).
7046                 local kb_per_ost=349526
7047
7048                 echo -n "Migrating 1GB file with limit..."
7049                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7050                         error "cannot migrate 1GB file with limit"
7051                 echo "done"
7052
7053                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7054                 echo -n "Verifying 1GB autostripe count with limited space..."
7055                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7056                         error "unexpected stripe count $stripe_count (min 3)"
7057                 echo "done"
7058         fi
7059
7060         # clean up
7061         rm -rf $dir
7062 }
7063 run_test 56xc "lfs migration autostripe"
7064
7065 test_56xd() {
7066         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7067
7068         local dir=$DIR/$tdir
7069         local f_mgrt=$dir/$tfile.mgrt
7070         local f_yaml=$dir/$tfile.yaml
7071         local f_copy=$dir/$tfile.copy
7072         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7073         local layout_copy="-c 2 -S 2M -i 1"
7074         local yamlfile=$dir/yamlfile
7075         local layout_before;
7076         local layout_after;
7077
7078         test_mkdir "$dir" || error "cannot create dir $dir"
7079         $LFS setstripe $layout_yaml $f_yaml ||
7080                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7081         $LFS getstripe --yaml $f_yaml > $yamlfile
7082         $LFS setstripe $layout_copy $f_copy ||
7083                 error "cannot setstripe $f_copy with layout $layout_copy"
7084         touch $f_mgrt
7085         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7086
7087         # 1. test option --yaml
7088         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7089                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7090         layout_before=$(get_layout_param $f_yaml)
7091         layout_after=$(get_layout_param $f_mgrt)
7092         [ "$layout_after" == "$layout_before" ] ||
7093                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7094
7095         # 2. test option --copy
7096         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7097                 error "cannot migrate $f_mgrt with --copy $f_copy"
7098         layout_before=$(get_layout_param $f_copy)
7099         layout_after=$(get_layout_param $f_mgrt)
7100         [ "$layout_after" == "$layout_before" ] ||
7101                 error "lfs_migrate --copy: $layout_after != $layout_before"
7102 }
7103 run_test 56xd "check lfs_migrate --yaml and --copy support"
7104
7105 test_56xe() {
7106         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7107
7108         local dir=$DIR/$tdir
7109         local f_comp=$dir/$tfile
7110         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7111         local layout_before=""
7112         local layout_after=""
7113
7114         test_mkdir "$dir" || error "cannot create dir $dir"
7115         $LFS setstripe $layout $f_comp ||
7116                 error "cannot setstripe $f_comp with layout $layout"
7117         layout_before=$(get_layout_param $f_comp)
7118         dd if=/dev/zero of=$f_comp bs=1M count=4
7119
7120         # 1. migrate a comp layout file by lfs_migrate
7121         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7122         layout_after=$(get_layout_param $f_comp)
7123         [ "$layout_before" == "$layout_after" ] ||
7124                 error "lfs_migrate: $layout_before != $layout_after"
7125
7126         # 2. migrate a comp layout file by lfs migrate
7127         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7128         layout_after=$(get_layout_param $f_comp)
7129         [ "$layout_before" == "$layout_after" ] ||
7130                 error "lfs migrate: $layout_before != $layout_after"
7131 }
7132 run_test 56xe "migrate a composite layout file"
7133
7134 test_56xf() {
7135         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7136
7137         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7138                 skip "Need server version at least 2.13.53"
7139
7140         local dir=$DIR/$tdir
7141         local f_comp=$dir/$tfile
7142         local layout="-E 1M -c1 -E -1 -c2"
7143         local fid_before=""
7144         local fid_after=""
7145
7146         test_mkdir "$dir" || error "cannot create dir $dir"
7147         $LFS setstripe $layout $f_comp ||
7148                 error "cannot setstripe $f_comp with layout $layout"
7149         fid_before=$($LFS getstripe --fid $f_comp)
7150         dd if=/dev/zero of=$f_comp bs=1M count=4
7151
7152         # 1. migrate a comp layout file to a comp layout
7153         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7154         fid_after=$($LFS getstripe --fid $f_comp)
7155         [ "$fid_before" == "$fid_after" ] ||
7156                 error "comp-to-comp migrate: $fid_before != $fid_after"
7157
7158         # 2. migrate a comp layout file to a plain layout
7159         $LFS migrate -c2 $f_comp ||
7160                 error "cannot migrate $f_comp by lfs migrate"
7161         fid_after=$($LFS getstripe --fid $f_comp)
7162         [ "$fid_before" == "$fid_after" ] ||
7163                 error "comp-to-plain migrate: $fid_before != $fid_after"
7164
7165         # 3. migrate a plain layout file to a comp layout
7166         $LFS migrate $layout $f_comp ||
7167                 error "cannot migrate $f_comp by lfs migrate"
7168         fid_after=$($LFS getstripe --fid $f_comp)
7169         [ "$fid_before" == "$fid_after" ] ||
7170                 error "plain-to-comp migrate: $fid_before != $fid_after"
7171 }
7172 run_test 56xf "FID is not lost during migration of a composite layout file"
7173
7174 test_56y() {
7175         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7176                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7177
7178         local res=""
7179         local dir=$DIR/$tdir
7180         local f1=$dir/file1
7181         local f2=$dir/file2
7182
7183         test_mkdir -p $dir || error "creating dir $dir"
7184         touch $f1 || error "creating std file $f1"
7185         $MULTIOP $f2 H2c || error "creating released file $f2"
7186
7187         # a directory can be raid0, so ask only for files
7188         res=$($LFS find $dir -L raid0 -type f | wc -l)
7189         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7190
7191         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7192         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7193
7194         # only files can be released, so no need to force file search
7195         res=$($LFS find $dir -L released)
7196         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7197
7198         res=$($LFS find $dir -type f \! -L released)
7199         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7200 }
7201 run_test 56y "lfs find -L raid0|released"
7202
7203 test_56z() { # LU-4824
7204         # This checks to make sure 'lfs find' continues after errors
7205         # There are two classes of errors that should be caught:
7206         # - If multiple paths are provided, all should be searched even if one
7207         #   errors out
7208         # - If errors are encountered during the search, it should not terminate
7209         #   early
7210         local dir=$DIR/$tdir
7211         local i
7212
7213         test_mkdir $dir
7214         for i in d{0..9}; do
7215                 test_mkdir $dir/$i
7216                 touch $dir/$i/$tfile
7217         done
7218         $LFS find $DIR/non_existent_dir $dir &&
7219                 error "$LFS find did not return an error"
7220         # Make a directory unsearchable. This should NOT be the last entry in
7221         # directory order.  Arbitrarily pick the 6th entry
7222         chmod 700 $($LFS find $dir -type d | sed '6!d')
7223
7224         $RUNAS $LFS find $DIR/non_existent $dir
7225         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7226
7227         # The user should be able to see 10 directories and 9 files
7228         (( count == 19 )) ||
7229                 error "$LFS find found $count != 19 entries after error"
7230 }
7231 run_test 56z "lfs find should continue after an error"
7232
7233 test_56aa() { # LU-5937
7234         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7235
7236         local dir=$DIR/$tdir
7237
7238         mkdir $dir
7239         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7240
7241         createmany -o $dir/striped_dir/${tfile}- 1024
7242         local dirs=$($LFS find --size +8k $dir/)
7243
7244         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7245 }
7246 run_test 56aa "lfs find --size under striped dir"
7247
7248 test_56ab() { # LU-10705
7249         test_mkdir $DIR/$tdir
7250         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7251         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7252         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7253         # Flush writes to ensure valid blocks.  Need to be more thorough for
7254         # ZFS, since blocks are not allocated/returned to client immediately.
7255         sync_all_data
7256         wait_zfs_commit ost1 2
7257         cancel_lru_locks osc
7258         ls -ls $DIR/$tdir
7259
7260         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7261
7262         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7263
7264         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7265         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7266
7267         rm -f $DIR/$tdir/$tfile.[123]
7268 }
7269 run_test 56ab "lfs find --blocks"
7270
7271 test_56ba() {
7272         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7273                 skip "Need MDS version at least 2.10.50"
7274
7275         # Create composite files with one component
7276         local dir=$DIR/$tdir
7277
7278         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7279         # Create composite files with three components
7280         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7281         # Create non-composite files
7282         createmany -o $dir/${tfile}- 10
7283
7284         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7285
7286         [[ $nfiles == 10 ]] ||
7287                 error "lfs find -E 1M found $nfiles != 10 files"
7288
7289         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7290         [[ $nfiles == 25 ]] ||
7291                 error "lfs find ! -E 1M found $nfiles != 25 files"
7292
7293         # All files have a component that starts at 0
7294         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7295         [[ $nfiles == 35 ]] ||
7296                 error "lfs find --component-start 0 - $nfiles != 35 files"
7297
7298         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7299         [[ $nfiles == 15 ]] ||
7300                 error "lfs find --component-start 2M - $nfiles != 15 files"
7301
7302         # All files created here have a componenet that does not starts at 2M
7303         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7304         [[ $nfiles == 35 ]] ||
7305                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7306
7307         # Find files with a specified number of components
7308         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7309         [[ $nfiles == 15 ]] ||
7310                 error "lfs find --component-count 3 - $nfiles != 15 files"
7311
7312         # Remember non-composite files have a component count of zero
7313         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7314         [[ $nfiles == 10 ]] ||
7315                 error "lfs find --component-count 0 - $nfiles != 10 files"
7316
7317         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7318         [[ $nfiles == 20 ]] ||
7319                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7320
7321         # All files have a flag called "init"
7322         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7323         [[ $nfiles == 35 ]] ||
7324                 error "lfs find --component-flags init - $nfiles != 35 files"
7325
7326         # Multi-component files will have a component not initialized
7327         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7328         [[ $nfiles == 15 ]] ||
7329                 error "lfs find !--component-flags init - $nfiles != 15 files"
7330
7331         rm -rf $dir
7332
7333 }
7334 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7335
7336 test_56ca() {
7337         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7338                 skip "Need MDS version at least 2.10.57"
7339
7340         local td=$DIR/$tdir
7341         local tf=$td/$tfile
7342         local dir
7343         local nfiles
7344         local cmd
7345         local i
7346         local j
7347
7348         # create mirrored directories and mirrored files
7349         mkdir $td || error "mkdir $td failed"
7350         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7351         createmany -o $tf- 10 || error "create $tf- failed"
7352
7353         for i in $(seq 2); do
7354                 dir=$td/dir$i
7355                 mkdir $dir || error "mkdir $dir failed"
7356                 $LFS mirror create -N$((3 + i)) $dir ||
7357                         error "create mirrored dir $dir failed"
7358                 createmany -o $dir/$tfile- 10 ||
7359                         error "create $dir/$tfile- failed"
7360         done
7361
7362         # change the states of some mirrored files
7363         echo foo > $tf-6
7364         for i in $(seq 2); do
7365                 dir=$td/dir$i
7366                 for j in $(seq 4 9); do
7367                         echo foo > $dir/$tfile-$j
7368                 done
7369         done
7370
7371         # find mirrored files with specific mirror count
7372         cmd="$LFS find --mirror-count 3 --type f $td"
7373         nfiles=$($cmd | wc -l)
7374         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7375
7376         cmd="$LFS find ! --mirror-count 3 --type f $td"
7377         nfiles=$($cmd | wc -l)
7378         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7379
7380         cmd="$LFS find --mirror-count +2 --type f $td"
7381         nfiles=$($cmd | wc -l)
7382         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7383
7384         cmd="$LFS find --mirror-count -6 --type f $td"
7385         nfiles=$($cmd | wc -l)
7386         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7387
7388         # find mirrored files with specific file state
7389         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7390         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7391
7392         cmd="$LFS find --mirror-state=ro --type f $td"
7393         nfiles=$($cmd | wc -l)
7394         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7395
7396         cmd="$LFS find ! --mirror-state=ro --type f $td"
7397         nfiles=$($cmd | wc -l)
7398         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7399
7400         cmd="$LFS find --mirror-state=wp --type f $td"
7401         nfiles=$($cmd | wc -l)
7402         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7403
7404         cmd="$LFS find ! --mirror-state=sp --type f $td"
7405         nfiles=$($cmd | wc -l)
7406         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7407 }
7408 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7409
7410 test_57a() {
7411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7412         # note test will not do anything if MDS is not local
7413         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7414                 skip_env "ldiskfs only test"
7415         fi
7416         remote_mds_nodsh && skip "remote MDS with nodsh"
7417
7418         local MNTDEV="osd*.*MDT*.mntdev"
7419         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7420         [ -z "$DEV" ] && error "can't access $MNTDEV"
7421         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7422                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7423                         error "can't access $DEV"
7424                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7425                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7426                 rm $TMP/t57a.dump
7427         done
7428 }
7429 run_test 57a "verify MDS filesystem created with large inodes =="
7430
7431 test_57b() {
7432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7433         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7434                 skip_env "ldiskfs only test"
7435         fi
7436         remote_mds_nodsh && skip "remote MDS with nodsh"
7437
7438         local dir=$DIR/$tdir
7439         local filecount=100
7440         local file1=$dir/f1
7441         local fileN=$dir/f$filecount
7442
7443         rm -rf $dir || error "removing $dir"
7444         test_mkdir -c1 $dir
7445         local mdtidx=$($LFS getstripe -m $dir)
7446         local mdtname=MDT$(printf %04x $mdtidx)
7447         local facet=mds$((mdtidx + 1))
7448
7449         echo "mcreating $filecount files"
7450         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7451
7452         # verify that files do not have EAs yet
7453         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7454                 error "$file1 has an EA"
7455         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7456                 error "$fileN has an EA"
7457
7458         sync
7459         sleep 1
7460         df $dir  #make sure we get new statfs data
7461         local mdsfree=$(do_facet $facet \
7462                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7463         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7464         local file
7465
7466         echo "opening files to create objects/EAs"
7467         for file in $(seq -f $dir/f%g 1 $filecount); do
7468                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7469                         error "opening $file"
7470         done
7471
7472         # verify that files have EAs now
7473         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7474         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7475
7476         sleep 1  #make sure we get new statfs data
7477         df $dir
7478         local mdsfree2=$(do_facet $facet \
7479                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7480         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7481
7482         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7483                 if [ "$mdsfree" != "$mdsfree2" ]; then
7484                         error "MDC before $mdcfree != after $mdcfree2"
7485                 else
7486                         echo "MDC before $mdcfree != after $mdcfree2"
7487                         echo "unable to confirm if MDS has large inodes"
7488                 fi
7489         fi
7490         rm -rf $dir
7491 }
7492 run_test 57b "default LOV EAs are stored inside large inodes ==="
7493
7494 test_58() {
7495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7496         [ -z "$(which wiretest 2>/dev/null)" ] &&
7497                         skip_env "could not find wiretest"
7498
7499         wiretest
7500 }
7501 run_test 58 "verify cross-platform wire constants =============="
7502
7503 test_59() {
7504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7505
7506         echo "touch 130 files"
7507         createmany -o $DIR/f59- 130
7508         echo "rm 130 files"
7509         unlinkmany $DIR/f59- 130
7510         sync
7511         # wait for commitment of removal
7512         wait_delete_completed
7513 }
7514 run_test 59 "verify cancellation of llog records async ========="
7515
7516 TEST60_HEAD="test_60 run $RANDOM"
7517 test_60a() {
7518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7519         remote_mgs_nodsh && skip "remote MGS with nodsh"
7520         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7521                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7522                         skip_env "missing subtest run-llog.sh"
7523
7524         log "$TEST60_HEAD - from kernel mode"
7525         do_facet mgs "$LCTL dk > /dev/null"
7526         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7527         do_facet mgs $LCTL dk > $TMP/$tfile
7528
7529         # LU-6388: test llog_reader
7530         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7531         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7532         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7533                         skip_env "missing llog_reader"
7534         local fstype=$(facet_fstype mgs)
7535         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7536                 skip_env "Only for ldiskfs or zfs type mgs"
7537
7538         local mntpt=$(facet_mntpt mgs)
7539         local mgsdev=$(mgsdevname 1)
7540         local fid_list
7541         local fid
7542         local rec_list
7543         local rec
7544         local rec_type
7545         local obj_file
7546         local path
7547         local seq
7548         local oid
7549         local pass=true
7550
7551         #get fid and record list
7552         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7553                 tail -n 4))
7554         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7555                 tail -n 4))
7556         #remount mgs as ldiskfs or zfs type
7557         stop mgs || error "stop mgs failed"
7558         mount_fstype mgs || error "remount mgs failed"
7559         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7560                 fid=${fid_list[i]}
7561                 rec=${rec_list[i]}
7562                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7563                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7564                 oid=$((16#$oid))
7565
7566                 case $fstype in
7567                         ldiskfs )
7568                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7569                         zfs )
7570                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7571                 esac
7572                 echo "obj_file is $obj_file"
7573                 do_facet mgs $llog_reader $obj_file
7574
7575                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7576                         awk '{ print $3 }' | sed -e "s/^type=//g")
7577                 if [ $rec_type != $rec ]; then
7578                         echo "FAILED test_60a wrong record type $rec_type," \
7579                               "should be $rec"
7580                         pass=false
7581                         break
7582                 fi
7583
7584                 #check obj path if record type is LLOG_LOGID_MAGIC
7585                 if [ "$rec" == "1064553b" ]; then
7586                         path=$(do_facet mgs $llog_reader $obj_file |
7587                                 grep "path=" | awk '{ print $NF }' |
7588                                 sed -e "s/^path=//g")
7589                         if [ $obj_file != $mntpt/$path ]; then
7590                                 echo "FAILED test_60a wrong obj path" \
7591                                       "$montpt/$path, should be $obj_file"
7592                                 pass=false
7593                                 break
7594                         fi
7595                 fi
7596         done
7597         rm -f $TMP/$tfile
7598         #restart mgs before "error", otherwise it will block the next test
7599         stop mgs || error "stop mgs failed"
7600         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7601         $pass || error "test failed, see FAILED test_60a messages for specifics"
7602 }
7603 run_test 60a "llog_test run from kernel module and test llog_reader"
7604
7605 test_60b() { # bug 6411
7606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7607
7608         dmesg > $DIR/$tfile
7609         LLOG_COUNT=$(do_facet mgs dmesg |
7610                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7611                           /llog_[a-z]*.c:[0-9]/ {
7612                                 if (marker)
7613                                         from_marker++
7614                                 from_begin++
7615                           }
7616                           END {
7617                                 if (marker)
7618                                         print from_marker
7619                                 else
7620                                         print from_begin
7621                           }")
7622
7623         [[ $LLOG_COUNT -gt 120 ]] &&
7624                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7625 }
7626 run_test 60b "limit repeated messages from CERROR/CWARN"
7627
7628 test_60c() {
7629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7630
7631         echo "create 5000 files"
7632         createmany -o $DIR/f60c- 5000
7633 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7634         lctl set_param fail_loc=0x80000137
7635         unlinkmany $DIR/f60c- 5000
7636         lctl set_param fail_loc=0
7637 }
7638 run_test 60c "unlink file when mds full"
7639
7640 test_60d() {
7641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7642
7643         SAVEPRINTK=$(lctl get_param -n printk)
7644         # verify "lctl mark" is even working"
7645         MESSAGE="test message ID $RANDOM $$"
7646         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7647         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7648
7649         lctl set_param printk=0 || error "set lnet.printk failed"
7650         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7651         MESSAGE="new test message ID $RANDOM $$"
7652         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7653         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7654         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7655
7656         lctl set_param -n printk="$SAVEPRINTK"
7657 }
7658 run_test 60d "test printk console message masking"
7659
7660 test_60e() {
7661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7662         remote_mds_nodsh && skip "remote MDS with nodsh"
7663
7664         touch $DIR/$tfile
7665 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7666         do_facet mds1 lctl set_param fail_loc=0x15b
7667         rm $DIR/$tfile
7668 }
7669 run_test 60e "no space while new llog is being created"
7670
7671 test_60g() {
7672         local pid
7673         local i
7674
7675         test_mkdir -c $MDSCOUNT $DIR/$tdir
7676
7677         (
7678                 local index=0
7679                 while true; do
7680                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7681                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7682                                 2>/dev/null
7683                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7684                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7685                         index=$((index + 1))
7686                 done
7687         ) &
7688
7689         pid=$!
7690
7691         for i in {0..100}; do
7692                 # define OBD_FAIL_OSD_TXN_START    0x19a
7693                 local index=$((i % MDSCOUNT + 1))
7694
7695                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7696                         > /dev/null
7697                 usleep 100
7698         done
7699
7700         kill -9 $pid
7701
7702         for i in $(seq $MDSCOUNT); do
7703                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7704         done
7705
7706         mkdir $DIR/$tdir/new || error "mkdir failed"
7707         rmdir $DIR/$tdir/new || error "rmdir failed"
7708
7709         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7710                 -t namespace
7711         for i in $(seq $MDSCOUNT); do
7712                 wait_update_facet mds$i "$LCTL get_param -n \
7713                         mdd.$(facet_svc mds$i).lfsck_namespace |
7714                         awk '/^status/ { print \\\$2 }'" "completed"
7715         done
7716
7717         ls -R $DIR/$tdir || error "ls failed"
7718         rm -rf $DIR/$tdir || error "rmdir failed"
7719 }
7720 run_test 60g "transaction abort won't cause MDT hung"
7721
7722 test_60h() {
7723         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7724                 skip "Need MDS version at least 2.12.52"
7725         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7726
7727         local f
7728
7729         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7730         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7731         for fail_loc in 0x80000188 0x80000189; do
7732                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7733                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7734                         error "mkdir $dir-$fail_loc failed"
7735                 for i in {0..10}; do
7736                         # create may fail on missing stripe
7737                         echo $i > $DIR/$tdir-$fail_loc/$i
7738                 done
7739                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7740                         error "getdirstripe $tdir-$fail_loc failed"
7741                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7742                         error "migrate $tdir-$fail_loc failed"
7743                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7744                         error "getdirstripe $tdir-$fail_loc failed"
7745                 pushd $DIR/$tdir-$fail_loc
7746                 for f in *; do
7747                         echo $f | cmp $f - || error "$f data mismatch"
7748                 done
7749                 popd
7750                 rm -rf $DIR/$tdir-$fail_loc
7751         done
7752 }
7753 run_test 60h "striped directory with missing stripes can be accessed"
7754
7755 test_61a() {
7756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7757
7758         f="$DIR/f61"
7759         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7760         cancel_lru_locks osc
7761         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7762         sync
7763 }
7764 run_test 61a "mmap() writes don't make sync hang ================"
7765
7766 test_61b() {
7767         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7768 }
7769 run_test 61b "mmap() of unstriped file is successful"
7770
7771 # bug 2330 - insufficient obd_match error checking causes LBUG
7772 test_62() {
7773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7774
7775         f="$DIR/f62"
7776         echo foo > $f
7777         cancel_lru_locks osc
7778         lctl set_param fail_loc=0x405
7779         cat $f && error "cat succeeded, expect -EIO"
7780         lctl set_param fail_loc=0
7781 }
7782 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7783 # match every page all of the time.
7784 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7785
7786 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7787 # Though this test is irrelevant anymore, it helped to reveal some
7788 # other grant bugs (LU-4482), let's keep it.
7789 test_63a() {   # was test_63
7790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7791
7792         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7793
7794         for i in `seq 10` ; do
7795                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7796                 sleep 5
7797                 kill $!
7798                 sleep 1
7799         done
7800
7801         rm -f $DIR/f63 || true
7802 }
7803 run_test 63a "Verify oig_wait interruption does not crash ======="
7804
7805 # bug 2248 - async write errors didn't return to application on sync
7806 # bug 3677 - async write errors left page locked
7807 test_63b() {
7808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7809
7810         debugsave
7811         lctl set_param debug=-1
7812
7813         # ensure we have a grant to do async writes
7814         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7815         rm $DIR/$tfile
7816
7817         sync    # sync lest earlier test intercept the fail_loc
7818
7819         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7820         lctl set_param fail_loc=0x80000406
7821         $MULTIOP $DIR/$tfile Owy && \
7822                 error "sync didn't return ENOMEM"
7823         sync; sleep 2; sync     # do a real sync this time to flush page
7824         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7825                 error "locked page left in cache after async error" || true
7826         debugrestore
7827 }
7828 run_test 63b "async write errors should be returned to fsync ==="
7829
7830 test_64a () {
7831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7832
7833         lfs df $DIR
7834         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7835 }
7836 run_test 64a "verify filter grant calculations (in kernel) ====="
7837
7838 test_64b () {
7839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7840
7841         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7842 }
7843 run_test 64b "check out-of-space detection on client"
7844
7845 test_64c() {
7846         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7847 }
7848 run_test 64c "verify grant shrink"
7849
7850 import_param() {
7851         local tgt=$1
7852         local param=$2
7853
7854         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7855 }
7856
7857 # this does exactly what osc_request.c:osc_announce_cached() does in
7858 # order to calculate max amount of grants to ask from server
7859 want_grant() {
7860         local tgt=$1
7861
7862         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7863         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7864
7865         ((rpc_in_flight++));
7866         nrpages=$((nrpages * rpc_in_flight))
7867
7868         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7869
7870         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7871
7872         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7873         local undirty=$((nrpages * PAGE_SIZE))
7874
7875         local max_extent_pages
7876         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7877         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7878         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7879         local grant_extent_tax
7880         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7881
7882         undirty=$((undirty + nrextents * grant_extent_tax))
7883
7884         echo $undirty
7885 }
7886
7887 # this is size of unit for grant allocation. It should be equal to
7888 # what tgt_grant.c:tgt_grant_chunk() calculates
7889 grant_chunk() {
7890         local tgt=$1
7891         local max_brw_size
7892         local grant_extent_tax
7893
7894         max_brw_size=$(import_param $tgt max_brw_size)
7895
7896         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7897
7898         echo $(((max_brw_size + grant_extent_tax) * 2))
7899 }
7900
7901 test_64d() {
7902         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7903                 skip "OST < 2.10.55 doesn't limit grants enough"
7904
7905         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7906
7907         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7908                 skip "no grant_param connect flag"
7909
7910         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7911
7912         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7913         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7914
7915
7916         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7917         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7918
7919         $LFS setstripe $DIR/$tfile -i 0 -c 1
7920         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7921         ddpid=$!
7922
7923         while kill -0 $ddpid; do
7924                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7925
7926                 if [[ $cur_grant -gt $max_cur_granted ]]; then
7927                         kill $ddpid
7928                         error "cur_grant $cur_grant > $max_cur_granted"
7929                 fi
7930
7931                 sleep 1
7932         done
7933 }
7934 run_test 64d "check grant limit exceed"
7935
7936 check_grants() {
7937         local tgt=$1
7938         local expected=$2
7939         local msg=$3
7940         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7941
7942         ((cur_grants == expected)) ||
7943                 error "$msg: grants mismatch: $cur_grants, expected $expected"
7944 }
7945
7946 round_up_p2() {
7947         echo $((($1 + $2 - 1) & ~($2 - 1)))
7948 }
7949
7950 test_64e() {
7951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7952         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
7953                 skip "Need OSS version at least 2.11.56"
7954
7955         # Remount client to reset grant
7956         remount_client $MOUNT || error "failed to remount client"
7957         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
7958
7959         local init_grants=$(import_param $osc_tgt initial_grant)
7960
7961         check_grants $osc_tgt $init_grants "init grants"
7962
7963         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
7964         local max_brw_size=$(import_param $osc_tgt max_brw_size)
7965         local gbs=$(import_param $osc_tgt grant_block_size)
7966
7967         # write random number of bytes from max_brw_size / 4 to max_brw_size
7968         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
7969         # align for direct io
7970         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
7971         # round to grant consumption unit
7972         local wb_round_up=$(round_up_p2 $write_bytes gbs)
7973
7974         local grants=$((wb_round_up + extent_tax))
7975
7976         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
7977
7978         # define OBD_FAIL_TGT_NO_GRANT 0x725
7979         # make the server not grant more back
7980         do_facet ost1 $LCTL set_param fail_loc=0x725
7981         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
7982
7983         do_facet ost1 $LCTL set_param fail_loc=0
7984
7985         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
7986
7987         rm -f $DIR/$tfile || error "rm failed"
7988
7989         # Remount client to reset grant
7990         remount_client $MOUNT || error "failed to remount client"
7991         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
7992
7993         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
7994
7995         # define OBD_FAIL_TGT_NO_GRANT 0x725
7996         # make the server not grant more back
7997         do_facet ost1 $LCTL set_param fail_loc=0x725
7998         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
7999         do_facet ost1 $LCTL set_param fail_loc=0
8000
8001         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8002 }
8003 run_test 64e "check grant consumption (no grant allocation)"
8004
8005 test_64f() {
8006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8007
8008         # Remount client to reset grant
8009         remount_client $MOUNT || error "failed to remount client"
8010         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8011
8012         local init_grants=$(import_param $osc_tgt initial_grant)
8013         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8014         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8015         local gbs=$(import_param $osc_tgt grant_block_size)
8016         local chunk=$(grant_chunk $osc_tgt)
8017
8018         # write random number of bytes from max_brw_size / 4 to max_brw_size
8019         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8020         # align for direct io
8021         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8022         # round to grant consumption unit
8023         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8024
8025         local grants=$((wb_round_up + extent_tax))
8026
8027         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8028         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8029                 error "error writing to $DIR/$tfile"
8030
8031         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8032                 "direct io with grant allocation"
8033
8034         rm -f $DIR/$tfile || error "rm failed"
8035
8036         # Remount client to reset grant
8037         remount_client $MOUNT || error "failed to remount client"
8038         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8039
8040         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8041
8042         local cmd="oO_WRONLY:w${write_bytes}_yc"
8043
8044         $MULTIOP $DIR/$tfile $cmd &
8045         MULTIPID=$!
8046         sleep 1
8047
8048         check_grants $osc_tgt $((init_grants - grants)) \
8049                 "buffered io, not write rpc"
8050
8051         kill -USR1 $MULTIPID
8052         wait
8053
8054         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8055                 "buffered io, one RPC"
8056 }
8057 run_test 64f "check grant consumption (with grant allocation)"
8058
8059 # bug 1414 - set/get directories' stripe info
8060 test_65a() {
8061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8062
8063         test_mkdir $DIR/$tdir
8064         touch $DIR/$tdir/f1
8065         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8066 }
8067 run_test 65a "directory with no stripe info"
8068
8069 test_65b() {
8070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8071
8072         test_mkdir $DIR/$tdir
8073         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8074
8075         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8076                                                 error "setstripe"
8077         touch $DIR/$tdir/f2
8078         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8079 }
8080 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8081
8082 test_65c() {
8083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8084         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8085
8086         test_mkdir $DIR/$tdir
8087         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8088
8089         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8090                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8091         touch $DIR/$tdir/f3
8092         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8093 }
8094 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8095
8096 test_65d() {
8097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8098
8099         test_mkdir $DIR/$tdir
8100         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8101         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8102
8103         if [[ $STRIPECOUNT -le 0 ]]; then
8104                 sc=1
8105         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8106                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8107                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8108         else
8109                 sc=$(($STRIPECOUNT - 1))
8110         fi
8111         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8112         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8113         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8114                 error "lverify failed"
8115 }
8116 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8117
8118 test_65e() {
8119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8120
8121         test_mkdir $DIR/$tdir
8122
8123         $LFS setstripe $DIR/$tdir || error "setstripe"
8124         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8125                                         error "no stripe info failed"
8126         touch $DIR/$tdir/f6
8127         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8128 }
8129 run_test 65e "directory setstripe defaults"
8130
8131 test_65f() {
8132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8133
8134         test_mkdir $DIR/${tdir}f
8135         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8136                 error "setstripe succeeded" || true
8137 }
8138 run_test 65f "dir setstripe permission (should return error) ==="
8139
8140 test_65g() {
8141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8142
8143         test_mkdir $DIR/$tdir
8144         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8145
8146         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8147                 error "setstripe -S failed"
8148         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8149         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8150                 error "delete default stripe failed"
8151 }
8152 run_test 65g "directory setstripe -d"
8153
8154 test_65h() {
8155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8156
8157         test_mkdir $DIR/$tdir
8158         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8159
8160         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8161                 error "setstripe -S failed"
8162         test_mkdir $DIR/$tdir/dd1
8163         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8164                 error "stripe info inherit failed"
8165 }
8166 run_test 65h "directory stripe info inherit ===================="
8167
8168 test_65i() {
8169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8170
8171         save_layout_restore_at_exit $MOUNT
8172
8173         # bug6367: set non-default striping on root directory
8174         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8175
8176         # bug12836: getstripe on -1 default directory striping
8177         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8178
8179         # bug12836: getstripe -v on -1 default directory striping
8180         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8181
8182         # bug12836: new find on -1 default directory striping
8183         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8184 }
8185 run_test 65i "various tests to set root directory striping"
8186
8187 test_65j() { # bug6367
8188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8189
8190         sync; sleep 1
8191
8192         # if we aren't already remounting for each test, do so for this test
8193         if [ "$I_MOUNTED" = "yes" ]; then
8194                 cleanup || error "failed to unmount"
8195                 setup
8196         fi
8197
8198         save_layout_restore_at_exit $MOUNT
8199
8200         $LFS setstripe -d $MOUNT || error "setstripe failed"
8201 }
8202 run_test 65j "set default striping on root directory (bug 6367)="
8203
8204 cleanup_65k() {
8205         rm -rf $DIR/$tdir
8206         wait_delete_completed
8207         do_facet $SINGLEMDS "lctl set_param -n \
8208                 osp.$ost*MDT0000.max_create_count=$max_count"
8209         do_facet $SINGLEMDS "lctl set_param -n \
8210                 osp.$ost*MDT0000.create_count=$count"
8211         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8212         echo $INACTIVE_OSC "is Activate"
8213
8214         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8215 }
8216
8217 test_65k() { # bug11679
8218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8219         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8220         remote_mds_nodsh && skip "remote MDS with nodsh"
8221
8222         local disable_precreate=true
8223         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8224                 disable_precreate=false
8225
8226         echo "Check OST status: "
8227         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8228                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8229
8230         for OSC in $MDS_OSCS; do
8231                 echo $OSC "is active"
8232                 do_facet $SINGLEMDS lctl --device %$OSC activate
8233         done
8234
8235         for INACTIVE_OSC in $MDS_OSCS; do
8236                 local ost=$(osc_to_ost $INACTIVE_OSC)
8237                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8238                                lov.*md*.target_obd |
8239                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8240
8241                 mkdir -p $DIR/$tdir
8242                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8243                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8244
8245                 echo "Deactivate: " $INACTIVE_OSC
8246                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8247
8248                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8249                               osp.$ost*MDT0000.create_count")
8250                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8251                                   osp.$ost*MDT0000.max_create_count")
8252                 $disable_precreate &&
8253                         do_facet $SINGLEMDS "lctl set_param -n \
8254                                 osp.$ost*MDT0000.max_create_count=0"
8255
8256                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8257                         [ -f $DIR/$tdir/$idx ] && continue
8258                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8259                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8260                                 { cleanup_65k;
8261                                   error "setstripe $idx should succeed"; }
8262                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8263                 done
8264                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8265                 rmdir $DIR/$tdir
8266
8267                 do_facet $SINGLEMDS "lctl set_param -n \
8268                         osp.$ost*MDT0000.max_create_count=$max_count"
8269                 do_facet $SINGLEMDS "lctl set_param -n \
8270                         osp.$ost*MDT0000.create_count=$count"
8271                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8272                 echo $INACTIVE_OSC "is Activate"
8273
8274                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8275         done
8276 }
8277 run_test 65k "validate manual striping works properly with deactivated OSCs"
8278
8279 test_65l() { # bug 12836
8280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8281
8282         test_mkdir -p $DIR/$tdir/test_dir
8283         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8284         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8285 }
8286 run_test 65l "lfs find on -1 stripe dir ========================"
8287
8288 test_65m() {
8289         local layout=$(save_layout $MOUNT)
8290         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8291                 restore_layout $MOUNT $layout
8292                 error "setstripe should fail by non-root users"
8293         }
8294         true
8295 }
8296 run_test 65m "normal user can't set filesystem default stripe"
8297
8298 test_65n() {
8299         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8300         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8301                 skip "Need MDS version at least 2.12.50"
8302         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8303
8304         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8305         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8306         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8307
8308         local root_layout=$(save_layout $MOUNT)
8309         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8310
8311         # new subdirectory under root directory should not inherit
8312         # the default layout from root
8313         local dir1=$MOUNT/$tdir-1
8314         mkdir $dir1 || error "mkdir $dir1 failed"
8315         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8316                 error "$dir1 shouldn't have LOV EA"
8317
8318         # delete the default layout on root directory
8319         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8320
8321         local dir2=$MOUNT/$tdir-2
8322         mkdir $dir2 || error "mkdir $dir2 failed"
8323         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8324                 error "$dir2 shouldn't have LOV EA"
8325
8326         # set a new striping pattern on root directory
8327         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8328         local new_def_stripe_size=$((def_stripe_size * 2))
8329         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8330                 error "set stripe size on $MOUNT failed"
8331
8332         # new file created in $dir2 should inherit the new stripe size from
8333         # the filesystem default
8334         local file2=$dir2/$tfile-2
8335         touch $file2 || error "touch $file2 failed"
8336
8337         local file2_stripe_size=$($LFS getstripe -S $file2)
8338         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8339                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8340
8341         local dir3=$MOUNT/$tdir-3
8342         mkdir $dir3 || error "mkdir $dir3 failed"
8343         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8344         # the root layout, which is the actual default layout that will be used
8345         # when new files are created in $dir3.
8346         local dir3_layout=$(get_layout_param $dir3)
8347         local root_dir_layout=$(get_layout_param $MOUNT)
8348         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8349                 error "$dir3 should show the default layout from $MOUNT"
8350
8351         # set OST pool on root directory
8352         local pool=$TESTNAME
8353         pool_add $pool || error "add $pool failed"
8354         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8355                 error "add targets to $pool failed"
8356
8357         $LFS setstripe -p $pool $MOUNT ||
8358                 error "set OST pool on $MOUNT failed"
8359
8360         # new file created in $dir3 should inherit the pool from
8361         # the filesystem default
8362         local file3=$dir3/$tfile-3
8363         touch $file3 || error "touch $file3 failed"
8364
8365         local file3_pool=$($LFS getstripe -p $file3)
8366         [[ "$file3_pool" = "$pool" ]] ||
8367                 error "$file3 didn't inherit OST pool $pool"
8368
8369         local dir4=$MOUNT/$tdir-4
8370         mkdir $dir4 || error "mkdir $dir4 failed"
8371         local dir4_layout=$(get_layout_param $dir4)
8372         root_dir_layout=$(get_layout_param $MOUNT)
8373         echo "$LFS getstripe -d $dir4"
8374         $LFS getstripe -d $dir4
8375         echo "$LFS getstripe -d $MOUNT"
8376         $LFS getstripe -d $MOUNT
8377         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8378                 error "$dir4 should show the default layout from $MOUNT"
8379
8380         # new file created in $dir4 should inherit the pool from
8381         # the filesystem default
8382         local file4=$dir4/$tfile-4
8383         touch $file4 || error "touch $file4 failed"
8384
8385         local file4_pool=$($LFS getstripe -p $file4)
8386         [[ "$file4_pool" = "$pool" ]] ||
8387                 error "$file4 didn't inherit OST pool $pool"
8388
8389         # new subdirectory under non-root directory should inherit
8390         # the default layout from its parent directory
8391         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8392                 error "set directory layout on $dir4 failed"
8393
8394         local dir5=$dir4/$tdir-5
8395         mkdir $dir5 || error "mkdir $dir5 failed"
8396
8397         dir4_layout=$(get_layout_param $dir4)
8398         local dir5_layout=$(get_layout_param $dir5)
8399         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8400                 error "$dir5 should inherit the default layout from $dir4"
8401
8402         # though subdir under ROOT doesn't inherit default layout, but
8403         # its sub dir/file should be created with default layout.
8404         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8405         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8406                 skip "Need MDS version at least 2.12.59"
8407
8408         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8409         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8410         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8411
8412         if [ $default_lmv_hash == "none" ]; then
8413                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8414         else
8415                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8416                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8417         fi
8418
8419         $LFS setdirstripe -D -c 2 $MOUNT ||
8420                 error "setdirstripe -D -c 2 failed"
8421         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8422         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8423         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8424 }
8425 run_test 65n "don't inherit default layout from root for new subdirectories"
8426
8427 # bug 2543 - update blocks count on client
8428 test_66() {
8429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8430
8431         COUNT=${COUNT:-8}
8432         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8433         sync; sync_all_data; sync; sync_all_data
8434         cancel_lru_locks osc
8435         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8436         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8437 }
8438 run_test 66 "update inode blocks count on client ==============="
8439
8440 meminfo() {
8441         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8442 }
8443
8444 swap_used() {
8445         swapon -s | awk '($1 == "'$1'") { print $4 }'
8446 }
8447
8448 # bug5265, obdfilter oa2dentry return -ENOENT
8449 # #define OBD_FAIL_SRV_ENOENT 0x217
8450 test_69() {
8451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8452         remote_ost_nodsh && skip "remote OST with nodsh"
8453
8454         f="$DIR/$tfile"
8455         $LFS setstripe -c 1 -i 0 $f
8456
8457         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8458
8459         do_facet ost1 lctl set_param fail_loc=0x217
8460         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8461         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8462
8463         do_facet ost1 lctl set_param fail_loc=0
8464         $DIRECTIO write $f 0 2 || error "write error"
8465
8466         cancel_lru_locks osc
8467         $DIRECTIO read $f 0 1 || error "read error"
8468
8469         do_facet ost1 lctl set_param fail_loc=0x217
8470         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8471
8472         do_facet ost1 lctl set_param fail_loc=0
8473         rm -f $f
8474 }
8475 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8476
8477 test_71() {
8478         test_mkdir $DIR/$tdir
8479         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8480         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8481 }
8482 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8483
8484 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8486         [ "$RUNAS_ID" = "$UID" ] &&
8487                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8488         # Check that testing environment is properly set up. Skip if not
8489         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8490                 skip_env "User $RUNAS_ID does not exist - skipping"
8491
8492         touch $DIR/$tfile
8493         chmod 777 $DIR/$tfile
8494         chmod ug+s $DIR/$tfile
8495         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8496                 error "$RUNAS dd $DIR/$tfile failed"
8497         # See if we are still setuid/sgid
8498         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8499                 error "S/gid is not dropped on write"
8500         # Now test that MDS is updated too
8501         cancel_lru_locks mdc
8502         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8503                 error "S/gid is not dropped on MDS"
8504         rm -f $DIR/$tfile
8505 }
8506 run_test 72a "Test that remove suid works properly (bug5695) ===="
8507
8508 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8509         local perm
8510
8511         [ "$RUNAS_ID" = "$UID" ] &&
8512                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8513         [ "$RUNAS_ID" -eq 0 ] &&
8514                 skip_env "RUNAS_ID = 0 -- skipping"
8515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8516         # Check that testing environment is properly set up. Skip if not
8517         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8518                 skip_env "User $RUNAS_ID does not exist - skipping"
8519
8520         touch $DIR/${tfile}-f{g,u}
8521         test_mkdir $DIR/${tfile}-dg
8522         test_mkdir $DIR/${tfile}-du
8523         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8524         chmod g+s $DIR/${tfile}-{f,d}g
8525         chmod u+s $DIR/${tfile}-{f,d}u
8526         for perm in 777 2777 4777; do
8527                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8528                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8529                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8530                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8531         done
8532         true
8533 }
8534 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8535
8536 # bug 3462 - multiple simultaneous MDC requests
8537 test_73() {
8538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8539
8540         test_mkdir $DIR/d73-1
8541         test_mkdir $DIR/d73-2
8542         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8543         pid1=$!
8544
8545         lctl set_param fail_loc=0x80000129
8546         $MULTIOP $DIR/d73-1/f73-2 Oc &
8547         sleep 1
8548         lctl set_param fail_loc=0
8549
8550         $MULTIOP $DIR/d73-2/f73-3 Oc &
8551         pid3=$!
8552
8553         kill -USR1 $pid1
8554         wait $pid1 || return 1
8555
8556         sleep 25
8557
8558         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8559         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8560         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8561
8562         rm -rf $DIR/d73-*
8563 }
8564 run_test 73 "multiple MDC requests (should not deadlock)"
8565
8566 test_74a() { # bug 6149, 6184
8567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8568
8569         touch $DIR/f74a
8570         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8571         #
8572         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8573         # will spin in a tight reconnection loop
8574         $LCTL set_param fail_loc=0x8000030e
8575         # get any lock that won't be difficult - lookup works.
8576         ls $DIR/f74a
8577         $LCTL set_param fail_loc=0
8578         rm -f $DIR/f74a
8579         true
8580 }
8581 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8582
8583 test_74b() { # bug 13310
8584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8585
8586         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8587         #
8588         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8589         # will spin in a tight reconnection loop
8590         $LCTL set_param fail_loc=0x8000030e
8591         # get a "difficult" lock
8592         touch $DIR/f74b
8593         $LCTL set_param fail_loc=0
8594         rm -f $DIR/f74b
8595         true
8596 }
8597 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8598
8599 test_74c() {
8600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8601
8602         #define OBD_FAIL_LDLM_NEW_LOCK
8603         $LCTL set_param fail_loc=0x319
8604         touch $DIR/$tfile && error "touch successful"
8605         $LCTL set_param fail_loc=0
8606         true
8607 }
8608 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8609
8610 num_inodes() {
8611         [ -f /sys/kernel/slab/lustre_inode_cache/shrink ] &&
8612                 echo 1 > /sys/kernel/slab/lustre_inode_cache/shrink
8613         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
8614 }
8615
8616 test_76() { # Now for bug 20433, added originally in bug 1443
8617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8618
8619         cancel_lru_locks osc
8620         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8621         local before=$(num_inodes)
8622         local count=$((512 * cpus))
8623         [ "$SLOW" = "no" ] && count=$((64 * cpus))
8624
8625         echo "before inodes: $before"
8626         for i in $(seq $count); do
8627                 touch $DIR/$tfile
8628                 rm -f $DIR/$tfile
8629         done
8630         cancel_lru_locks osc
8631         local after=$(num_inodes)
8632         echo "after inodes: $after"
8633         while (( after > before + 8 * ${cpus:-1} )); do
8634                 sleep 1
8635                 after=$(num_inodes)
8636                 wait=$((wait + 1))
8637                 (( wait % 5 == 0 )) && echo "wait $wait seconds inodes: $after"
8638                 if (( wait > 30 )); then
8639                         error "inode slab grew from $before to $after"
8640                 fi
8641         done
8642 }
8643 run_test 76 "confirm clients recycle inodes properly ===="
8644
8645
8646 export ORIG_CSUM=""
8647 set_checksums()
8648 {
8649         # Note: in sptlrpc modes which enable its own bulk checksum, the
8650         # original crc32_le bulk checksum will be automatically disabled,
8651         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8652         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8653         # In this case set_checksums() will not be no-op, because sptlrpc
8654         # bulk checksum will be enabled all through the test.
8655
8656         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8657         lctl set_param -n osc.*.checksums $1
8658         return 0
8659 }
8660
8661 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8662                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8663 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8664                              tr -d [] | head -n1)}
8665 set_checksum_type()
8666 {
8667         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8668         rc=$?
8669         log "set checksum type to $1, rc = $rc"
8670         return $rc
8671 }
8672
8673 get_osc_checksum_type()
8674 {
8675         # arugment 1: OST name, like OST0000
8676         ost=$1
8677         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8678                         sed 's/.*\[\(.*\)\].*/\1/g')
8679         rc=$?
8680         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8681         echo $checksum_type
8682 }
8683
8684 F77_TMP=$TMP/f77-temp
8685 F77SZ=8
8686 setup_f77() {
8687         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8688                 error "error writing to $F77_TMP"
8689 }
8690
8691 test_77a() { # bug 10889
8692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8693         $GSS && skip_env "could not run with gss"
8694
8695         [ ! -f $F77_TMP ] && setup_f77
8696         set_checksums 1
8697         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8698         set_checksums 0
8699         rm -f $DIR/$tfile
8700 }
8701 run_test 77a "normal checksum read/write operation"
8702
8703 test_77b() { # bug 10889
8704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8705         $GSS && skip_env "could not run with gss"
8706
8707         [ ! -f $F77_TMP ] && setup_f77
8708         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8709         $LCTL set_param fail_loc=0x80000409
8710         set_checksums 1
8711
8712         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8713                 error "dd error: $?"
8714         $LCTL set_param fail_loc=0
8715
8716         for algo in $CKSUM_TYPES; do
8717                 cancel_lru_locks osc
8718                 set_checksum_type $algo
8719                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8720                 $LCTL set_param fail_loc=0x80000408
8721                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8722                 $LCTL set_param fail_loc=0
8723         done
8724         set_checksums 0
8725         set_checksum_type $ORIG_CSUM_TYPE
8726         rm -f $DIR/$tfile
8727 }
8728 run_test 77b "checksum error on client write, read"
8729
8730 cleanup_77c() {
8731         trap 0
8732         set_checksums 0
8733         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8734         $check_ost &&
8735                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8736         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8737         $check_ost && [ -n "$ost_file_prefix" ] &&
8738                 do_facet ost1 rm -f ${ost_file_prefix}\*
8739 }
8740
8741 test_77c() {
8742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8743         $GSS && skip_env "could not run with gss"
8744         remote_ost_nodsh && skip "remote OST with nodsh"
8745
8746         local bad1
8747         local osc_file_prefix
8748         local osc_file
8749         local check_ost=false
8750         local ost_file_prefix
8751         local ost_file
8752         local orig_cksum
8753         local dump_cksum
8754         local fid
8755
8756         # ensure corruption will occur on first OSS/OST
8757         $LFS setstripe -i 0 $DIR/$tfile
8758
8759         [ ! -f $F77_TMP ] && setup_f77
8760         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8761                 error "dd write error: $?"
8762         fid=$($LFS path2fid $DIR/$tfile)
8763
8764         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8765         then
8766                 check_ost=true
8767                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8768                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8769         else
8770                 echo "OSS do not support bulk pages dump upon error"
8771         fi
8772
8773         osc_file_prefix=$($LCTL get_param -n debug_path)
8774         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8775
8776         trap cleanup_77c EXIT
8777
8778         set_checksums 1
8779         # enable bulk pages dump upon error on Client
8780         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8781         # enable bulk pages dump upon error on OSS
8782         $check_ost &&
8783                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8784
8785         # flush Client cache to allow next read to reach OSS
8786         cancel_lru_locks osc
8787
8788         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8789         $LCTL set_param fail_loc=0x80000408
8790         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8791         $LCTL set_param fail_loc=0
8792
8793         rm -f $DIR/$tfile
8794
8795         # check cksum dump on Client
8796         osc_file=$(ls ${osc_file_prefix}*)
8797         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8798         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8799         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8800         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8801         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8802                      cksum)
8803         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8804         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8805                 error "dump content does not match on Client"
8806
8807         $check_ost || skip "No need to check cksum dump on OSS"
8808
8809         # check cksum dump on OSS
8810         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8811         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8812         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8813         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8814         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8815                 error "dump content does not match on OSS"
8816
8817         cleanup_77c
8818 }
8819 run_test 77c "checksum error on client read with debug"
8820
8821 test_77d() { # bug 10889
8822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8823         $GSS && skip_env "could not run with gss"
8824
8825         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8826         $LCTL set_param fail_loc=0x80000409
8827         set_checksums 1
8828         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8829                 error "direct write: rc=$?"
8830         $LCTL set_param fail_loc=0
8831         set_checksums 0
8832
8833         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8834         $LCTL set_param fail_loc=0x80000408
8835         set_checksums 1
8836         cancel_lru_locks osc
8837         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8838                 error "direct read: rc=$?"
8839         $LCTL set_param fail_loc=0
8840         set_checksums 0
8841 }
8842 run_test 77d "checksum error on OST direct write, read"
8843
8844 test_77f() { # bug 10889
8845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8846         $GSS && skip_env "could not run with gss"
8847
8848         set_checksums 1
8849         for algo in $CKSUM_TYPES; do
8850                 cancel_lru_locks osc
8851                 set_checksum_type $algo
8852                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8853                 $LCTL set_param fail_loc=0x409
8854                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8855                         error "direct write succeeded"
8856                 $LCTL set_param fail_loc=0
8857         done
8858         set_checksum_type $ORIG_CSUM_TYPE
8859         set_checksums 0
8860 }
8861 run_test 77f "repeat checksum error on write (expect error)"
8862
8863 test_77g() { # bug 10889
8864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8865         $GSS && skip_env "could not run with gss"
8866         remote_ost_nodsh && skip "remote OST with nodsh"
8867
8868         [ ! -f $F77_TMP ] && setup_f77
8869
8870         local file=$DIR/$tfile
8871         stack_trap "rm -f $file" EXIT
8872
8873         $LFS setstripe -c 1 -i 0 $file
8874         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8875         do_facet ost1 lctl set_param fail_loc=0x8000021a
8876         set_checksums 1
8877         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8878                 error "write error: rc=$?"
8879         do_facet ost1 lctl set_param fail_loc=0
8880         set_checksums 0
8881
8882         cancel_lru_locks osc
8883         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8884         do_facet ost1 lctl set_param fail_loc=0x8000021b
8885         set_checksums 1
8886         cmp $F77_TMP $file || error "file compare failed"
8887         do_facet ost1 lctl set_param fail_loc=0
8888         set_checksums 0
8889 }
8890 run_test 77g "checksum error on OST write, read"
8891
8892 test_77k() { # LU-10906
8893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8894         $GSS && skip_env "could not run with gss"
8895
8896         local cksum_param="osc.$FSNAME*.checksums"
8897         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8898         local checksum
8899         local i
8900
8901         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8902         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
8903         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
8904
8905         for i in 0 1; do
8906                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8907                         error "failed to set checksum=$i on MGS"
8908                 wait_update $HOSTNAME "$get_checksum" $i
8909                 #remount
8910                 echo "remount client, checksum should be $i"
8911                 remount_client $MOUNT || error "failed to remount client"
8912                 checksum=$(eval $get_checksum)
8913                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8914         done
8915         # remove persistent param to avoid races with checksum mountopt below
8916         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8917                 error "failed to delete checksum on MGS"
8918
8919         for opt in "checksum" "nochecksum"; do
8920                 #remount with mount option
8921                 echo "remount client with option $opt, checksum should be $i"
8922                 umount_client $MOUNT || error "failed to umount client"
8923                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8924                         error "failed to mount client with option '$opt'"
8925                 checksum=$(eval $get_checksum)
8926                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8927                 i=$((i - 1))
8928         done
8929
8930         remount_client $MOUNT || error "failed to remount client"
8931 }
8932 run_test 77k "enable/disable checksum correctly"
8933
8934 test_77l() {
8935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8936         $GSS && skip_env "could not run with gss"
8937
8938         set_checksums 1
8939         stack_trap "set_checksums $ORIG_CSUM" EXIT
8940         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8941
8942         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8943
8944         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8945         for algo in $CKSUM_TYPES; do
8946                 set_checksum_type $algo || error "fail to set checksum type $algo"
8947                 osc_algo=$(get_osc_checksum_type OST0000)
8948                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8949
8950                 # no locks, no reqs to let the connection idle
8951                 cancel_lru_locks osc
8952                 lru_resize_disable osc
8953                 wait_osc_import_state client ost1 IDLE
8954
8955                 # ensure ost1 is connected
8956                 stat $DIR/$tfile >/dev/null || error "can't stat"
8957                 wait_osc_import_state client ost1 FULL
8958
8959                 osc_algo=$(get_osc_checksum_type OST0000)
8960                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8961         done
8962         return 0
8963 }
8964 run_test 77l "preferred checksum type is remembered after reconnected"
8965
8966 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8967 rm -f $F77_TMP
8968 unset F77_TMP
8969
8970 cleanup_test_78() {
8971         trap 0
8972         rm -f $DIR/$tfile
8973 }
8974
8975 test_78() { # bug 10901
8976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8977         remote_ost || skip_env "local OST"
8978
8979         NSEQ=5
8980         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8981         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8982         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8983         echo "MemTotal: $MEMTOTAL"
8984
8985         # reserve 256MB of memory for the kernel and other running processes,
8986         # and then take 1/2 of the remaining memory for the read/write buffers.
8987         if [ $MEMTOTAL -gt 512 ] ;then
8988                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8989         else
8990                 # for those poor memory-starved high-end clusters...
8991                 MEMTOTAL=$((MEMTOTAL / 2))
8992         fi
8993         echo "Mem to use for directio: $MEMTOTAL"
8994
8995         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8996         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8997         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8998         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8999                 head -n1)
9000         echo "Smallest OST: $SMALLESTOST"
9001         [[ $SMALLESTOST -lt 10240 ]] &&
9002                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9003
9004         trap cleanup_test_78 EXIT
9005
9006         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9007                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9008
9009         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9010         echo "File size: $F78SIZE"
9011         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9012         for i in $(seq 1 $NSEQ); do
9013                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9014                 echo directIO rdwr round $i of $NSEQ
9015                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9016         done
9017
9018         cleanup_test_78
9019 }
9020 run_test 78 "handle large O_DIRECT writes correctly ============"
9021
9022 test_79() { # bug 12743
9023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9024
9025         wait_delete_completed
9026
9027         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9028         BKFREE=$(calc_osc_kbytes kbytesfree)
9029         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9030
9031         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9032         DFTOTAL=`echo $STRING | cut -d, -f1`
9033         DFUSED=`echo $STRING  | cut -d, -f2`
9034         DFAVAIL=`echo $STRING | cut -d, -f3`
9035         DFFREE=$(($DFTOTAL - $DFUSED))
9036
9037         ALLOWANCE=$((64 * $OSTCOUNT))
9038
9039         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9040            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9041                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9042         fi
9043         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9044            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9045                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9046         fi
9047         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9048            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9049                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9050         fi
9051 }
9052 run_test 79 "df report consistency check ======================="
9053
9054 test_80() { # bug 10718
9055         remote_ost_nodsh && skip "remote OST with nodsh"
9056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9057
9058         # relax strong synchronous semantics for slow backends like ZFS
9059         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9060                 local soc="obdfilter.*.sync_lock_cancel"
9061                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9062
9063                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9064                 if [ -z "$save" ]; then
9065                         soc="obdfilter.*.sync_on_lock_cancel"
9066                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9067                 fi
9068
9069                 if [ "$save" != "never" ]; then
9070                         local hosts=$(comma_list $(osts_nodes))
9071
9072                         do_nodes $hosts $LCTL set_param $soc=never
9073                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9074                 fi
9075         fi
9076
9077         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9078         sync; sleep 1; sync
9079         local before=$(date +%s)
9080         cancel_lru_locks osc
9081         local after=$(date +%s)
9082         local diff=$((after - before))
9083         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9084
9085         rm -f $DIR/$tfile
9086 }
9087 run_test 80 "Page eviction is equally fast at high offsets too"
9088
9089 test_81a() { # LU-456
9090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9091         remote_ost_nodsh && skip "remote OST with nodsh"
9092
9093         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9094         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9095         do_facet ost1 lctl set_param fail_loc=0x80000228
9096
9097         # write should trigger a retry and success
9098         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9099         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9100         RC=$?
9101         if [ $RC -ne 0 ] ; then
9102                 error "write should success, but failed for $RC"
9103         fi
9104 }
9105 run_test 81a "OST should retry write when get -ENOSPC ==============="
9106
9107 test_81b() { # LU-456
9108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9109         remote_ost_nodsh && skip "remote OST with nodsh"
9110
9111         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9112         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9113         do_facet ost1 lctl set_param fail_loc=0x228
9114
9115         # write should retry several times and return -ENOSPC finally
9116         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9117         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9118         RC=$?
9119         ENOSPC=28
9120         if [ $RC -ne $ENOSPC ] ; then
9121                 error "dd should fail for -ENOSPC, but succeed."
9122         fi
9123 }
9124 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9125
9126 test_99() {
9127         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9128
9129         test_mkdir $DIR/$tdir.cvsroot
9130         chown $RUNAS_ID $DIR/$tdir.cvsroot
9131
9132         cd $TMP
9133         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9134
9135         cd /etc/init.d
9136         # some versions of cvs import exit(1) when asked to import links or
9137         # files they can't read.  ignore those files.
9138         local toignore=$(find . -type l -printf '-I %f\n' -o \
9139                          ! -perm /4 -printf '-I %f\n')
9140         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9141                 $tdir.reposname vtag rtag
9142
9143         cd $DIR
9144         test_mkdir $DIR/$tdir.reposname
9145         chown $RUNAS_ID $DIR/$tdir.reposname
9146         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9147
9148         cd $DIR/$tdir.reposname
9149         $RUNAS touch foo99
9150         $RUNAS cvs add -m 'addmsg' foo99
9151         $RUNAS cvs update
9152         $RUNAS cvs commit -m 'nomsg' foo99
9153         rm -fr $DIR/$tdir.cvsroot
9154 }
9155 run_test 99 "cvs strange file/directory operations"
9156
9157 test_100() {
9158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9159         [[ "$NETTYPE" =~ tcp ]] ||
9160                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9161         remote_ost_nodsh && skip "remote OST with nodsh"
9162         remote_mds_nodsh && skip "remote MDS with nodsh"
9163         remote_servers ||
9164                 skip "useless for local single node setup"
9165
9166         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9167                 [ "$PROT" != "tcp" ] && continue
9168                 RPORT=$(echo $REMOTE | cut -d: -f2)
9169                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9170
9171                 rc=0
9172                 LPORT=`echo $LOCAL | cut -d: -f2`
9173                 if [ $LPORT -ge 1024 ]; then
9174                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9175                         netstat -tna
9176                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9177                 fi
9178         done
9179         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9180 }
9181 run_test 100 "check local port using privileged port ==========="
9182
9183 function get_named_value()
9184 {
9185     local tag
9186
9187     tag=$1
9188     while read ;do
9189         line=$REPLY
9190         case $line in
9191         $tag*)
9192             echo $line | sed "s/^$tag[ ]*//"
9193             break
9194             ;;
9195         esac
9196     done
9197 }
9198
9199 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9200                    awk '/^max_cached_mb/ { print $2 }')
9201
9202 cleanup_101a() {
9203         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9204         trap 0
9205 }
9206
9207 test_101a() {
9208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9209
9210         local s
9211         local discard
9212         local nreads=10000
9213         local cache_limit=32
9214
9215         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9216         trap cleanup_101a EXIT
9217         $LCTL set_param -n llite.*.read_ahead_stats 0
9218         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9219
9220         #
9221         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9222         #
9223         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9224         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9225
9226         discard=0
9227         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9228                 get_named_value 'read but discarded' | cut -d" " -f1); do
9229                         discard=$(($discard + $s))
9230         done
9231         cleanup_101a
9232
9233         $LCTL get_param osc.*-osc*.rpc_stats
9234         $LCTL get_param llite.*.read_ahead_stats
9235
9236         # Discard is generally zero, but sometimes a few random reads line up
9237         # and trigger larger readahead, which is wasted & leads to discards.
9238         if [[ $(($discard)) -gt $nreads ]]; then
9239                 error "too many ($discard) discarded pages"
9240         fi
9241         rm -f $DIR/$tfile || true
9242 }
9243 run_test 101a "check read-ahead for random reads"
9244
9245 setup_test101bc() {
9246         test_mkdir $DIR/$tdir
9247         local ssize=$1
9248         local FILE_LENGTH=$2
9249         STRIPE_OFFSET=0
9250
9251         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9252
9253         local list=$(comma_list $(osts_nodes))
9254         set_osd_param $list '' read_cache_enable 0
9255         set_osd_param $list '' writethrough_cache_enable 0
9256
9257         trap cleanup_test101bc EXIT
9258         # prepare the read-ahead file
9259         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9260
9261         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9262                                 count=$FILE_SIZE_MB 2> /dev/null
9263
9264 }
9265
9266 cleanup_test101bc() {
9267         trap 0
9268         rm -rf $DIR/$tdir
9269         rm -f $DIR/$tfile
9270
9271         local list=$(comma_list $(osts_nodes))
9272         set_osd_param $list '' read_cache_enable 1
9273         set_osd_param $list '' writethrough_cache_enable 1
9274 }
9275
9276 calc_total() {
9277         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9278 }
9279
9280 ra_check_101() {
9281         local READ_SIZE=$1
9282         local STRIPE_SIZE=$2
9283         local FILE_LENGTH=$3
9284         local RA_INC=1048576
9285         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9286         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9287                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9288         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9289                         get_named_value 'read but discarded' |
9290                         cut -d" " -f1 | calc_total)
9291         if [[ $DISCARD -gt $discard_limit ]]; then
9292                 $LCTL get_param llite.*.read_ahead_stats
9293                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9294         else
9295                 echo "Read-ahead success for size ${READ_SIZE}"
9296         fi
9297 }
9298
9299 test_101b() {
9300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9301         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9302
9303         local STRIPE_SIZE=1048576
9304         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9305
9306         if [ $SLOW == "yes" ]; then
9307                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9308         else
9309                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9310         fi
9311
9312         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9313
9314         # prepare the read-ahead file
9315         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9316         cancel_lru_locks osc
9317         for BIDX in 2 4 8 16 32 64 128 256
9318         do
9319                 local BSIZE=$((BIDX*4096))
9320                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9321                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9322                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9323                 $LCTL set_param -n llite.*.read_ahead_stats 0
9324                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9325                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9326                 cancel_lru_locks osc
9327                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9328         done
9329         cleanup_test101bc
9330         true
9331 }
9332 run_test 101b "check stride-io mode read-ahead ================="
9333
9334 test_101c() {
9335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9336
9337         local STRIPE_SIZE=1048576
9338         local FILE_LENGTH=$((STRIPE_SIZE*100))
9339         local nreads=10000
9340         local rsize=65536
9341         local osc_rpc_stats
9342
9343         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9344
9345         cancel_lru_locks osc
9346         $LCTL set_param osc.*.rpc_stats 0
9347         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9348         $LCTL get_param osc.*.rpc_stats
9349         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9350                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9351                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9352                 local size
9353
9354                 if [ $lines -le 20 ]; then
9355                         echo "continue debug"
9356                         continue
9357                 fi
9358                 for size in 1 2 4 8; do
9359                         local rpc=$(echo "$stats" |
9360                                     awk '($1 == "'$size':") {print $2; exit; }')
9361                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9362                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9363                 done
9364                 echo "$osc_rpc_stats check passed!"
9365         done
9366         cleanup_test101bc
9367         true
9368 }
9369 run_test 101c "check stripe_size aligned read-ahead ================="
9370
9371 test_101d() {
9372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9373
9374         local file=$DIR/$tfile
9375         local sz_MB=${FILESIZE_101d:-80}
9376         local ra_MB=${READAHEAD_MB:-40}
9377
9378         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9379         [ $free_MB -lt $sz_MB ] &&
9380                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9381
9382         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9383         $LFS setstripe -c -1 $file || error "setstripe failed"
9384
9385         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9386         echo Cancel LRU locks on lustre client to flush the client cache
9387         cancel_lru_locks osc
9388
9389         echo Disable read-ahead
9390         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9391         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9392         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9393         $LCTL get_param -n llite.*.max_read_ahead_mb
9394
9395         echo "Reading the test file $file with read-ahead disabled"
9396         local sz_KB=$((sz_MB * 1024 / 4))
9397         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9398         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9399         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9400                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9401
9402         echo "Cancel LRU locks on lustre client to flush the client cache"
9403         cancel_lru_locks osc
9404         echo Enable read-ahead with ${ra_MB}MB
9405         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9406
9407         echo "Reading the test file $file with read-ahead enabled"
9408         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9409                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9410
9411         echo "read-ahead disabled time read $raOFF"
9412         echo "read-ahead enabled time read $raON"
9413
9414         rm -f $file
9415         wait_delete_completed
9416
9417         # use awk for this check instead of bash because it handles decimals
9418         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9419                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9420 }
9421 run_test 101d "file read with and without read-ahead enabled"
9422
9423 test_101e() {
9424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9425
9426         local file=$DIR/$tfile
9427         local size_KB=500  #KB
9428         local count=100
9429         local bsize=1024
9430
9431         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9432         local need_KB=$((count * size_KB))
9433         [[ $free_KB -le $need_KB ]] &&
9434                 skip_env "Need free space $need_KB, have $free_KB"
9435
9436         echo "Creating $count ${size_KB}K test files"
9437         for ((i = 0; i < $count; i++)); do
9438                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9439         done
9440
9441         echo "Cancel LRU locks on lustre client to flush the client cache"
9442         cancel_lru_locks $OSC
9443
9444         echo "Reset readahead stats"
9445         $LCTL set_param -n llite.*.read_ahead_stats 0
9446
9447         for ((i = 0; i < $count; i++)); do
9448                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9449         done
9450
9451         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9452                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9453
9454         for ((i = 0; i < $count; i++)); do
9455                 rm -rf $file.$i 2>/dev/null
9456         done
9457
9458         #10000 means 20% reads are missing in readahead
9459         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9460 }
9461 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9462
9463 test_101f() {
9464         which iozone || skip_env "no iozone installed"
9465
9466         local old_debug=$($LCTL get_param debug)
9467         old_debug=${old_debug#*=}
9468         $LCTL set_param debug="reada mmap"
9469
9470         # create a test file
9471         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
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         echo mmap read the file with small block size
9480         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9481                 > /dev/null 2>&1
9482
9483         echo checking missing pages
9484         $LCTL get_param llite.*.read_ahead_stats
9485         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9486                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9487
9488         $LCTL set_param debug="$old_debug"
9489         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9490         rm -f $DIR/$tfile
9491 }
9492 run_test 101f "check mmap read performance"
9493
9494 test_101g_brw_size_test() {
9495         local mb=$1
9496         local pages=$((mb * 1048576 / PAGE_SIZE))
9497         local file=$DIR/$tfile
9498
9499         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9500                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9501         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9502                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9503                         return 2
9504         done
9505
9506         stack_trap "rm -f $file" EXIT
9507         $LCTL set_param -n osc.*.rpc_stats=0
9508
9509         # 10 RPCs should be enough for the test
9510         local count=10
9511         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9512                 { error "dd write ${mb} MB blocks failed"; return 3; }
9513         cancel_lru_locks osc
9514         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9515                 { error "dd write ${mb} MB blocks failed"; return 4; }
9516
9517         # calculate number of full-sized read and write RPCs
9518         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9519                 sed -n '/pages per rpc/,/^$/p' |
9520                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9521                 END { print reads,writes }'))
9522         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
9523                 return 5
9524         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
9525                 return 6
9526
9527         return 0
9528 }
9529
9530 test_101g() {
9531         remote_ost_nodsh && skip "remote OST with nodsh"
9532
9533         local rpcs
9534         local osts=$(get_facets OST)
9535         local list=$(comma_list $(osts_nodes))
9536         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9537         local brw_size="obdfilter.*.brw_size"
9538
9539         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9540
9541         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9542
9543         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9544                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9545                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9546            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9547                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9548                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9549
9550                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9551                         suffix="M"
9552
9553                 if [[ $orig_mb -lt 16 ]]; then
9554                         save_lustre_params $osts "$brw_size" > $p
9555                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9556                                 error "set 16MB RPC size failed"
9557
9558                         echo "remount client to enable new RPC size"
9559                         remount_client $MOUNT || error "remount_client failed"
9560                 fi
9561
9562                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9563                 # should be able to set brw_size=12, but no rpc_stats for that
9564                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9565         fi
9566
9567         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9568
9569         if [[ $orig_mb -lt 16 ]]; then
9570                 restore_lustre_params < $p
9571                 remount_client $MOUNT || error "remount_client restore failed"
9572         fi
9573
9574         rm -f $p $DIR/$tfile
9575 }
9576 run_test 101g "Big bulk(4/16 MiB) readahead"
9577
9578 test_101h() {
9579         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9580
9581         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9582                 error "dd 70M file failed"
9583         echo Cancel LRU locks on lustre client to flush the client cache
9584         cancel_lru_locks osc
9585
9586         echo "Reset readahead stats"
9587         $LCTL set_param -n llite.*.read_ahead_stats 0
9588
9589         echo "Read 10M of data but cross 64M bundary"
9590         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9591         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9592                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9593         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9594         rm -f $p $DIR/$tfile
9595 }
9596 run_test 101h "Readahead should cover current read window"
9597
9598 test_101i() {
9599         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9600                 error "dd 10M file failed"
9601
9602         local max_per_file_mb=$($LCTL get_param -n \
9603                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9604         cancel_lru_locks osc
9605         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9606         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9607                 error "set max_read_ahead_per_file_mb to 1 failed"
9608
9609         echo "Reset readahead stats"
9610         $LCTL set_param llite.*.read_ahead_stats=0
9611
9612         dd if=$DIR/$tfile of=/dev/null bs=2M
9613
9614         $LCTL get_param llite.*.read_ahead_stats
9615         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9616                      awk '/misses/ { print $2 }')
9617         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9618         rm -f $DIR/$tfile
9619 }
9620 run_test 101i "allow current readahead to exceed reservation"
9621
9622 test_101j() {
9623         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9624                 error "setstripe $DIR/$tfile failed"
9625         local file_size=$((1048576 * 16))
9626         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9627         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9628
9629         echo Disable read-ahead
9630         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9631
9632         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9633         for blk in $PAGE_SIZE 1048576 $file_size; do
9634                 cancel_lru_locks osc
9635                 echo "Reset readahead stats"
9636                 $LCTL set_param -n llite.*.read_ahead_stats=0
9637                 local count=$(($file_size / $blk))
9638                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9639                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9640                              get_named_value 'failed to fast read' |
9641                              cut -d" " -f1 | calc_total)
9642                 $LCTL get_param -n llite.*.read_ahead_stats
9643                 [ $miss -eq $count ] || error "expected $count got $miss"
9644         done
9645
9646         rm -f $p $DIR/$tfile
9647 }
9648 run_test 101j "A complete read block should be submitted when no RA"
9649
9650 setup_test102() {
9651         test_mkdir $DIR/$tdir
9652         chown $RUNAS_ID $DIR/$tdir
9653         STRIPE_SIZE=65536
9654         STRIPE_OFFSET=1
9655         STRIPE_COUNT=$OSTCOUNT
9656         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9657
9658         trap cleanup_test102 EXIT
9659         cd $DIR
9660         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9661         cd $DIR/$tdir
9662         for num in 1 2 3 4; do
9663                 for count in $(seq 1 $STRIPE_COUNT); do
9664                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9665                                 local size=`expr $STRIPE_SIZE \* $num`
9666                                 local file=file"$num-$idx-$count"
9667                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9668                         done
9669                 done
9670         done
9671
9672         cd $DIR
9673         $1 tar cf $TMP/f102.tar $tdir --xattrs
9674 }
9675
9676 cleanup_test102() {
9677         trap 0
9678         rm -f $TMP/f102.tar
9679         rm -rf $DIR/d0.sanity/d102
9680 }
9681
9682 test_102a() {
9683         [ "$UID" != 0 ] && skip "must run as root"
9684         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9685                 skip_env "must have user_xattr"
9686
9687         [ -z "$(which setfattr 2>/dev/null)" ] &&
9688                 skip_env "could not find setfattr"
9689
9690         local testfile=$DIR/$tfile
9691
9692         touch $testfile
9693         echo "set/get xattr..."
9694         setfattr -n trusted.name1 -v value1 $testfile ||
9695                 error "setfattr -n trusted.name1=value1 $testfile failed"
9696         getfattr -n trusted.name1 $testfile 2> /dev/null |
9697           grep "trusted.name1=.value1" ||
9698                 error "$testfile missing trusted.name1=value1"
9699
9700         setfattr -n user.author1 -v author1 $testfile ||
9701                 error "setfattr -n user.author1=author1 $testfile failed"
9702         getfattr -n user.author1 $testfile 2> /dev/null |
9703           grep "user.author1=.author1" ||
9704                 error "$testfile missing trusted.author1=author1"
9705
9706         echo "listxattr..."
9707         setfattr -n trusted.name2 -v value2 $testfile ||
9708                 error "$testfile unable to set trusted.name2"
9709         setfattr -n trusted.name3 -v value3 $testfile ||
9710                 error "$testfile unable to set trusted.name3"
9711         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9712             grep "trusted.name" | wc -l) -eq 3 ] ||
9713                 error "$testfile missing 3 trusted.name xattrs"
9714
9715         setfattr -n user.author2 -v author2 $testfile ||
9716                 error "$testfile unable to set user.author2"
9717         setfattr -n user.author3 -v author3 $testfile ||
9718                 error "$testfile unable to set user.author3"
9719         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9720             grep "user.author" | wc -l) -eq 3 ] ||
9721                 error "$testfile missing 3 user.author xattrs"
9722
9723         echo "remove xattr..."
9724         setfattr -x trusted.name1 $testfile ||
9725                 error "$testfile error deleting trusted.name1"
9726         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9727                 error "$testfile did not delete trusted.name1 xattr"
9728
9729         setfattr -x user.author1 $testfile ||
9730                 error "$testfile error deleting user.author1"
9731         echo "set lustre special xattr ..."
9732         $LFS setstripe -c1 $testfile
9733         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9734                 awk -F "=" '/trusted.lov/ { print $2 }' )
9735         setfattr -n "trusted.lov" -v $lovea $testfile ||
9736                 error "$testfile doesn't ignore setting trusted.lov again"
9737         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9738                 error "$testfile allow setting invalid trusted.lov"
9739         rm -f $testfile
9740 }
9741 run_test 102a "user xattr test =================================="
9742
9743 check_102b_layout() {
9744         local layout="$*"
9745         local testfile=$DIR/$tfile
9746
9747         echo "test layout '$layout'"
9748         $LFS setstripe $layout $testfile || error "setstripe failed"
9749         $LFS getstripe -y $testfile
9750
9751         echo "get/set/list trusted.lov xattr ..." # b=10930
9752         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9753         [[ "$value" =~ "trusted.lov" ]] ||
9754                 error "can't get trusted.lov from $testfile"
9755         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9756                 error "getstripe failed"
9757
9758         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9759
9760         value=$(cut -d= -f2 <<<$value)
9761         # LU-13168: truncated xattr should fail if short lov_user_md header
9762         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9763                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9764         for len in $lens; do
9765                 echo "setfattr $len $testfile.2"
9766                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9767                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9768         done
9769         local stripe_size=$($LFS getstripe -S $testfile.2)
9770         local stripe_count=$($LFS getstripe -c $testfile.2)
9771         [[ $stripe_size -eq 65536 ]] ||
9772                 error "stripe size $stripe_size != 65536"
9773         [[ $stripe_count -eq $stripe_count_orig ]] ||
9774                 error "stripe count $stripe_count != $stripe_count_orig"
9775         rm $testfile $testfile.2
9776 }
9777
9778 test_102b() {
9779         [ -z "$(which setfattr 2>/dev/null)" ] &&
9780                 skip_env "could not find setfattr"
9781         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9782
9783         # check plain layout
9784         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9785
9786         # and also check composite layout
9787         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9788
9789 }
9790 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9791
9792 test_102c() {
9793         [ -z "$(which setfattr 2>/dev/null)" ] &&
9794                 skip_env "could not find setfattr"
9795         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9796
9797         # b10930: get/set/list lustre.lov xattr
9798         echo "get/set/list lustre.lov xattr ..."
9799         test_mkdir $DIR/$tdir
9800         chown $RUNAS_ID $DIR/$tdir
9801         local testfile=$DIR/$tdir/$tfile
9802         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9803                 error "setstripe failed"
9804         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9805                 error "getstripe failed"
9806         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9807         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9808
9809         local testfile2=${testfile}2
9810         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9811                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9812
9813         $RUNAS $MCREATE $testfile2
9814         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9815         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9816         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9817         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9818         [ $stripe_count -eq $STRIPECOUNT ] ||
9819                 error "stripe count $stripe_count != $STRIPECOUNT"
9820 }
9821 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9822
9823 compare_stripe_info1() {
9824         local stripe_index_all_zero=true
9825
9826         for num in 1 2 3 4; do
9827                 for count in $(seq 1 $STRIPE_COUNT); do
9828                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9829                                 local size=$((STRIPE_SIZE * num))
9830                                 local file=file"$num-$offset-$count"
9831                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9832                                 [[ $stripe_size -ne $size ]] &&
9833                                     error "$file: size $stripe_size != $size"
9834                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9835                                 # allow fewer stripes to be created, ORI-601
9836                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9837                                     error "$file: count $stripe_count != $count"
9838                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9839                                 [[ $stripe_index -ne 0 ]] &&
9840                                         stripe_index_all_zero=false
9841                         done
9842                 done
9843         done
9844         $stripe_index_all_zero &&
9845                 error "all files are being extracted starting from OST index 0"
9846         return 0
9847 }
9848
9849 have_xattrs_include() {
9850         tar --help | grep -q xattrs-include &&
9851                 echo --xattrs-include="lustre.*"
9852 }
9853
9854 test_102d() {
9855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9857
9858         XINC=$(have_xattrs_include)
9859         setup_test102
9860         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9861         cd $DIR/$tdir/$tdir
9862         compare_stripe_info1
9863 }
9864 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9865
9866 test_102f() {
9867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9868         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9869
9870         XINC=$(have_xattrs_include)
9871         setup_test102
9872         test_mkdir $DIR/$tdir.restore
9873         cd $DIR
9874         tar cf - --xattrs $tdir | tar xf - \
9875                 -C $DIR/$tdir.restore --xattrs $XINC
9876         cd $DIR/$tdir.restore/$tdir
9877         compare_stripe_info1
9878 }
9879 run_test 102f "tar copy files, not keep osts"
9880
9881 grow_xattr() {
9882         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9883                 skip "must have user_xattr"
9884         [ -z "$(which setfattr 2>/dev/null)" ] &&
9885                 skip_env "could not find setfattr"
9886         [ -z "$(which getfattr 2>/dev/null)" ] &&
9887                 skip_env "could not find getfattr"
9888
9889         local xsize=${1:-1024}  # in bytes
9890         local file=$DIR/$tfile
9891         local value="$(generate_string $xsize)"
9892         local xbig=trusted.big
9893         local toobig=$2
9894
9895         touch $file
9896         log "save $xbig on $file"
9897         if [ -z "$toobig" ]
9898         then
9899                 setfattr -n $xbig -v $value $file ||
9900                         error "saving $xbig on $file failed"
9901         else
9902                 setfattr -n $xbig -v $value $file &&
9903                         error "saving $xbig on $file succeeded"
9904                 return 0
9905         fi
9906
9907         local orig=$(get_xattr_value $xbig $file)
9908         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9909
9910         local xsml=trusted.sml
9911         log "save $xsml on $file"
9912         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9913
9914         local new=$(get_xattr_value $xbig $file)
9915         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9916
9917         log "grow $xsml on $file"
9918         setfattr -n $xsml -v "$value" $file ||
9919                 error "growing $xsml on $file failed"
9920
9921         new=$(get_xattr_value $xbig $file)
9922         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9923         log "$xbig still valid after growing $xsml"
9924
9925         rm -f $file
9926 }
9927
9928 test_102h() { # bug 15777
9929         grow_xattr 1024
9930 }
9931 run_test 102h "grow xattr from inside inode to external block"
9932
9933 test_102ha() {
9934         large_xattr_enabled || skip_env "ea_inode feature disabled"
9935
9936         echo "setting xattr of max xattr size: $(max_xattr_size)"
9937         grow_xattr $(max_xattr_size)
9938
9939         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9940         echo "This should fail:"
9941         grow_xattr $(($(max_xattr_size) + 10)) 1
9942 }
9943 run_test 102ha "grow xattr from inside inode to external inode"
9944
9945 test_102i() { # bug 17038
9946         [ -z "$(which getfattr 2>/dev/null)" ] &&
9947                 skip "could not find getfattr"
9948
9949         touch $DIR/$tfile
9950         ln -s $DIR/$tfile $DIR/${tfile}link
9951         getfattr -n trusted.lov $DIR/$tfile ||
9952                 error "lgetxattr on $DIR/$tfile failed"
9953         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9954                 grep -i "no such attr" ||
9955                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9956         rm -f $DIR/$tfile $DIR/${tfile}link
9957 }
9958 run_test 102i "lgetxattr test on symbolic link ============"
9959
9960 test_102j() {
9961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9962         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9963
9964         XINC=$(have_xattrs_include)
9965         setup_test102 "$RUNAS"
9966         chown $RUNAS_ID $DIR/$tdir
9967         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9968         cd $DIR/$tdir/$tdir
9969         compare_stripe_info1 "$RUNAS"
9970 }
9971 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9972
9973 test_102k() {
9974         [ -z "$(which setfattr 2>/dev/null)" ] &&
9975                 skip "could not find setfattr"
9976
9977         touch $DIR/$tfile
9978         # b22187 just check that does not crash for regular file.
9979         setfattr -n trusted.lov $DIR/$tfile
9980         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9981         local test_kdir=$DIR/$tdir
9982         test_mkdir $test_kdir
9983         local default_size=$($LFS getstripe -S $test_kdir)
9984         local default_count=$($LFS getstripe -c $test_kdir)
9985         local default_offset=$($LFS getstripe -i $test_kdir)
9986         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
9987                 error 'dir setstripe failed'
9988         setfattr -n trusted.lov $test_kdir
9989         local stripe_size=$($LFS getstripe -S $test_kdir)
9990         local stripe_count=$($LFS getstripe -c $test_kdir)
9991         local stripe_offset=$($LFS getstripe -i $test_kdir)
9992         [ $stripe_size -eq $default_size ] ||
9993                 error "stripe size $stripe_size != $default_size"
9994         [ $stripe_count -eq $default_count ] ||
9995                 error "stripe count $stripe_count != $default_count"
9996         [ $stripe_offset -eq $default_offset ] ||
9997                 error "stripe offset $stripe_offset != $default_offset"
9998         rm -rf $DIR/$tfile $test_kdir
9999 }
10000 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10001
10002 test_102l() {
10003         [ -z "$(which getfattr 2>/dev/null)" ] &&
10004                 skip "could not find getfattr"
10005
10006         # LU-532 trusted. xattr is invisible to non-root
10007         local testfile=$DIR/$tfile
10008
10009         touch $testfile
10010
10011         echo "listxattr as user..."
10012         chown $RUNAS_ID $testfile
10013         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10014             grep -q "trusted" &&
10015                 error "$testfile trusted xattrs are user visible"
10016
10017         return 0;
10018 }
10019 run_test 102l "listxattr size test =================================="
10020
10021 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10022         local path=$DIR/$tfile
10023         touch $path
10024
10025         listxattr_size_check $path || error "listattr_size_check $path failed"
10026 }
10027 run_test 102m "Ensure listxattr fails on small bufffer ========"
10028
10029 cleanup_test102
10030
10031 getxattr() { # getxattr path name
10032         # Return the base64 encoding of the value of xattr name on path.
10033         local path=$1
10034         local name=$2
10035
10036         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10037         # file: $path
10038         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10039         #
10040         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10041
10042         getfattr --absolute-names --encoding=base64 --name=$name $path |
10043                 awk -F= -v name=$name '$1 == name {
10044                         print substr($0, index($0, "=") + 1);
10045         }'
10046 }
10047
10048 test_102n() { # LU-4101 mdt: protect internal xattrs
10049         [ -z "$(which setfattr 2>/dev/null)" ] &&
10050                 skip "could not find setfattr"
10051         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10052         then
10053                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10054         fi
10055
10056         local file0=$DIR/$tfile.0
10057         local file1=$DIR/$tfile.1
10058         local xattr0=$TMP/$tfile.0
10059         local xattr1=$TMP/$tfile.1
10060         local namelist="lov lma lmv link fid version som hsm"
10061         local name
10062         local value
10063
10064         rm -rf $file0 $file1 $xattr0 $xattr1
10065         touch $file0 $file1
10066
10067         # Get 'before' xattrs of $file1.
10068         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10069
10070         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10071                 namelist+=" lfsck_namespace"
10072         for name in $namelist; do
10073                 # Try to copy xattr from $file0 to $file1.
10074                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10075
10076                 setfattr --name=trusted.$name --value="$value" $file1 ||
10077                         error "setxattr 'trusted.$name' failed"
10078
10079                 # Try to set a garbage xattr.
10080                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10081
10082                 if [[ x$name == "xlov" ]]; then
10083                         setfattr --name=trusted.lov --value="$value" $file1 &&
10084                         error "setxattr invalid 'trusted.lov' success"
10085                 else
10086                         setfattr --name=trusted.$name --value="$value" $file1 ||
10087                                 error "setxattr invalid 'trusted.$name' failed"
10088                 fi
10089
10090                 # Try to remove the xattr from $file1. We don't care if this
10091                 # appears to succeed or fail, we just don't want there to be
10092                 # any changes or crashes.
10093                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10094         done
10095
10096         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10097         then
10098                 name="lfsck_ns"
10099                 # Try to copy xattr from $file0 to $file1.
10100                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10101
10102                 setfattr --name=trusted.$name --value="$value" $file1 ||
10103                         error "setxattr 'trusted.$name' failed"
10104
10105                 # Try to set a garbage xattr.
10106                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10107
10108                 setfattr --name=trusted.$name --value="$value" $file1 ||
10109                         error "setxattr 'trusted.$name' failed"
10110
10111                 # Try to remove the xattr from $file1. We don't care if this
10112                 # appears to succeed or fail, we just don't want there to be
10113                 # any changes or crashes.
10114                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10115         fi
10116
10117         # Get 'after' xattrs of file1.
10118         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10119
10120         if ! diff $xattr0 $xattr1; then
10121                 error "before and after xattrs of '$file1' differ"
10122         fi
10123
10124         rm -rf $file0 $file1 $xattr0 $xattr1
10125
10126         return 0
10127 }
10128 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10129
10130 test_102p() { # LU-4703 setxattr did not check ownership
10131         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10132                 skip "MDS needs to be at least 2.5.56"
10133
10134         local testfile=$DIR/$tfile
10135
10136         touch $testfile
10137
10138         echo "setfacl as user..."
10139         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10140         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10141
10142         echo "setfattr as user..."
10143         setfacl -m "u:$RUNAS_ID:---" $testfile
10144         $RUNAS setfattr -x system.posix_acl_access $testfile
10145         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10146 }
10147 run_test 102p "check setxattr(2) correctly fails without permission"
10148
10149 test_102q() {
10150         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10151                 skip "MDS needs to be at least 2.6.92"
10152
10153         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10154 }
10155 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10156
10157 test_102r() {
10158         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10159                 skip "MDS needs to be at least 2.6.93"
10160
10161         touch $DIR/$tfile || error "touch"
10162         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10163         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10164         rm $DIR/$tfile || error "rm"
10165
10166         #normal directory
10167         mkdir -p $DIR/$tdir || error "mkdir"
10168         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10169         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10170         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10171                 error "$testfile error deleting user.author1"
10172         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10173                 grep "user.$(basename $tdir)" &&
10174                 error "$tdir did not delete user.$(basename $tdir)"
10175         rmdir $DIR/$tdir || error "rmdir"
10176
10177         #striped directory
10178         test_mkdir $DIR/$tdir
10179         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10180         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10181         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10182                 error "$testfile error deleting user.author1"
10183         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10184                 grep "user.$(basename $tdir)" &&
10185                 error "$tdir did not delete user.$(basename $tdir)"
10186         rmdir $DIR/$tdir || error "rm striped dir"
10187 }
10188 run_test 102r "set EAs with empty values"
10189
10190 test_102s() {
10191         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10192                 skip "MDS needs to be at least 2.11.52"
10193
10194         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10195
10196         save_lustre_params client "llite.*.xattr_cache" > $save
10197
10198         for cache in 0 1; do
10199                 lctl set_param llite.*.xattr_cache=$cache
10200
10201                 rm -f $DIR/$tfile
10202                 touch $DIR/$tfile || error "touch"
10203                 for prefix in lustre security system trusted user; do
10204                         # Note getxattr() may fail with 'Operation not
10205                         # supported' or 'No such attribute' depending
10206                         # on prefix and cache.
10207                         getfattr -n $prefix.n102s $DIR/$tfile &&
10208                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10209                 done
10210         done
10211
10212         restore_lustre_params < $save
10213 }
10214 run_test 102s "getting nonexistent xattrs should fail"
10215
10216 test_102t() {
10217         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10218                 skip "MDS needs to be at least 2.11.52"
10219
10220         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10221
10222         save_lustre_params client "llite.*.xattr_cache" > $save
10223
10224         for cache in 0 1; do
10225                 lctl set_param llite.*.xattr_cache=$cache
10226
10227                 for buf_size in 0 256; do
10228                         rm -f $DIR/$tfile
10229                         touch $DIR/$tfile || error "touch"
10230                         setfattr -n user.multiop $DIR/$tfile
10231                         $MULTIOP $DIR/$tfile oa$buf_size ||
10232                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10233                 done
10234         done
10235
10236         restore_lustre_params < $save
10237 }
10238 run_test 102t "zero length xattr values handled correctly"
10239
10240 run_acl_subtest()
10241 {
10242     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10243     return $?
10244 }
10245
10246 test_103a() {
10247         [ "$UID" != 0 ] && skip "must run as root"
10248         $GSS && skip_env "could not run under gss"
10249         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10250                 skip_env "must have acl enabled"
10251         [ -z "$(which setfacl 2>/dev/null)" ] &&
10252                 skip_env "could not find setfacl"
10253         remote_mds_nodsh && skip "remote MDS with nodsh"
10254
10255         gpasswd -a daemon bin                           # LU-5641
10256         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10257
10258         declare -a identity_old
10259
10260         for num in $(seq $MDSCOUNT); do
10261                 switch_identity $num true || identity_old[$num]=$?
10262         done
10263
10264         SAVE_UMASK=$(umask)
10265         umask 0022
10266         mkdir -p $DIR/$tdir
10267         cd $DIR/$tdir
10268
10269         echo "performing cp ..."
10270         run_acl_subtest cp || error "run_acl_subtest cp failed"
10271         echo "performing getfacl-noacl..."
10272         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10273         echo "performing misc..."
10274         run_acl_subtest misc || error  "misc test failed"
10275         echo "performing permissions..."
10276         run_acl_subtest permissions || error "permissions failed"
10277         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10278         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10279                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10280                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10281         then
10282                 echo "performing permissions xattr..."
10283                 run_acl_subtest permissions_xattr ||
10284                         error "permissions_xattr failed"
10285         fi
10286         echo "performing setfacl..."
10287         run_acl_subtest setfacl || error  "setfacl test failed"
10288
10289         # inheritance test got from HP
10290         echo "performing inheritance..."
10291         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10292         chmod +x make-tree || error "chmod +x failed"
10293         run_acl_subtest inheritance || error "inheritance test failed"
10294         rm -f make-tree
10295
10296         echo "LU-974 ignore umask when acl is enabled..."
10297         run_acl_subtest 974 || error "LU-974 umask test failed"
10298         if [ $MDSCOUNT -ge 2 ]; then
10299                 run_acl_subtest 974_remote ||
10300                         error "LU-974 umask test failed under remote dir"
10301         fi
10302
10303         echo "LU-2561 newly created file is same size as directory..."
10304         if [ "$mds1_FSTYPE" != "zfs" ]; then
10305                 run_acl_subtest 2561 || error "LU-2561 test failed"
10306         else
10307                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10308         fi
10309
10310         run_acl_subtest 4924 || error "LU-4924 test failed"
10311
10312         cd $SAVE_PWD
10313         umask $SAVE_UMASK
10314
10315         for num in $(seq $MDSCOUNT); do
10316                 if [ "${identity_old[$num]}" = 1 ]; then
10317                         switch_identity $num false || identity_old[$num]=$?
10318                 fi
10319         done
10320 }
10321 run_test 103a "acl test"
10322
10323 test_103b() {
10324         declare -a pids
10325         local U
10326
10327         for U in {0..511}; do
10328                 {
10329                 local O=$(printf "%04o" $U)
10330
10331                 umask $(printf "%04o" $((511 ^ $O)))
10332                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10333                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10334
10335                 (( $S == ($O & 0666) )) ||
10336                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10337
10338                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10339                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10340                 (( $S == ($O & 0666) )) ||
10341                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10342
10343                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10344                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10345                 (( $S == ($O & 0666) )) ||
10346                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10347                 rm -f $DIR/$tfile.[smp]$0
10348                 } &
10349                 local pid=$!
10350
10351                 # limit the concurrently running threads to 64. LU-11878
10352                 local idx=$((U % 64))
10353                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10354                 pids[idx]=$pid
10355         done
10356         wait
10357 }
10358 run_test 103b "umask lfs setstripe"
10359
10360 test_103c() {
10361         mkdir -p $DIR/$tdir
10362         cp -rp $DIR/$tdir $DIR/$tdir.bak
10363
10364         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10365                 error "$DIR/$tdir shouldn't contain default ACL"
10366         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10367                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10368         true
10369 }
10370 run_test 103c "'cp -rp' won't set empty acl"
10371
10372 test_104a() {
10373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10374
10375         touch $DIR/$tfile
10376         lfs df || error "lfs df failed"
10377         lfs df -ih || error "lfs df -ih failed"
10378         lfs df -h $DIR || error "lfs df -h $DIR failed"
10379         lfs df -i $DIR || error "lfs df -i $DIR failed"
10380         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10381         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10382
10383         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10384         lctl --device %$OSC deactivate
10385         lfs df || error "lfs df with deactivated OSC failed"
10386         lctl --device %$OSC activate
10387         # wait the osc back to normal
10388         wait_osc_import_ready client ost
10389
10390         lfs df || error "lfs df with reactivated OSC failed"
10391         rm -f $DIR/$tfile
10392 }
10393 run_test 104a "lfs df [-ih] [path] test ========================="
10394
10395 test_104b() {
10396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10397         [ $RUNAS_ID -eq $UID ] &&
10398                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10399
10400         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10401                         grep "Permission denied" | wc -l)))
10402         if [ $denied_cnt -ne 0 ]; then
10403                 error "lfs check servers test failed"
10404         fi
10405 }
10406 run_test 104b "$RUNAS lfs check servers test ===================="
10407
10408 test_105a() {
10409         # doesn't work on 2.4 kernels
10410         touch $DIR/$tfile
10411         if $(flock_is_enabled); then
10412                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10413         else
10414                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10415         fi
10416         rm -f $DIR/$tfile
10417 }
10418 run_test 105a "flock when mounted without -o flock test ========"
10419
10420 test_105b() {
10421         touch $DIR/$tfile
10422         if $(flock_is_enabled); then
10423                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10424         else
10425                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10426         fi
10427         rm -f $DIR/$tfile
10428 }
10429 run_test 105b "fcntl when mounted without -o flock test ========"
10430
10431 test_105c() {
10432         touch $DIR/$tfile
10433         if $(flock_is_enabled); then
10434                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10435         else
10436                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10437         fi
10438         rm -f $DIR/$tfile
10439 }
10440 run_test 105c "lockf when mounted without -o flock test"
10441
10442 test_105d() { # bug 15924
10443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10444
10445         test_mkdir $DIR/$tdir
10446         flock_is_enabled || skip_env "mount w/o flock enabled"
10447         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10448         $LCTL set_param fail_loc=0x80000315
10449         flocks_test 2 $DIR/$tdir
10450 }
10451 run_test 105d "flock race (should not freeze) ========"
10452
10453 test_105e() { # bug 22660 && 22040
10454         flock_is_enabled || skip_env "mount w/o flock enabled"
10455
10456         touch $DIR/$tfile
10457         flocks_test 3 $DIR/$tfile
10458 }
10459 run_test 105e "Two conflicting flocks from same process"
10460
10461 test_106() { #bug 10921
10462         test_mkdir $DIR/$tdir
10463         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10464         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10465 }
10466 run_test 106 "attempt exec of dir followed by chown of that dir"
10467
10468 test_107() {
10469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10470
10471         CDIR=`pwd`
10472         local file=core
10473
10474         cd $DIR
10475         rm -f $file
10476
10477         local save_pattern=$(sysctl -n kernel.core_pattern)
10478         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10479         sysctl -w kernel.core_pattern=$file
10480         sysctl -w kernel.core_uses_pid=0
10481
10482         ulimit -c unlimited
10483         sleep 60 &
10484         SLEEPPID=$!
10485
10486         sleep 1
10487
10488         kill -s 11 $SLEEPPID
10489         wait $SLEEPPID
10490         if [ -e $file ]; then
10491                 size=`stat -c%s $file`
10492                 [ $size -eq 0 ] && error "Fail to create core file $file"
10493         else
10494                 error "Fail to create core file $file"
10495         fi
10496         rm -f $file
10497         sysctl -w kernel.core_pattern=$save_pattern
10498         sysctl -w kernel.core_uses_pid=$save_uses_pid
10499         cd $CDIR
10500 }
10501 run_test 107 "Coredump on SIG"
10502
10503 test_110() {
10504         test_mkdir $DIR/$tdir
10505         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10506         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10507                 error "mkdir with 256 char should fail, but did not"
10508         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10509                 error "create with 255 char failed"
10510         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10511                 error "create with 256 char should fail, but did not"
10512
10513         ls -l $DIR/$tdir
10514         rm -rf $DIR/$tdir
10515 }
10516 run_test 110 "filename length checking"
10517
10518 #
10519 # Purpose: To verify dynamic thread (OSS) creation.
10520 #
10521 test_115() {
10522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10523         remote_ost_nodsh && skip "remote OST with nodsh"
10524
10525         # Lustre does not stop service threads once they are started.
10526         # Reset number of running threads to default.
10527         stopall
10528         setupall
10529
10530         local OSTIO_pre
10531         local save_params="$TMP/sanity-$TESTNAME.parameters"
10532
10533         # Get ll_ost_io count before I/O
10534         OSTIO_pre=$(do_facet ost1 \
10535                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10536         # Exit if lustre is not running (ll_ost_io not running).
10537         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10538
10539         echo "Starting with $OSTIO_pre threads"
10540         local thread_max=$((OSTIO_pre * 2))
10541         local rpc_in_flight=$((thread_max * 2))
10542         # Number of I/O Process proposed to be started.
10543         local nfiles
10544         local facets=$(get_facets OST)
10545
10546         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10547         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10548
10549         # Set in_flight to $rpc_in_flight
10550         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10551                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10552         nfiles=${rpc_in_flight}
10553         # Set ost thread_max to $thread_max
10554         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10555
10556         # 5 Minutes should be sufficient for max number of OSS
10557         # threads(thread_max) to be created.
10558         local timeout=300
10559
10560         # Start I/O.
10561         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10562         test_mkdir $DIR/$tdir
10563         for i in $(seq $nfiles); do
10564                 local file=$DIR/$tdir/${tfile}-$i
10565                 $LFS setstripe -c -1 -i 0 $file
10566                 ($WTL $file $timeout)&
10567         done
10568
10569         # I/O Started - Wait for thread_started to reach thread_max or report
10570         # error if thread_started is more than thread_max.
10571         echo "Waiting for thread_started to reach thread_max"
10572         local thread_started=0
10573         local end_time=$((SECONDS + timeout))
10574
10575         while [ $SECONDS -le $end_time ] ; do
10576                 echo -n "."
10577                 # Get ost i/o thread_started count.
10578                 thread_started=$(do_facet ost1 \
10579                         "$LCTL get_param \
10580                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10581                 # Break out if thread_started is equal/greater than thread_max
10582                 if [[ $thread_started -ge $thread_max ]]; then
10583                         echo ll_ost_io thread_started $thread_started, \
10584                                 equal/greater than thread_max $thread_max
10585                         break
10586                 fi
10587                 sleep 1
10588         done
10589
10590         # Cleanup - We have the numbers, Kill i/o jobs if running.
10591         jobcount=($(jobs -p))
10592         for i in $(seq 0 $((${#jobcount[@]}-1)))
10593         do
10594                 kill -9 ${jobcount[$i]}
10595                 if [ $? -ne 0 ] ; then
10596                         echo Warning: \
10597                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10598                 fi
10599         done
10600
10601         # Cleanup files left by WTL binary.
10602         for i in $(seq $nfiles); do
10603                 local file=$DIR/$tdir/${tfile}-$i
10604                 rm -rf $file
10605                 if [ $? -ne 0 ] ; then
10606                         echo "Warning: Failed to delete file $file"
10607                 fi
10608         done
10609
10610         restore_lustre_params <$save_params
10611         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10612
10613         # Error out if no new thread has started or Thread started is greater
10614         # than thread max.
10615         if [[ $thread_started -le $OSTIO_pre ||
10616                         $thread_started -gt $thread_max ]]; then
10617                 error "ll_ost_io: thread_started $thread_started" \
10618                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10619                       "No new thread started or thread started greater " \
10620                       "than thread_max."
10621         fi
10622 }
10623 run_test 115 "verify dynamic thread creation===================="
10624
10625 free_min_max () {
10626         wait_delete_completed
10627         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10628         echo "OST kbytes available: ${AVAIL[@]}"
10629         MAXV=${AVAIL[0]}
10630         MAXI=0
10631         MINV=${AVAIL[0]}
10632         MINI=0
10633         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10634                 #echo OST $i: ${AVAIL[i]}kb
10635                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10636                         MAXV=${AVAIL[i]}
10637                         MAXI=$i
10638                 fi
10639                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10640                         MINV=${AVAIL[i]}
10641                         MINI=$i
10642                 fi
10643         done
10644         echo "Min free space: OST $MINI: $MINV"
10645         echo "Max free space: OST $MAXI: $MAXV"
10646 }
10647
10648 test_116a() { # was previously test_116()
10649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10650         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10651         remote_mds_nodsh && skip "remote MDS with nodsh"
10652
10653         echo -n "Free space priority "
10654         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10655                 head -n1
10656         declare -a AVAIL
10657         free_min_max
10658
10659         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10660         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10661         trap simple_cleanup_common EXIT
10662
10663         # Check if we need to generate uneven OSTs
10664         test_mkdir -p $DIR/$tdir/OST${MINI}
10665         local FILL=$((MINV / 4))
10666         local DIFF=$((MAXV - MINV))
10667         local DIFF2=$((DIFF * 100 / MINV))
10668
10669         local threshold=$(do_facet $SINGLEMDS \
10670                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10671         threshold=${threshold%%%}
10672         echo -n "Check for uneven OSTs: "
10673         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10674
10675         if [[ $DIFF2 -gt $threshold ]]; then
10676                 echo "ok"
10677                 echo "Don't need to fill OST$MINI"
10678         else
10679                 # generate uneven OSTs. Write 2% over the QOS threshold value
10680                 echo "no"
10681                 DIFF=$((threshold - DIFF2 + 2))
10682                 DIFF2=$((MINV * DIFF / 100))
10683                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10684                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10685                         error "setstripe failed"
10686                 DIFF=$((DIFF2 / 2048))
10687                 i=0
10688                 while [ $i -lt $DIFF ]; do
10689                         i=$((i + 1))
10690                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10691                                 bs=2M count=1 2>/dev/null
10692                         echo -n .
10693                 done
10694                 echo .
10695                 sync
10696                 sleep_maxage
10697                 free_min_max
10698         fi
10699
10700         DIFF=$((MAXV - MINV))
10701         DIFF2=$((DIFF * 100 / MINV))
10702         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10703         if [ $DIFF2 -gt $threshold ]; then
10704                 echo "ok"
10705         else
10706                 echo "failed - QOS mode won't be used"
10707                 simple_cleanup_common
10708                 skip "QOS imbalance criteria not met"
10709         fi
10710
10711         MINI1=$MINI
10712         MINV1=$MINV
10713         MAXI1=$MAXI
10714         MAXV1=$MAXV
10715
10716         # now fill using QOS
10717         $LFS setstripe -c 1 $DIR/$tdir
10718         FILL=$((FILL / 200))
10719         if [ $FILL -gt 600 ]; then
10720                 FILL=600
10721         fi
10722         echo "writing $FILL files to QOS-assigned OSTs"
10723         i=0
10724         while [ $i -lt $FILL ]; do
10725                 i=$((i + 1))
10726                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10727                         count=1 2>/dev/null
10728                 echo -n .
10729         done
10730         echo "wrote $i 200k files"
10731         sync
10732         sleep_maxage
10733
10734         echo "Note: free space may not be updated, so measurements might be off"
10735         free_min_max
10736         DIFF2=$((MAXV - MINV))
10737         echo "free space delta: orig $DIFF final $DIFF2"
10738         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10739         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10740         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10741         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10742         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10743         if [[ $DIFF -gt 0 ]]; then
10744                 FILL=$((DIFF2 * 100 / DIFF - 100))
10745                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10746         fi
10747
10748         # Figure out which files were written where
10749         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10750                awk '/'$MINI1': / {print $2; exit}')
10751         echo $UUID
10752         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10753         echo "$MINC files created on smaller OST $MINI1"
10754         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10755                awk '/'$MAXI1': / {print $2; exit}')
10756         echo $UUID
10757         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10758         echo "$MAXC files created on larger OST $MAXI1"
10759         if [[ $MINC -gt 0 ]]; then
10760                 FILL=$((MAXC * 100 / MINC - 100))
10761                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10762         fi
10763         [[ $MAXC -gt $MINC ]] ||
10764                 error_ignore LU-9 "stripe QOS didn't balance free space"
10765         simple_cleanup_common
10766 }
10767 run_test 116a "stripe QOS: free space balance ==================="
10768
10769 test_116b() { # LU-2093
10770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10771         remote_mds_nodsh && skip "remote MDS with nodsh"
10772
10773 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10774         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10775                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10776         [ -z "$old_rr" ] && skip "no QOS"
10777         do_facet $SINGLEMDS lctl set_param \
10778                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10779         mkdir -p $DIR/$tdir
10780         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10781         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10782         do_facet $SINGLEMDS lctl set_param fail_loc=0
10783         rm -rf $DIR/$tdir
10784         do_facet $SINGLEMDS lctl set_param \
10785                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10786 }
10787 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10788
10789 test_117() # bug 10891
10790 {
10791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10792
10793         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10794         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10795         lctl set_param fail_loc=0x21e
10796         > $DIR/$tfile || error "truncate failed"
10797         lctl set_param fail_loc=0
10798         echo "Truncate succeeded."
10799         rm -f $DIR/$tfile
10800 }
10801 run_test 117 "verify osd extend =========="
10802
10803 NO_SLOW_RESENDCOUNT=4
10804 export OLD_RESENDCOUNT=""
10805 set_resend_count () {
10806         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10807         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10808         lctl set_param -n $PROC_RESENDCOUNT $1
10809         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10810 }
10811
10812 # for reduce test_118* time (b=14842)
10813 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10814
10815 # Reset async IO behavior after error case
10816 reset_async() {
10817         FILE=$DIR/reset_async
10818
10819         # Ensure all OSCs are cleared
10820         $LFS setstripe -c -1 $FILE
10821         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10822         sync
10823         rm $FILE
10824 }
10825
10826 test_118a() #bug 11710
10827 {
10828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10829
10830         reset_async
10831
10832         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10833         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10834         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10835
10836         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10837                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10838                 return 1;
10839         fi
10840         rm -f $DIR/$tfile
10841 }
10842 run_test 118a "verify O_SYNC works =========="
10843
10844 test_118b()
10845 {
10846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10847         remote_ost_nodsh && skip "remote OST with nodsh"
10848
10849         reset_async
10850
10851         #define OBD_FAIL_SRV_ENOENT 0x217
10852         set_nodes_failloc "$(osts_nodes)" 0x217
10853         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10854         RC=$?
10855         set_nodes_failloc "$(osts_nodes)" 0
10856         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10857         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10858                     grep -c writeback)
10859
10860         if [[ $RC -eq 0 ]]; then
10861                 error "Must return error due to dropped pages, rc=$RC"
10862                 return 1;
10863         fi
10864
10865         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10866                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10867                 return 1;
10868         fi
10869
10870         echo "Dirty pages not leaked on ENOENT"
10871
10872         # Due to the above error the OSC will issue all RPCs syncronously
10873         # until a subsequent RPC completes successfully without error.
10874         $MULTIOP $DIR/$tfile Ow4096yc
10875         rm -f $DIR/$tfile
10876
10877         return 0
10878 }
10879 run_test 118b "Reclaim dirty pages on fatal error =========="
10880
10881 test_118c()
10882 {
10883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10884
10885         # for 118c, restore the original resend count, LU-1940
10886         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10887                                 set_resend_count $OLD_RESENDCOUNT
10888         remote_ost_nodsh && skip "remote OST with nodsh"
10889
10890         reset_async
10891
10892         #define OBD_FAIL_OST_EROFS               0x216
10893         set_nodes_failloc "$(osts_nodes)" 0x216
10894
10895         # multiop should block due to fsync until pages are written
10896         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10897         MULTIPID=$!
10898         sleep 1
10899
10900         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10901                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10902         fi
10903
10904         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10905                     grep -c writeback)
10906         if [[ $WRITEBACK -eq 0 ]]; then
10907                 error "No page in writeback, writeback=$WRITEBACK"
10908         fi
10909
10910         set_nodes_failloc "$(osts_nodes)" 0
10911         wait $MULTIPID
10912         RC=$?
10913         if [[ $RC -ne 0 ]]; then
10914                 error "Multiop fsync failed, rc=$RC"
10915         fi
10916
10917         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10918         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10919                     grep -c writeback)
10920         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10921                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10922         fi
10923
10924         rm -f $DIR/$tfile
10925         echo "Dirty pages flushed via fsync on EROFS"
10926         return 0
10927 }
10928 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10929
10930 # continue to use small resend count to reduce test_118* time (b=14842)
10931 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10932
10933 test_118d()
10934 {
10935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10936         remote_ost_nodsh && skip "remote OST with nodsh"
10937
10938         reset_async
10939
10940         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10941         set_nodes_failloc "$(osts_nodes)" 0x214
10942         # multiop should block due to fsync until pages are written
10943         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10944         MULTIPID=$!
10945         sleep 1
10946
10947         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10948                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10949         fi
10950
10951         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10952                     grep -c writeback)
10953         if [[ $WRITEBACK -eq 0 ]]; then
10954                 error "No page in writeback, writeback=$WRITEBACK"
10955         fi
10956
10957         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10958         set_nodes_failloc "$(osts_nodes)" 0
10959
10960         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10961         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10962                     grep -c writeback)
10963         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10964                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10965         fi
10966
10967         rm -f $DIR/$tfile
10968         echo "Dirty pages gaurenteed flushed via fsync"
10969         return 0
10970 }
10971 run_test 118d "Fsync validation inject a delay of the bulk =========="
10972
10973 test_118f() {
10974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10975
10976         reset_async
10977
10978         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10979         lctl set_param fail_loc=0x8000040a
10980
10981         # Should simulate EINVAL error which is fatal
10982         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10983         RC=$?
10984         if [[ $RC -eq 0 ]]; then
10985                 error "Must return error due to dropped pages, rc=$RC"
10986         fi
10987
10988         lctl set_param fail_loc=0x0
10989
10990         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
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 [[ $LOCKED -ne 0 ]]; then
10995                 error "Locked pages remain in cache, locked=$LOCKED"
10996         fi
10997
10998         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10999                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11000         fi
11001
11002         rm -f $DIR/$tfile
11003         echo "No pages locked after fsync"
11004
11005         reset_async
11006         return 0
11007 }
11008 run_test 118f "Simulate unrecoverable OSC side error =========="
11009
11010 test_118g() {
11011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11012
11013         reset_async
11014
11015         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11016         lctl set_param fail_loc=0x406
11017
11018         # simulate local -ENOMEM
11019         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11020         RC=$?
11021
11022         lctl set_param fail_loc=0
11023         if [[ $RC -eq 0 ]]; then
11024                 error "Must return error due to dropped pages, rc=$RC"
11025         fi
11026
11027         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11028         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11029         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11030                         grep -c writeback)
11031         if [[ $LOCKED -ne 0 ]]; then
11032                 error "Locked pages remain in cache, locked=$LOCKED"
11033         fi
11034
11035         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11036                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11037         fi
11038
11039         rm -f $DIR/$tfile
11040         echo "No pages locked after fsync"
11041
11042         reset_async
11043         return 0
11044 }
11045 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11046
11047 test_118h() {
11048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11049         remote_ost_nodsh && skip "remote OST with nodsh"
11050
11051         reset_async
11052
11053         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11054         set_nodes_failloc "$(osts_nodes)" 0x20e
11055         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11056         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11057         RC=$?
11058
11059         set_nodes_failloc "$(osts_nodes)" 0
11060         if [[ $RC -eq 0 ]]; then
11061                 error "Must return error due to dropped pages, rc=$RC"
11062         fi
11063
11064         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11065         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11066         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11067                     grep -c writeback)
11068         if [[ $LOCKED -ne 0 ]]; then
11069                 error "Locked pages remain in cache, locked=$LOCKED"
11070         fi
11071
11072         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11073                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11074         fi
11075
11076         rm -f $DIR/$tfile
11077         echo "No pages locked after fsync"
11078
11079         return 0
11080 }
11081 run_test 118h "Verify timeout in handling recoverables errors  =========="
11082
11083 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11084
11085 test_118i() {
11086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11087         remote_ost_nodsh && skip "remote OST with nodsh"
11088
11089         reset_async
11090
11091         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11092         set_nodes_failloc "$(osts_nodes)" 0x20e
11093
11094         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11095         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11096         PID=$!
11097         sleep 5
11098         set_nodes_failloc "$(osts_nodes)" 0
11099
11100         wait $PID
11101         RC=$?
11102         if [[ $RC -ne 0 ]]; then
11103                 error "got error, but should be not, rc=$RC"
11104         fi
11105
11106         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11107         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11108         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11109         if [[ $LOCKED -ne 0 ]]; then
11110                 error "Locked pages remain in cache, locked=$LOCKED"
11111         fi
11112
11113         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11114                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11115         fi
11116
11117         rm -f $DIR/$tfile
11118         echo "No pages locked after fsync"
11119
11120         return 0
11121 }
11122 run_test 118i "Fix error before timeout in recoverable error  =========="
11123
11124 [ "$SLOW" = "no" ] && set_resend_count 4
11125
11126 test_118j() {
11127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11128         remote_ost_nodsh && skip "remote OST with nodsh"
11129
11130         reset_async
11131
11132         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11133         set_nodes_failloc "$(osts_nodes)" 0x220
11134
11135         # return -EIO from OST
11136         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11137         RC=$?
11138         set_nodes_failloc "$(osts_nodes)" 0x0
11139         if [[ $RC -eq 0 ]]; then
11140                 error "Must return error due to dropped pages, rc=$RC"
11141         fi
11142
11143         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11144         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11145         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11146         if [[ $LOCKED -ne 0 ]]; then
11147                 error "Locked pages remain in cache, locked=$LOCKED"
11148         fi
11149
11150         # in recoverable error on OST we want resend and stay until it finished
11151         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11152                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11153         fi
11154
11155         rm -f $DIR/$tfile
11156         echo "No pages locked after fsync"
11157
11158         return 0
11159 }
11160 run_test 118j "Simulate unrecoverable OST side error =========="
11161
11162 test_118k()
11163 {
11164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11165         remote_ost_nodsh && skip "remote OSTs with nodsh"
11166
11167         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11168         set_nodes_failloc "$(osts_nodes)" 0x20e
11169         test_mkdir $DIR/$tdir
11170
11171         for ((i=0;i<10;i++)); do
11172                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11173                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11174                 SLEEPPID=$!
11175                 sleep 0.500s
11176                 kill $SLEEPPID
11177                 wait $SLEEPPID
11178         done
11179
11180         set_nodes_failloc "$(osts_nodes)" 0
11181         rm -rf $DIR/$tdir
11182 }
11183 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11184
11185 test_118l() # LU-646
11186 {
11187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11188
11189         test_mkdir $DIR/$tdir
11190         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11191         rm -rf $DIR/$tdir
11192 }
11193 run_test 118l "fsync dir"
11194
11195 test_118m() # LU-3066
11196 {
11197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11198
11199         test_mkdir $DIR/$tdir
11200         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11201         rm -rf $DIR/$tdir
11202 }
11203 run_test 118m "fdatasync dir ========="
11204
11205 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11206
11207 test_118n()
11208 {
11209         local begin
11210         local end
11211
11212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11213         remote_ost_nodsh && skip "remote OSTs with nodsh"
11214
11215         # Sleep to avoid a cached response.
11216         #define OBD_STATFS_CACHE_SECONDS 1
11217         sleep 2
11218
11219         # Inject a 10 second delay in the OST_STATFS handler.
11220         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11221         set_nodes_failloc "$(osts_nodes)" 0x242
11222
11223         begin=$SECONDS
11224         stat --file-system $MOUNT > /dev/null
11225         end=$SECONDS
11226
11227         set_nodes_failloc "$(osts_nodes)" 0
11228
11229         if ((end - begin > 20)); then
11230             error "statfs took $((end - begin)) seconds, expected 10"
11231         fi
11232 }
11233 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11234
11235 test_119a() # bug 11737
11236 {
11237         BSIZE=$((512 * 1024))
11238         directio write $DIR/$tfile 0 1 $BSIZE
11239         # We ask to read two blocks, which is more than a file size.
11240         # directio will indicate an error when requested and actual
11241         # sizes aren't equeal (a normal situation in this case) and
11242         # print actual read amount.
11243         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11244         if [ "$NOB" != "$BSIZE" ]; then
11245                 error "read $NOB bytes instead of $BSIZE"
11246         fi
11247         rm -f $DIR/$tfile
11248 }
11249 run_test 119a "Short directIO read must return actual read amount"
11250
11251 test_119b() # bug 11737
11252 {
11253         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11254
11255         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11256         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11257         sync
11258         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11259                 error "direct read failed"
11260         rm -f $DIR/$tfile
11261 }
11262 run_test 119b "Sparse directIO read must return actual read amount"
11263
11264 test_119c() # bug 13099
11265 {
11266         BSIZE=1048576
11267         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11268         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11269         rm -f $DIR/$tfile
11270 }
11271 run_test 119c "Testing for direct read hitting hole"
11272
11273 test_119d() # bug 15950
11274 {
11275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11276
11277         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11278         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11279         BSIZE=1048576
11280         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11281         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11282         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11283         lctl set_param fail_loc=0x40d
11284         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11285         pid_dio=$!
11286         sleep 1
11287         cat $DIR/$tfile > /dev/null &
11288         lctl set_param fail_loc=0
11289         pid_reads=$!
11290         wait $pid_dio
11291         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11292         sleep 2
11293         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11294         error "the read rpcs have not completed in 2s"
11295         rm -f $DIR/$tfile
11296         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11297 }
11298 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11299
11300 test_120a() {
11301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11302         remote_mds_nodsh && skip "remote MDS with nodsh"
11303         test_mkdir -i0 -c1 $DIR/$tdir
11304         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11305                 skip_env "no early lock cancel on server"
11306
11307         lru_resize_disable mdc
11308         lru_resize_disable osc
11309         cancel_lru_locks mdc
11310         # asynchronous object destroy at MDT could cause bl ast to client
11311         cancel_lru_locks osc
11312
11313         stat $DIR/$tdir > /dev/null
11314         can1=$(do_facet mds1 \
11315                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11316                awk '/ldlm_cancel/ {print $2}')
11317         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11318                awk '/ldlm_bl_callback/ {print $2}')
11319         test_mkdir -i0 -c1 $DIR/$tdir/d1
11320         can2=$(do_facet mds1 \
11321                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11322                awk '/ldlm_cancel/ {print $2}')
11323         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11324                awk '/ldlm_bl_callback/ {print $2}')
11325         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11326         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11327         lru_resize_enable mdc
11328         lru_resize_enable osc
11329 }
11330 run_test 120a "Early Lock Cancel: mkdir test"
11331
11332 test_120b() {
11333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11334         remote_mds_nodsh && skip "remote MDS with nodsh"
11335         test_mkdir $DIR/$tdir
11336         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11337                 skip_env "no early lock cancel on server"
11338
11339         lru_resize_disable mdc
11340         lru_resize_disable osc
11341         cancel_lru_locks mdc
11342         stat $DIR/$tdir > /dev/null
11343         can1=$(do_facet $SINGLEMDS \
11344                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11345                awk '/ldlm_cancel/ {print $2}')
11346         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11347                awk '/ldlm_bl_callback/ {print $2}')
11348         touch $DIR/$tdir/f1
11349         can2=$(do_facet $SINGLEMDS \
11350                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11351                awk '/ldlm_cancel/ {print $2}')
11352         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11353                awk '/ldlm_bl_callback/ {print $2}')
11354         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11355         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11356         lru_resize_enable mdc
11357         lru_resize_enable osc
11358 }
11359 run_test 120b "Early Lock Cancel: create test"
11360
11361 test_120c() {
11362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11363         remote_mds_nodsh && skip "remote MDS with nodsh"
11364         test_mkdir -i0 -c1 $DIR/$tdir
11365         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11366                 skip "no early lock cancel on server"
11367
11368         lru_resize_disable mdc
11369         lru_resize_disable osc
11370         test_mkdir -i0 -c1 $DIR/$tdir/d1
11371         test_mkdir -i0 -c1 $DIR/$tdir/d2
11372         touch $DIR/$tdir/d1/f1
11373         cancel_lru_locks mdc
11374         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11375         can1=$(do_facet mds1 \
11376                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11377                awk '/ldlm_cancel/ {print $2}')
11378         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11379                awk '/ldlm_bl_callback/ {print $2}')
11380         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11381         can2=$(do_facet mds1 \
11382                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11383                awk '/ldlm_cancel/ {print $2}')
11384         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11385                awk '/ldlm_bl_callback/ {print $2}')
11386         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11387         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11388         lru_resize_enable mdc
11389         lru_resize_enable osc
11390 }
11391 run_test 120c "Early Lock Cancel: link test"
11392
11393 test_120d() {
11394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11395         remote_mds_nodsh && skip "remote MDS with nodsh"
11396         test_mkdir -i0 -c1 $DIR/$tdir
11397         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11398                 skip_env "no early lock cancel on server"
11399
11400         lru_resize_disable mdc
11401         lru_resize_disable osc
11402         touch $DIR/$tdir
11403         cancel_lru_locks mdc
11404         stat $DIR/$tdir > /dev/null
11405         can1=$(do_facet mds1 \
11406                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11407                awk '/ldlm_cancel/ {print $2}')
11408         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11409                awk '/ldlm_bl_callback/ {print $2}')
11410         chmod a+x $DIR/$tdir
11411         can2=$(do_facet mds1 \
11412                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11413                awk '/ldlm_cancel/ {print $2}')
11414         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11415                awk '/ldlm_bl_callback/ {print $2}')
11416         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11417         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11418         lru_resize_enable mdc
11419         lru_resize_enable osc
11420 }
11421 run_test 120d "Early Lock Cancel: setattr test"
11422
11423 test_120e() {
11424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11425         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11426                 skip_env "no early lock cancel on server"
11427         remote_mds_nodsh && skip "remote MDS with nodsh"
11428
11429         local dlmtrace_set=false
11430
11431         test_mkdir -i0 -c1 $DIR/$tdir
11432         lru_resize_disable mdc
11433         lru_resize_disable osc
11434         ! $LCTL get_param debug | grep -q dlmtrace &&
11435                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11436         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11437         cancel_lru_locks mdc
11438         cancel_lru_locks osc
11439         dd if=$DIR/$tdir/f1 of=/dev/null
11440         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11441         # XXX client can not do early lock cancel of OST lock
11442         # during unlink (LU-4206), so cancel osc lock now.
11443         sleep 2
11444         cancel_lru_locks osc
11445         can1=$(do_facet mds1 \
11446                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11447                awk '/ldlm_cancel/ {print $2}')
11448         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11449                awk '/ldlm_bl_callback/ {print $2}')
11450         unlink $DIR/$tdir/f1
11451         sleep 5
11452         can2=$(do_facet mds1 \
11453                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11454                awk '/ldlm_cancel/ {print $2}')
11455         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11456                awk '/ldlm_bl_callback/ {print $2}')
11457         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11458                 $LCTL dk $TMP/cancel.debug.txt
11459         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11460                 $LCTL dk $TMP/blocking.debug.txt
11461         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11462         lru_resize_enable mdc
11463         lru_resize_enable osc
11464 }
11465 run_test 120e "Early Lock Cancel: unlink test"
11466
11467 test_120f() {
11468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11469         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11470                 skip_env "no early lock cancel on server"
11471         remote_mds_nodsh && skip "remote MDS with nodsh"
11472
11473         test_mkdir -i0 -c1 $DIR/$tdir
11474         lru_resize_disable mdc
11475         lru_resize_disable osc
11476         test_mkdir -i0 -c1 $DIR/$tdir/d1
11477         test_mkdir -i0 -c1 $DIR/$tdir/d2
11478         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11479         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11480         cancel_lru_locks mdc
11481         cancel_lru_locks osc
11482         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11483         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11484         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11485         # XXX client can not do early lock cancel of OST lock
11486         # during rename (LU-4206), so cancel osc lock now.
11487         sleep 2
11488         cancel_lru_locks osc
11489         can1=$(do_facet mds1 \
11490                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11491                awk '/ldlm_cancel/ {print $2}')
11492         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11493                awk '/ldlm_bl_callback/ {print $2}')
11494         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11495         sleep 5
11496         can2=$(do_facet mds1 \
11497                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11498                awk '/ldlm_cancel/ {print $2}')
11499         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11500                awk '/ldlm_bl_callback/ {print $2}')
11501         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11502         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11503         lru_resize_enable mdc
11504         lru_resize_enable osc
11505 }
11506 run_test 120f "Early Lock Cancel: rename test"
11507
11508 test_120g() {
11509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11510         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11511                 skip_env "no early lock cancel on server"
11512         remote_mds_nodsh && skip "remote MDS with nodsh"
11513
11514         lru_resize_disable mdc
11515         lru_resize_disable osc
11516         count=10000
11517         echo create $count files
11518         test_mkdir $DIR/$tdir
11519         cancel_lru_locks mdc
11520         cancel_lru_locks osc
11521         t0=$(date +%s)
11522
11523         can0=$(do_facet $SINGLEMDS \
11524                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11525                awk '/ldlm_cancel/ {print $2}')
11526         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11527                awk '/ldlm_bl_callback/ {print $2}')
11528         createmany -o $DIR/$tdir/f $count
11529         sync
11530         can1=$(do_facet $SINGLEMDS \
11531                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11532                awk '/ldlm_cancel/ {print $2}')
11533         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11534                awk '/ldlm_bl_callback/ {print $2}')
11535         t1=$(date +%s)
11536         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11537         echo rm $count files
11538         rm -r $DIR/$tdir
11539         sync
11540         can2=$(do_facet $SINGLEMDS \
11541                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11542                awk '/ldlm_cancel/ {print $2}')
11543         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11544                awk '/ldlm_bl_callback/ {print $2}')
11545         t2=$(date +%s)
11546         echo total: $count removes in $((t2-t1))
11547         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11548         sleep 2
11549         # wait for commitment of removal
11550         lru_resize_enable mdc
11551         lru_resize_enable osc
11552 }
11553 run_test 120g "Early Lock Cancel: performance test"
11554
11555 test_121() { #bug #10589
11556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11557
11558         rm -rf $DIR/$tfile
11559         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11560 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11561         lctl set_param fail_loc=0x310
11562         cancel_lru_locks osc > /dev/null
11563         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11564         lctl set_param fail_loc=0
11565         [[ $reads -eq $writes ]] ||
11566                 error "read $reads blocks, must be $writes blocks"
11567 }
11568 run_test 121 "read cancel race ========="
11569
11570 test_123a_base() { # was test 123, statahead(bug 11401)
11571         local lsx="$1"
11572
11573         SLOWOK=0
11574         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11575                 log "testing UP system. Performance may be lower than expected."
11576                 SLOWOK=1
11577         fi
11578
11579         rm -rf $DIR/$tdir
11580         test_mkdir $DIR/$tdir
11581         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11582         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11583         MULT=10
11584         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11585                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11586
11587                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11588                 lctl set_param -n llite.*.statahead_max 0
11589                 lctl get_param llite.*.statahead_max
11590                 cancel_lru_locks mdc
11591                 cancel_lru_locks osc
11592                 stime=$(date +%s)
11593                 time $lsx $DIR/$tdir | wc -l
11594                 etime=$(date +%s)
11595                 delta=$((etime - stime))
11596                 log "$lsx $i files without statahead: $delta sec"
11597                 lctl set_param llite.*.statahead_max=$max
11598
11599                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11600                         grep "statahead wrong:" | awk '{print $3}')
11601                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11602                 cancel_lru_locks mdc
11603                 cancel_lru_locks osc
11604                 stime=$(date +%s)
11605                 time $lsx $DIR/$tdir | wc -l
11606                 etime=$(date +%s)
11607                 delta_sa=$((etime - stime))
11608                 log "$lsx $i files with statahead: $delta_sa sec"
11609                 lctl get_param -n llite.*.statahead_stats
11610                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11611                         grep "statahead wrong:" | awk '{print $3}')
11612
11613                 [[ $swrong -lt $ewrong ]] &&
11614                         log "statahead was stopped, maybe too many locks held!"
11615                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11616
11617                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11618                         max=$(lctl get_param -n llite.*.statahead_max |
11619                                 head -n 1)
11620                         lctl set_param -n llite.*.statahead_max 0
11621                         lctl get_param llite.*.statahead_max
11622                         cancel_lru_locks mdc
11623                         cancel_lru_locks osc
11624                         stime=$(date +%s)
11625                         time $lsx $DIR/$tdir | wc -l
11626                         etime=$(date +%s)
11627                         delta=$((etime - stime))
11628                         log "$lsx $i files again without statahead: $delta sec"
11629                         lctl set_param llite.*.statahead_max=$max
11630                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11631                                 if [  $SLOWOK -eq 0 ]; then
11632                                         error "$lsx $i files is slower with statahead!"
11633                                 else
11634                                         log "$lsx $i files is slower with statahead!"
11635                                 fi
11636                                 break
11637                         fi
11638                 fi
11639
11640                 [ $delta -gt 20 ] && break
11641                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11642                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11643         done
11644         log "$lsx done"
11645
11646         stime=$(date +%s)
11647         rm -r $DIR/$tdir
11648         sync
11649         etime=$(date +%s)
11650         delta=$((etime - stime))
11651         log "rm -r $DIR/$tdir/: $delta seconds"
11652         log "rm done"
11653         lctl get_param -n llite.*.statahead_stats
11654 }
11655
11656 test_123aa() {
11657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11658
11659         test_123a_base "ls -l"
11660 }
11661 run_test 123aa "verify statahead work"
11662
11663 test_123ab() {
11664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11665
11666         statx_supported || skip_env "Test must be statx() syscall supported"
11667
11668         test_123a_base "$STATX -l"
11669 }
11670 run_test 123ab "verify statahead work by using statx"
11671
11672 test_123ac() {
11673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11674
11675         statx_supported || skip_env "Test must be statx() syscall supported"
11676
11677         local rpcs_before
11678         local rpcs_after
11679         local agl_before
11680         local agl_after
11681
11682         cancel_lru_locks $OSC
11683         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11684         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11685                 awk '/agl.total:/ {print $3}')
11686         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11687         test_123a_base "$STATX --cached=always -D"
11688         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11689                 awk '/agl.total:/ {print $3}')
11690         [ $agl_before -eq $agl_after ] ||
11691                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11692         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11693         [ $rpcs_after -eq $rpcs_before ] ||
11694                 error "$STATX should not send glimpse RPCs to $OSC"
11695 }
11696 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11697
11698 test_123b () { # statahead(bug 15027)
11699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11700
11701         test_mkdir $DIR/$tdir
11702         createmany -o $DIR/$tdir/$tfile-%d 1000
11703
11704         cancel_lru_locks mdc
11705         cancel_lru_locks osc
11706
11707 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11708         lctl set_param fail_loc=0x80000803
11709         ls -lR $DIR/$tdir > /dev/null
11710         log "ls done"
11711         lctl set_param fail_loc=0x0
11712         lctl get_param -n llite.*.statahead_stats
11713         rm -r $DIR/$tdir
11714         sync
11715
11716 }
11717 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11718
11719 test_123c() {
11720         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11721
11722         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11723         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11724         touch $DIR/$tdir.1/{1..3}
11725         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11726
11727         remount_client $MOUNT
11728
11729         $MULTIOP $DIR/$tdir.0 Q
11730
11731         # let statahead to complete
11732         ls -l $DIR/$tdir.0 > /dev/null
11733
11734         testid=$(echo $TESTNAME | tr '_' ' ')
11735         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11736                 error "statahead warning" || true
11737 }
11738 run_test 123c "Can not initialize inode warning on DNE statahead"
11739
11740 test_124a() {
11741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11742         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11743                 skip_env "no lru resize on server"
11744
11745         local NR=2000
11746
11747         test_mkdir $DIR/$tdir
11748
11749         log "create $NR files at $DIR/$tdir"
11750         createmany -o $DIR/$tdir/f $NR ||
11751                 error "failed to create $NR files in $DIR/$tdir"
11752
11753         cancel_lru_locks mdc
11754         ls -l $DIR/$tdir > /dev/null
11755
11756         local NSDIR=""
11757         local LRU_SIZE=0
11758         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11759                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11760                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11761                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11762                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11763                         log "NSDIR=$NSDIR"
11764                         log "NS=$(basename $NSDIR)"
11765                         break
11766                 fi
11767         done
11768
11769         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11770                 skip "Not enough cached locks created!"
11771         fi
11772         log "LRU=$LRU_SIZE"
11773
11774         local SLEEP=30
11775
11776         # We know that lru resize allows one client to hold $LIMIT locks
11777         # for 10h. After that locks begin to be killed by client.
11778         local MAX_HRS=10
11779         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11780         log "LIMIT=$LIMIT"
11781         if [ $LIMIT -lt $LRU_SIZE ]; then
11782                 skip "Limit is too small $LIMIT"
11783         fi
11784
11785         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11786         # killing locks. Some time was spent for creating locks. This means
11787         # that up to the moment of sleep finish we must have killed some of
11788         # them (10-100 locks). This depends on how fast ther were created.
11789         # Many of them were touched in almost the same moment and thus will
11790         # be killed in groups.
11791         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11792
11793         # Use $LRU_SIZE_B here to take into account real number of locks
11794         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11795         local LRU_SIZE_B=$LRU_SIZE
11796         log "LVF=$LVF"
11797         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11798         log "OLD_LVF=$OLD_LVF"
11799         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11800
11801         # Let's make sure that we really have some margin. Client checks
11802         # cached locks every 10 sec.
11803         SLEEP=$((SLEEP+20))
11804         log "Sleep ${SLEEP} sec"
11805         local SEC=0
11806         while ((SEC<$SLEEP)); do
11807                 echo -n "..."
11808                 sleep 5
11809                 SEC=$((SEC+5))
11810                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11811                 echo -n "$LRU_SIZE"
11812         done
11813         echo ""
11814         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11815         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11816
11817         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11818                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11819                 unlinkmany $DIR/$tdir/f $NR
11820                 return
11821         }
11822
11823         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11824         log "unlink $NR files at $DIR/$tdir"
11825         unlinkmany $DIR/$tdir/f $NR
11826 }
11827 run_test 124a "lru resize ======================================="
11828
11829 get_max_pool_limit()
11830 {
11831         local limit=$($LCTL get_param \
11832                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11833         local max=0
11834         for l in $limit; do
11835                 if [[ $l -gt $max ]]; then
11836                         max=$l
11837                 fi
11838         done
11839         echo $max
11840 }
11841
11842 test_124b() {
11843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11844         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11845                 skip_env "no lru resize on server"
11846
11847         LIMIT=$(get_max_pool_limit)
11848
11849         NR=$(($(default_lru_size)*20))
11850         if [[ $NR -gt $LIMIT ]]; then
11851                 log "Limit lock number by $LIMIT locks"
11852                 NR=$LIMIT
11853         fi
11854
11855         IFree=$(mdsrate_inodes_available)
11856         if [ $IFree -lt $NR ]; then
11857                 log "Limit lock number by $IFree inodes"
11858                 NR=$IFree
11859         fi
11860
11861         lru_resize_disable mdc
11862         test_mkdir -p $DIR/$tdir/disable_lru_resize
11863
11864         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11865         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11866         cancel_lru_locks mdc
11867         stime=`date +%s`
11868         PID=""
11869         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11870         PID="$PID $!"
11871         sleep 2
11872         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11873         PID="$PID $!"
11874         sleep 2
11875         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11876         PID="$PID $!"
11877         wait $PID
11878         etime=`date +%s`
11879         nolruresize_delta=$((etime-stime))
11880         log "ls -la time: $nolruresize_delta seconds"
11881         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11882         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11883
11884         lru_resize_enable mdc
11885         test_mkdir -p $DIR/$tdir/enable_lru_resize
11886
11887         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11888         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11889         cancel_lru_locks mdc
11890         stime=`date +%s`
11891         PID=""
11892         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11893         PID="$PID $!"
11894         sleep 2
11895         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11896         PID="$PID $!"
11897         sleep 2
11898         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11899         PID="$PID $!"
11900         wait $PID
11901         etime=`date +%s`
11902         lruresize_delta=$((etime-stime))
11903         log "ls -la time: $lruresize_delta seconds"
11904         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11905
11906         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11907                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11908         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11909                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11910         else
11911                 log "lru resize performs the same with no lru resize"
11912         fi
11913         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11914 }
11915 run_test 124b "lru resize (performance test) ======================="
11916
11917 test_124c() {
11918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11919         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11920                 skip_env "no lru resize on server"
11921
11922         # cache ununsed locks on client
11923         local nr=100
11924         cancel_lru_locks mdc
11925         test_mkdir $DIR/$tdir
11926         createmany -o $DIR/$tdir/f $nr ||
11927                 error "failed to create $nr files in $DIR/$tdir"
11928         ls -l $DIR/$tdir > /dev/null
11929
11930         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11931         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11932         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11933         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11934         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11935
11936         # set lru_max_age to 1 sec
11937         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11938         echo "sleep $((recalc_p * 2)) seconds..."
11939         sleep $((recalc_p * 2))
11940
11941         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11942         # restore lru_max_age
11943         $LCTL set_param -n $nsdir.lru_max_age $max_age
11944         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11945         unlinkmany $DIR/$tdir/f $nr
11946 }
11947 run_test 124c "LRUR cancel very aged locks"
11948
11949 test_124d() {
11950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11951         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11952                 skip_env "no lru resize on server"
11953
11954         # cache ununsed locks on client
11955         local nr=100
11956
11957         lru_resize_disable mdc
11958         stack_trap "lru_resize_enable mdc" EXIT
11959
11960         cancel_lru_locks mdc
11961
11962         # asynchronous object destroy at MDT could cause bl ast to client
11963         test_mkdir $DIR/$tdir
11964         createmany -o $DIR/$tdir/f $nr ||
11965                 error "failed to create $nr files in $DIR/$tdir"
11966         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11967
11968         ls -l $DIR/$tdir > /dev/null
11969
11970         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11971         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11972         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11973         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11974
11975         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11976
11977         # set lru_max_age to 1 sec
11978         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11979         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
11980
11981         echo "sleep $((recalc_p * 2)) seconds..."
11982         sleep $((recalc_p * 2))
11983
11984         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11985
11986         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11987 }
11988 run_test 124d "cancel very aged locks if lru-resize diasbaled"
11989
11990 test_125() { # 13358
11991         $LCTL get_param -n llite.*.client_type | grep -q local ||
11992                 skip "must run as local client"
11993         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
11994                 skip_env "must have acl enabled"
11995         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11996
11997         test_mkdir $DIR/$tdir
11998         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
11999         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12000         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12001 }
12002 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12003
12004 test_126() { # bug 12829/13455
12005         $GSS && skip_env "must run as gss disabled"
12006         $LCTL get_param -n llite.*.client_type | grep -q local ||
12007                 skip "must run as local client"
12008         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12009
12010         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12011         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12012         rm -f $DIR/$tfile
12013         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12014 }
12015 run_test 126 "check that the fsgid provided by the client is taken into account"
12016
12017 test_127a() { # bug 15521
12018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12019         local name count samp unit min max sum sumsq
12020
12021         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12022         echo "stats before reset"
12023         $LCTL get_param osc.*.stats
12024         $LCTL set_param osc.*.stats=0
12025         local fsize=$((2048 * 1024))
12026
12027         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12028         cancel_lru_locks osc
12029         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12030
12031         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12032         stack_trap "rm -f $TMP/$tfile.tmp"
12033         while read name count samp unit min max sum sumsq; do
12034                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12035                 [ ! $min ] && error "Missing min value for $name proc entry"
12036                 eval $name=$count || error "Wrong proc format"
12037
12038                 case $name in
12039                 read_bytes|write_bytes)
12040                         [[ "$unit" =~ "bytes" ]] ||
12041                                 error "unit is not 'bytes': $unit"
12042                         (( $min >= 4096 )) || error "min is too small: $min"
12043                         (( $min <= $fsize )) || error "min is too big: $min"
12044                         (( $max >= 4096 )) || error "max is too small: $max"
12045                         (( $max <= $fsize )) || error "max is too big: $max"
12046                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12047                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12048                                 error "sumsquare is too small: $sumsq"
12049                         (( $sumsq <= $fsize * $fsize )) ||
12050                                 error "sumsquare is too big: $sumsq"
12051                         ;;
12052                 ost_read|ost_write)
12053                         [[ "$unit" =~ "usec" ]] ||
12054                                 error "unit is not 'usec': $unit"
12055                         ;;
12056                 *)      ;;
12057                 esac
12058         done < $DIR/$tfile.tmp
12059
12060         #check that we actually got some stats
12061         [ "$read_bytes" ] || error "Missing read_bytes stats"
12062         [ "$write_bytes" ] || error "Missing write_bytes stats"
12063         [ "$read_bytes" != 0 ] || error "no read done"
12064         [ "$write_bytes" != 0 ] || error "no write done"
12065 }
12066 run_test 127a "verify the client stats are sane"
12067
12068 test_127b() { # bug LU-333
12069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12070         local name count samp unit min max sum sumsq
12071
12072         echo "stats before reset"
12073         $LCTL get_param llite.*.stats
12074         $LCTL set_param llite.*.stats=0
12075
12076         # perform 2 reads and writes so MAX is different from SUM.
12077         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12078         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12079         cancel_lru_locks osc
12080         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12081         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12082
12083         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12084         stack_trap "rm -f $TMP/$tfile.tmp"
12085         while read name count samp unit min max sum sumsq; do
12086                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12087                 eval $name=$count || error "Wrong proc format"
12088
12089                 case $name in
12090                 read_bytes|write_bytes)
12091                         [[ "$unit" =~ "bytes" ]] ||
12092                                 error "unit is not 'bytes': $unit"
12093                         (( $count == 2 )) || error "count is not 2: $count"
12094                         (( $min == $PAGE_SIZE )) ||
12095                                 error "min is not $PAGE_SIZE: $min"
12096                         (( $max == $PAGE_SIZE )) ||
12097                                 error "max is not $PAGE_SIZE: $max"
12098                         (( $sum == $PAGE_SIZE * 2 )) ||
12099                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12100                         ;;
12101                 read|write)
12102                         [[ "$unit" =~ "usec" ]] ||
12103                                 error "unit is not 'usec': $unit"
12104                         ;;
12105                 *)      ;;
12106                 esac
12107         done < $TMP/$tfile.tmp
12108
12109         #check that we actually got some stats
12110         [ "$read_bytes" ] || error "Missing read_bytes stats"
12111         [ "$write_bytes" ] || error "Missing write_bytes stats"
12112         [ "$read_bytes" != 0 ] || error "no read done"
12113         [ "$write_bytes" != 0 ] || error "no write done"
12114 }
12115 run_test 127b "verify the llite client stats are sane"
12116
12117 test_127c() { # LU-12394
12118         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12119         local size
12120         local bsize
12121         local reads
12122         local writes
12123         local count
12124
12125         $LCTL set_param llite.*.extents_stats=1
12126         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12127
12128         # Use two stripes so there is enough space in default config
12129         $LFS setstripe -c 2 $DIR/$tfile
12130
12131         # Extent stats start at 0-4K and go in power of two buckets
12132         # LL_HIST_START = 12 --> 2^12 = 4K
12133         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12134         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12135         # small configs
12136         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12137                 do
12138                 # Write and read, 2x each, second time at a non-zero offset
12139                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12140                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12141                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12142                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12143                 rm -f $DIR/$tfile
12144         done
12145
12146         $LCTL get_param llite.*.extents_stats
12147
12148         count=2
12149         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12150                 do
12151                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12152                                 grep -m 1 $bsize)
12153                 reads=$(echo $bucket | awk '{print $5}')
12154                 writes=$(echo $bucket | awk '{print $9}')
12155                 [ "$reads" -eq $count ] ||
12156                         error "$reads reads in < $bsize bucket, expect $count"
12157                 [ "$writes" -eq $count ] ||
12158                         error "$writes writes in < $bsize bucket, expect $count"
12159         done
12160
12161         # Test mmap write and read
12162         $LCTL set_param llite.*.extents_stats=c
12163         size=512
12164         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12165         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12166         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12167
12168         $LCTL get_param llite.*.extents_stats
12169
12170         count=$(((size*1024) / PAGE_SIZE))
12171
12172         bsize=$((2 * PAGE_SIZE / 1024))K
12173
12174         bucket=$($LCTL get_param -n llite.*.extents_stats |
12175                         grep -m 1 $bsize)
12176         reads=$(echo $bucket | awk '{print $5}')
12177         writes=$(echo $bucket | awk '{print $9}')
12178         # mmap writes fault in the page first, creating an additonal read
12179         [ "$reads" -eq $((2 * count)) ] ||
12180                 error "$reads reads in < $bsize bucket, expect $count"
12181         [ "$writes" -eq $count ] ||
12182                 error "$writes writes in < $bsize bucket, expect $count"
12183 }
12184 run_test 127c "test llite extent stats with regular & mmap i/o"
12185
12186 test_128() { # bug 15212
12187         touch $DIR/$tfile
12188         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12189                 find $DIR/$tfile
12190                 find $DIR/$tfile
12191         EOF
12192
12193         result=$(grep error $TMP/$tfile.log)
12194         rm -f $DIR/$tfile $TMP/$tfile.log
12195         [ -z "$result" ] ||
12196                 error "consecutive find's under interactive lfs failed"
12197 }
12198 run_test 128 "interactive lfs for 2 consecutive find's"
12199
12200 set_dir_limits () {
12201         local mntdev
12202         local canondev
12203         local node
12204
12205         local ldproc=/proc/fs/ldiskfs
12206         local facets=$(get_facets MDS)
12207
12208         for facet in ${facets//,/ }; do
12209                 canondev=$(ldiskfs_canon \
12210                            *.$(convert_facet2label $facet).mntdev $facet)
12211                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12212                         ldproc=/sys/fs/ldiskfs
12213                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12214                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12215         done
12216 }
12217
12218 check_mds_dmesg() {
12219         local facets=$(get_facets MDS)
12220         for facet in ${facets//,/ }; do
12221                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12222         done
12223         return 1
12224 }
12225
12226 test_129() {
12227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12228         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12229                 skip "Need MDS version with at least 2.5.56"
12230         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12231                 skip_env "ldiskfs only test"
12232         fi
12233         remote_mds_nodsh && skip "remote MDS with nodsh"
12234
12235         local ENOSPC=28
12236         local has_warning=false
12237
12238         rm -rf $DIR/$tdir
12239         mkdir -p $DIR/$tdir
12240
12241         # block size of mds1
12242         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12243         set_dir_limits $maxsize $((maxsize * 6 / 8))
12244         stack_trap "set_dir_limits 0 0"
12245         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12246         local dirsize=$(stat -c%s "$DIR/$tdir")
12247         local nfiles=0
12248         while (( $dirsize <= $maxsize )); do
12249                 $MCREATE $DIR/$tdir/file_base_$nfiles
12250                 rc=$?
12251                 # check two errors:
12252                 # ENOSPC for ext4 max_dir_size, which has been used since
12253                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12254                 if (( rc == ENOSPC )); then
12255                         set_dir_limits 0 0
12256                         echo "rc=$rc returned as expected after $nfiles files"
12257
12258                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12259                                 error "create failed w/o dir size limit"
12260
12261                         # messages may be rate limited if test is run repeatedly
12262                         check_mds_dmesg '"is approaching max"' ||
12263                                 echo "warning message should be output"
12264                         check_mds_dmesg '"has reached max"' ||
12265                                 echo "reached message should be output"
12266
12267                         dirsize=$(stat -c%s "$DIR/$tdir")
12268
12269                         [[ $dirsize -ge $maxsize ]] && return 0
12270                         error "dirsize $dirsize < $maxsize after $nfiles files"
12271                 elif (( rc != 0 )); then
12272                         break
12273                 fi
12274                 nfiles=$((nfiles + 1))
12275                 dirsize=$(stat -c%s "$DIR/$tdir")
12276         done
12277
12278         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12279 }
12280 run_test 129 "test directory size limit ========================"
12281
12282 OLDIFS="$IFS"
12283 cleanup_130() {
12284         trap 0
12285         IFS="$OLDIFS"
12286 }
12287
12288 test_130a() {
12289         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12290         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12291
12292         trap cleanup_130 EXIT RETURN
12293
12294         local fm_file=$DIR/$tfile
12295         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12296         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12297                 error "dd failed for $fm_file"
12298
12299         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12300         filefrag -ves $fm_file
12301         RC=$?
12302         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12303                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12304         [ $RC != 0 ] && error "filefrag $fm_file failed"
12305
12306         filefrag_op=$(filefrag -ve -k $fm_file |
12307                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12308         lun=$($LFS getstripe -i $fm_file)
12309
12310         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12311         IFS=$'\n'
12312         tot_len=0
12313         for line in $filefrag_op
12314         do
12315                 frag_lun=`echo $line | cut -d: -f5`
12316                 ext_len=`echo $line | cut -d: -f4`
12317                 if (( $frag_lun != $lun )); then
12318                         cleanup_130
12319                         error "FIEMAP on 1-stripe file($fm_file) failed"
12320                         return
12321                 fi
12322                 (( tot_len += ext_len ))
12323         done
12324
12325         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12326                 cleanup_130
12327                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12328                 return
12329         fi
12330
12331         cleanup_130
12332
12333         echo "FIEMAP on single striped file succeeded"
12334 }
12335 run_test 130a "FIEMAP (1-stripe file)"
12336
12337 test_130b() {
12338         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12339
12340         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12341         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12342
12343         trap cleanup_130 EXIT RETURN
12344
12345         local fm_file=$DIR/$tfile
12346         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12347                         error "setstripe on $fm_file"
12348         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12349                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12350
12351         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12352                 error "dd failed on $fm_file"
12353
12354         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12355         filefrag_op=$(filefrag -ve -k $fm_file |
12356                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12357
12358         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12359                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12360
12361         IFS=$'\n'
12362         tot_len=0
12363         num_luns=1
12364         for line in $filefrag_op
12365         do
12366                 frag_lun=$(echo $line | cut -d: -f5 |
12367                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12368                 ext_len=$(echo $line | cut -d: -f4)
12369                 if (( $frag_lun != $last_lun )); then
12370                         if (( tot_len != 1024 )); then
12371                                 cleanup_130
12372                                 error "FIEMAP on $fm_file failed; returned " \
12373                                 "len $tot_len for OST $last_lun instead of 1024"
12374                                 return
12375                         else
12376                                 (( num_luns += 1 ))
12377                                 tot_len=0
12378                         fi
12379                 fi
12380                 (( tot_len += ext_len ))
12381                 last_lun=$frag_lun
12382         done
12383         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12384                 cleanup_130
12385                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12386                         "luns or wrong len for OST $last_lun"
12387                 return
12388         fi
12389
12390         cleanup_130
12391
12392         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12393 }
12394 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12395
12396 test_130c() {
12397         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12398
12399         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12400         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12401
12402         trap cleanup_130 EXIT RETURN
12403
12404         local fm_file=$DIR/$tfile
12405         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12406         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12407                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12408
12409         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12410                         error "dd failed on $fm_file"
12411
12412         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12413         filefrag_op=$(filefrag -ve -k $fm_file |
12414                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12415
12416         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12417                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12418
12419         IFS=$'\n'
12420         tot_len=0
12421         num_luns=1
12422         for line in $filefrag_op
12423         do
12424                 frag_lun=$(echo $line | cut -d: -f5 |
12425                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12426                 ext_len=$(echo $line | cut -d: -f4)
12427                 if (( $frag_lun != $last_lun )); then
12428                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12429                         if (( logical != 512 )); then
12430                                 cleanup_130
12431                                 error "FIEMAP on $fm_file failed; returned " \
12432                                 "logical start for lun $logical instead of 512"
12433                                 return
12434                         fi
12435                         if (( tot_len != 512 )); then
12436                                 cleanup_130
12437                                 error "FIEMAP on $fm_file failed; returned " \
12438                                 "len $tot_len for OST $last_lun instead of 1024"
12439                                 return
12440                         else
12441                                 (( num_luns += 1 ))
12442                                 tot_len=0
12443                         fi
12444                 fi
12445                 (( tot_len += ext_len ))
12446                 last_lun=$frag_lun
12447         done
12448         if (( num_luns != 2 || tot_len != 512 )); then
12449                 cleanup_130
12450                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12451                         "luns or wrong len for OST $last_lun"
12452                 return
12453         fi
12454
12455         cleanup_130
12456
12457         echo "FIEMAP on 2-stripe file with hole succeeded"
12458 }
12459 run_test 130c "FIEMAP (2-stripe file with hole)"
12460
12461 test_130d() {
12462         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12463
12464         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12465         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12466
12467         trap cleanup_130 EXIT RETURN
12468
12469         local fm_file=$DIR/$tfile
12470         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12471                         error "setstripe on $fm_file"
12472         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12473                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12474
12475         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12476         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12477                 error "dd failed on $fm_file"
12478
12479         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12480         filefrag_op=$(filefrag -ve -k $fm_file |
12481                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12482
12483         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12484                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12485
12486         IFS=$'\n'
12487         tot_len=0
12488         num_luns=1
12489         for line in $filefrag_op
12490         do
12491                 frag_lun=$(echo $line | cut -d: -f5 |
12492                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12493                 ext_len=$(echo $line | cut -d: -f4)
12494                 if (( $frag_lun != $last_lun )); then
12495                         if (( tot_len != 1024 )); then
12496                                 cleanup_130
12497                                 error "FIEMAP on $fm_file failed; returned " \
12498                                 "len $tot_len for OST $last_lun instead of 1024"
12499                                 return
12500                         else
12501                                 (( num_luns += 1 ))
12502                                 tot_len=0
12503                         fi
12504                 fi
12505                 (( tot_len += ext_len ))
12506                 last_lun=$frag_lun
12507         done
12508         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12509                 cleanup_130
12510                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12511                         "luns or wrong len for OST $last_lun"
12512                 return
12513         fi
12514
12515         cleanup_130
12516
12517         echo "FIEMAP on N-stripe file succeeded"
12518 }
12519 run_test 130d "FIEMAP (N-stripe file)"
12520
12521 test_130e() {
12522         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12523
12524         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12525         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12526
12527         trap cleanup_130 EXIT RETURN
12528
12529         local fm_file=$DIR/$tfile
12530         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12531         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12532                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12533
12534         NUM_BLKS=512
12535         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12536         for ((i = 0; i < $NUM_BLKS; i++))
12537         do
12538                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12539         done
12540
12541         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12542         filefrag_op=$(filefrag -ve -k $fm_file |
12543                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12544
12545         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12546                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12547
12548         IFS=$'\n'
12549         tot_len=0
12550         num_luns=1
12551         for line in $filefrag_op
12552         do
12553                 frag_lun=$(echo $line | cut -d: -f5 |
12554                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12555                 ext_len=$(echo $line | cut -d: -f4)
12556                 if (( $frag_lun != $last_lun )); then
12557                         if (( tot_len != $EXPECTED_LEN )); then
12558                                 cleanup_130
12559                                 error "FIEMAP on $fm_file failed; returned " \
12560                                 "len $tot_len for OST $last_lun instead " \
12561                                 "of $EXPECTED_LEN"
12562                                 return
12563                         else
12564                                 (( num_luns += 1 ))
12565                                 tot_len=0
12566                         fi
12567                 fi
12568                 (( tot_len += ext_len ))
12569                 last_lun=$frag_lun
12570         done
12571         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12572                 cleanup_130
12573                 error "FIEMAP on $fm_file failed; returned wrong number " \
12574                         "of luns or wrong len for OST $last_lun"
12575                 return
12576         fi
12577
12578         cleanup_130
12579
12580         echo "FIEMAP with continuation calls succeeded"
12581 }
12582 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12583
12584 test_130f() {
12585         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12586         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12587
12588         local fm_file=$DIR/$tfile
12589         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12590                 error "multiop create with lov_delay_create on $fm_file"
12591
12592         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12593         filefrag_extents=$(filefrag -vek $fm_file |
12594                            awk '/extents? found/ { print $2 }')
12595         if [[ "$filefrag_extents" != "0" ]]; then
12596                 error "FIEMAP on $fm_file failed; " \
12597                       "returned $filefrag_extents expected 0"
12598         fi
12599
12600         rm -f $fm_file
12601 }
12602 run_test 130f "FIEMAP (unstriped file)"
12603
12604 # Test for writev/readv
12605 test_131a() {
12606         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12607                 error "writev test failed"
12608         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12609                 error "readv failed"
12610         rm -f $DIR/$tfile
12611 }
12612 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12613
12614 test_131b() {
12615         local fsize=$((524288 + 1048576 + 1572864))
12616         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12617                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12618                         error "append writev test failed"
12619
12620         ((fsize += 1572864 + 1048576))
12621         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12622                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12623                         error "append writev test failed"
12624         rm -f $DIR/$tfile
12625 }
12626 run_test 131b "test append writev"
12627
12628 test_131c() {
12629         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12630         error "NOT PASS"
12631 }
12632 run_test 131c "test read/write on file w/o objects"
12633
12634 test_131d() {
12635         rwv -f $DIR/$tfile -w -n 1 1572864
12636         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12637         if [ "$NOB" != 1572864 ]; then
12638                 error "Short read filed: read $NOB bytes instead of 1572864"
12639         fi
12640         rm -f $DIR/$tfile
12641 }
12642 run_test 131d "test short read"
12643
12644 test_131e() {
12645         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12646         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12647         error "read hitting hole failed"
12648         rm -f $DIR/$tfile
12649 }
12650 run_test 131e "test read hitting hole"
12651
12652 check_stats() {
12653         local facet=$1
12654         local op=$2
12655         local want=${3:-0}
12656         local res
12657
12658         case $facet in
12659         mds*) res=$(do_facet $facet \
12660                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12661                  ;;
12662         ost*) res=$(do_facet $facet \
12663                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12664                  ;;
12665         *) error "Wrong facet '$facet'" ;;
12666         esac
12667         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12668         # if the argument $3 is zero, it means any stat increment is ok.
12669         if [[ $want -gt 0 ]]; then
12670                 local count=$(echo $res | awk '{ print $2 }')
12671                 [[ $count -ne $want ]] &&
12672                         error "The $op counter on $facet is $count, not $want"
12673         fi
12674 }
12675
12676 test_133a() {
12677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12678         remote_ost_nodsh && skip "remote OST with nodsh"
12679         remote_mds_nodsh && skip "remote MDS with nodsh"
12680         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12681                 skip_env "MDS doesn't support rename stats"
12682
12683         local testdir=$DIR/${tdir}/stats_testdir
12684
12685         mkdir -p $DIR/${tdir}
12686
12687         # clear stats.
12688         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12689         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12690
12691         # verify mdt stats first.
12692         mkdir ${testdir} || error "mkdir failed"
12693         check_stats $SINGLEMDS "mkdir" 1
12694         touch ${testdir}/${tfile} || error "touch failed"
12695         check_stats $SINGLEMDS "open" 1
12696         check_stats $SINGLEMDS "close" 1
12697         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12698                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12699                 check_stats $SINGLEMDS "mknod" 2
12700         }
12701         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12702         check_stats $SINGLEMDS "unlink" 1
12703         rm -f ${testdir}/${tfile} || error "file remove failed"
12704         check_stats $SINGLEMDS "unlink" 2
12705
12706         # remove working dir and check mdt stats again.
12707         rmdir ${testdir} || error "rmdir failed"
12708         check_stats $SINGLEMDS "rmdir" 1
12709
12710         local testdir1=$DIR/${tdir}/stats_testdir1
12711         mkdir -p ${testdir}
12712         mkdir -p ${testdir1}
12713         touch ${testdir1}/test1
12714         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12715         check_stats $SINGLEMDS "crossdir_rename" 1
12716
12717         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12718         check_stats $SINGLEMDS "samedir_rename" 1
12719
12720         rm -rf $DIR/${tdir}
12721 }
12722 run_test 133a "Verifying MDT stats ========================================"
12723
12724 test_133b() {
12725         local res
12726
12727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12728         remote_ost_nodsh && skip "remote OST with nodsh"
12729         remote_mds_nodsh && skip "remote MDS with nodsh"
12730
12731         local testdir=$DIR/${tdir}/stats_testdir
12732
12733         mkdir -p ${testdir} || error "mkdir failed"
12734         touch ${testdir}/${tfile} || error "touch failed"
12735         cancel_lru_locks mdc
12736
12737         # clear stats.
12738         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12739         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12740
12741         # extra mdt stats verification.
12742         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12743         check_stats $SINGLEMDS "setattr" 1
12744         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12745         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12746         then            # LU-1740
12747                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12748                 check_stats $SINGLEMDS "getattr" 1
12749         fi
12750         rm -rf $DIR/${tdir}
12751
12752         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12753         # so the check below is not reliable
12754         [ $MDSCOUNT -eq 1 ] || return 0
12755
12756         # Sleep to avoid a cached response.
12757         #define OBD_STATFS_CACHE_SECONDS 1
12758         sleep 2
12759         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12760         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12761         $LFS df || error "lfs failed"
12762         check_stats $SINGLEMDS "statfs" 1
12763
12764         # check aggregated statfs (LU-10018)
12765         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12766                 return 0
12767         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12768                 return 0
12769         sleep 2
12770         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12771         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12772         df $DIR
12773         check_stats $SINGLEMDS "statfs" 1
12774
12775         # We want to check that the client didn't send OST_STATFS to
12776         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12777         # extra care is needed here.
12778         if remote_mds; then
12779                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12780                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12781
12782                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12783                 [ "$res" ] && error "OST got STATFS"
12784         fi
12785
12786         return 0
12787 }
12788 run_test 133b "Verifying extra MDT stats =================================="
12789
12790 test_133c() {
12791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12792         remote_ost_nodsh && skip "remote OST with nodsh"
12793         remote_mds_nodsh && skip "remote MDS with nodsh"
12794
12795         local testdir=$DIR/$tdir/stats_testdir
12796
12797         test_mkdir -p $testdir
12798
12799         # verify obdfilter stats.
12800         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12801         sync
12802         cancel_lru_locks osc
12803         wait_delete_completed
12804
12805         # clear stats.
12806         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12807         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12808
12809         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12810                 error "dd failed"
12811         sync
12812         cancel_lru_locks osc
12813         check_stats ost1 "write" 1
12814
12815         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12816         check_stats ost1 "read" 1
12817
12818         > $testdir/$tfile || error "truncate failed"
12819         check_stats ost1 "punch" 1
12820
12821         rm -f $testdir/$tfile || error "file remove failed"
12822         wait_delete_completed
12823         check_stats ost1 "destroy" 1
12824
12825         rm -rf $DIR/$tdir
12826 }
12827 run_test 133c "Verifying OST stats ========================================"
12828
12829 order_2() {
12830         local value=$1
12831         local orig=$value
12832         local order=1
12833
12834         while [ $value -ge 2 ]; do
12835                 order=$((order*2))
12836                 value=$((value/2))
12837         done
12838
12839         if [ $orig -gt $order ]; then
12840                 order=$((order*2))
12841         fi
12842         echo $order
12843 }
12844
12845 size_in_KMGT() {
12846     local value=$1
12847     local size=('K' 'M' 'G' 'T');
12848     local i=0
12849     local size_string=$value
12850
12851     while [ $value -ge 1024 ]; do
12852         if [ $i -gt 3 ]; then
12853             #T is the biggest unit we get here, if that is bigger,
12854             #just return XXXT
12855             size_string=${value}T
12856             break
12857         fi
12858         value=$((value >> 10))
12859         if [ $value -lt 1024 ]; then
12860             size_string=${value}${size[$i]}
12861             break
12862         fi
12863         i=$((i + 1))
12864     done
12865
12866     echo $size_string
12867 }
12868
12869 get_rename_size() {
12870         local size=$1
12871         local context=${2:-.}
12872         local sample=$(do_facet $SINGLEMDS $LCTL \
12873                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12874                 grep -A1 $context |
12875                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12876         echo $sample
12877 }
12878
12879 test_133d() {
12880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12881         remote_ost_nodsh && skip "remote OST with nodsh"
12882         remote_mds_nodsh && skip "remote MDS with nodsh"
12883         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12884                 skip_env "MDS doesn't support rename stats"
12885
12886         local testdir1=$DIR/${tdir}/stats_testdir1
12887         local testdir2=$DIR/${tdir}/stats_testdir2
12888         mkdir -p $DIR/${tdir}
12889
12890         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12891
12892         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12893         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12894
12895         createmany -o $testdir1/test 512 || error "createmany failed"
12896
12897         # check samedir rename size
12898         mv ${testdir1}/test0 ${testdir1}/test_0
12899
12900         local testdir1_size=$(ls -l $DIR/${tdir} |
12901                 awk '/stats_testdir1/ {print $5}')
12902         local testdir2_size=$(ls -l $DIR/${tdir} |
12903                 awk '/stats_testdir2/ {print $5}')
12904
12905         testdir1_size=$(order_2 $testdir1_size)
12906         testdir2_size=$(order_2 $testdir2_size)
12907
12908         testdir1_size=$(size_in_KMGT $testdir1_size)
12909         testdir2_size=$(size_in_KMGT $testdir2_size)
12910
12911         echo "source rename dir size: ${testdir1_size}"
12912         echo "target rename dir size: ${testdir2_size}"
12913
12914         local cmd="do_facet $SINGLEMDS $LCTL "
12915         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12916
12917         eval $cmd || error "$cmd failed"
12918         local samedir=$($cmd | grep 'same_dir')
12919         local same_sample=$(get_rename_size $testdir1_size)
12920         [ -z "$samedir" ] && error "samedir_rename_size count error"
12921         [[ $same_sample -eq 1 ]] ||
12922                 error "samedir_rename_size error $same_sample"
12923         echo "Check same dir rename stats success"
12924
12925         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12926
12927         # check crossdir rename size
12928         mv ${testdir1}/test_0 ${testdir2}/test_0
12929
12930         testdir1_size=$(ls -l $DIR/${tdir} |
12931                 awk '/stats_testdir1/ {print $5}')
12932         testdir2_size=$(ls -l $DIR/${tdir} |
12933                 awk '/stats_testdir2/ {print $5}')
12934
12935         testdir1_size=$(order_2 $testdir1_size)
12936         testdir2_size=$(order_2 $testdir2_size)
12937
12938         testdir1_size=$(size_in_KMGT $testdir1_size)
12939         testdir2_size=$(size_in_KMGT $testdir2_size)
12940
12941         echo "source rename dir size: ${testdir1_size}"
12942         echo "target rename dir size: ${testdir2_size}"
12943
12944         eval $cmd || error "$cmd failed"
12945         local crossdir=$($cmd | grep 'crossdir')
12946         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12947         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12948         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12949         [[ $src_sample -eq 1 ]] ||
12950                 error "crossdir_rename_size error $src_sample"
12951         [[ $tgt_sample -eq 1 ]] ||
12952                 error "crossdir_rename_size error $tgt_sample"
12953         echo "Check cross dir rename stats success"
12954         rm -rf $DIR/${tdir}
12955 }
12956 run_test 133d "Verifying rename_stats ========================================"
12957
12958 test_133e() {
12959         remote_mds_nodsh && skip "remote MDS with nodsh"
12960         remote_ost_nodsh && skip "remote OST with nodsh"
12961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12962
12963         local testdir=$DIR/${tdir}/stats_testdir
12964         local ctr f0 f1 bs=32768 count=42 sum
12965
12966         mkdir -p ${testdir} || error "mkdir failed"
12967
12968         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12969
12970         for ctr in {write,read}_bytes; do
12971                 sync
12972                 cancel_lru_locks osc
12973
12974                 do_facet ost1 $LCTL set_param -n \
12975                         "obdfilter.*.exports.clear=clear"
12976
12977                 if [ $ctr = write_bytes ]; then
12978                         f0=/dev/zero
12979                         f1=${testdir}/${tfile}
12980                 else
12981                         f0=${testdir}/${tfile}
12982                         f1=/dev/null
12983                 fi
12984
12985                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
12986                         error "dd failed"
12987                 sync
12988                 cancel_lru_locks osc
12989
12990                 sum=$(do_facet ost1 $LCTL get_param \
12991                         "obdfilter.*.exports.*.stats" |
12992                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
12993                                 $1 == ctr { sum += $7 }
12994                                 END { printf("%0.0f", sum) }')
12995
12996                 if ((sum != bs * count)); then
12997                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
12998                 fi
12999         done
13000
13001         rm -rf $DIR/${tdir}
13002 }
13003 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13004
13005 test_133f() {
13006         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13007                 skip "too old lustre for get_param -R ($facet_ver)"
13008
13009         # verifying readability.
13010         $LCTL get_param -R '*' &> /dev/null
13011
13012         # Verifing writability with badarea_io.
13013         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13014                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13015                 error "client badarea_io failed"
13016
13017         # remount the FS in case writes/reads /proc break the FS
13018         cleanup || error "failed to unmount"
13019         setup || error "failed to setup"
13020 }
13021 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13022
13023 test_133g() {
13024         remote_mds_nodsh && skip "remote MDS with nodsh"
13025         remote_ost_nodsh && skip "remote OST with nodsh"
13026
13027         local facet
13028         for facet in mds1 ost1; do
13029                 local facet_ver=$(lustre_version_code $facet)
13030                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13031                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13032                 else
13033                         log "$facet: too old lustre for get_param -R"
13034                 fi
13035                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13036                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13037                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13038                                 xargs badarea_io" ||
13039                                         error "$facet badarea_io failed"
13040                 else
13041                         skip_noexit "$facet: too old lustre for get_param -R"
13042                 fi
13043         done
13044
13045         # remount the FS in case writes/reads /proc break the FS
13046         cleanup || error "failed to unmount"
13047         setup || error "failed to setup"
13048 }
13049 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13050
13051 test_133h() {
13052         remote_mds_nodsh && skip "remote MDS with nodsh"
13053         remote_ost_nodsh && skip "remote OST with nodsh"
13054         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13055                 skip "Need MDS version at least 2.9.54"
13056
13057         local facet
13058         for facet in client mds1 ost1; do
13059                 # Get the list of files that are missing the terminating newline
13060                 local plist=$(do_facet $facet
13061                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13062                 local ent
13063                 for ent in $plist; do
13064                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13065                                 awk -v FS='\v' -v RS='\v\v' \
13066                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13067                                         print FILENAME}'" 2>/dev/null)
13068                         [ -z $missing ] || {
13069                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13070                                 error "file does not end with newline: $facet-$ent"
13071                         }
13072                 done
13073         done
13074 }
13075 run_test 133h "Proc files should end with newlines"
13076
13077 test_134a() {
13078         remote_mds_nodsh && skip "remote MDS with nodsh"
13079         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13080                 skip "Need MDS version at least 2.7.54"
13081
13082         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13083         cancel_lru_locks mdc
13084
13085         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13086         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13087         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13088
13089         local nr=1000
13090         createmany -o $DIR/$tdir/f $nr ||
13091                 error "failed to create $nr files in $DIR/$tdir"
13092         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13093
13094         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13095         do_facet mds1 $LCTL set_param fail_loc=0x327
13096         do_facet mds1 $LCTL set_param fail_val=500
13097         touch $DIR/$tdir/m
13098
13099         echo "sleep 10 seconds ..."
13100         sleep 10
13101         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13102
13103         do_facet mds1 $LCTL set_param fail_loc=0
13104         do_facet mds1 $LCTL set_param fail_val=0
13105         [ $lck_cnt -lt $unused ] ||
13106                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13107
13108         rm $DIR/$tdir/m
13109         unlinkmany $DIR/$tdir/f $nr
13110 }
13111 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13112
13113 test_134b() {
13114         remote_mds_nodsh && skip "remote MDS with nodsh"
13115         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13116                 skip "Need MDS version at least 2.7.54"
13117
13118         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13119         cancel_lru_locks mdc
13120
13121         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13122                         ldlm.lock_reclaim_threshold_mb)
13123         # disable reclaim temporarily
13124         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13125
13126         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13127         do_facet mds1 $LCTL set_param fail_loc=0x328
13128         do_facet mds1 $LCTL set_param fail_val=500
13129
13130         $LCTL set_param debug=+trace
13131
13132         local nr=600
13133         createmany -o $DIR/$tdir/f $nr &
13134         local create_pid=$!
13135
13136         echo "Sleep $TIMEOUT seconds ..."
13137         sleep $TIMEOUT
13138         if ! ps -p $create_pid  > /dev/null 2>&1; then
13139                 do_facet mds1 $LCTL set_param fail_loc=0
13140                 do_facet mds1 $LCTL set_param fail_val=0
13141                 do_facet mds1 $LCTL set_param \
13142                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13143                 error "createmany finished incorrectly!"
13144         fi
13145         do_facet mds1 $LCTL set_param fail_loc=0
13146         do_facet mds1 $LCTL set_param fail_val=0
13147         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13148         wait $create_pid || return 1
13149
13150         unlinkmany $DIR/$tdir/f $nr
13151 }
13152 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13153
13154 test_135() {
13155         remote_mds_nodsh && skip "remote MDS with nodsh"
13156         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13157                 skip "Need MDS version at least 2.13.50"
13158         local fname
13159
13160         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13161
13162 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13163         #set only one record at plain llog
13164         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13165
13166         #fill already existed plain llog each 64767
13167         #wrapping whole catalog
13168         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13169
13170         createmany -o $DIR/$tdir/$tfile_ 64700
13171         for (( i = 0; i < 64700; i = i + 2 ))
13172         do
13173                 rm $DIR/$tdir/$tfile_$i &
13174                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13175                 local pid=$!
13176                 wait $pid
13177         done
13178
13179         #waiting osp synchronization
13180         wait_delete_completed
13181 }
13182 run_test 135 "Race catalog processing"
13183
13184 test_136() {
13185         remote_mds_nodsh && skip "remote MDS with nodsh"
13186         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13187                 skip "Need MDS version at least 2.13.50"
13188         local fname
13189
13190         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13191         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13192         #set only one record at plain llog
13193 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13194         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13195
13196         #fill already existed 2 plain llogs each 64767
13197         #wrapping whole catalog
13198         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13199         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13200         wait_delete_completed
13201
13202         createmany -o $DIR/$tdir/$tfile_ 10
13203         sleep 25
13204
13205         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13206         for (( i = 0; i < 10; i = i + 3 ))
13207         do
13208                 rm $DIR/$tdir/$tfile_$i &
13209                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13210                 local pid=$!
13211                 wait $pid
13212                 sleep 7
13213                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13214         done
13215
13216         #waiting osp synchronization
13217         wait_delete_completed
13218 }
13219 run_test 136 "Race catalog processing 2"
13220
13221 test_140() { #bug-17379
13222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13223
13224         test_mkdir $DIR/$tdir
13225         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13226         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13227
13228         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13229         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13230         local i=0
13231         while i=$((i + 1)); do
13232                 test_mkdir $i
13233                 cd $i || error "Changing to $i"
13234                 ln -s ../stat stat || error "Creating stat symlink"
13235                 # Read the symlink until ELOOP present,
13236                 # not LBUGing the system is considered success,
13237                 # we didn't overrun the stack.
13238                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13239                 if [ $ret -ne 0 ]; then
13240                         if [ $ret -eq 40 ]; then
13241                                 break  # -ELOOP
13242                         else
13243                                 error "Open stat symlink"
13244                                         return
13245                         fi
13246                 fi
13247         done
13248         i=$((i - 1))
13249         echo "The symlink depth = $i"
13250         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13251                 error "Invalid symlink depth"
13252
13253         # Test recursive symlink
13254         ln -s symlink_self symlink_self
13255         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13256         echo "open symlink_self returns $ret"
13257         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13258 }
13259 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13260
13261 test_150a() {
13262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13263
13264         local TF="$TMP/$tfile"
13265
13266         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13267         cp $TF $DIR/$tfile
13268         cancel_lru_locks $OSC
13269         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13270         remount_client $MOUNT
13271         df -P $MOUNT
13272         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13273
13274         $TRUNCATE $TF 6000
13275         $TRUNCATE $DIR/$tfile 6000
13276         cancel_lru_locks $OSC
13277         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13278
13279         echo "12345" >>$TF
13280         echo "12345" >>$DIR/$tfile
13281         cancel_lru_locks $OSC
13282         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13283
13284         echo "12345" >>$TF
13285         echo "12345" >>$DIR/$tfile
13286         cancel_lru_locks $OSC
13287         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13288
13289         rm -f $TF
13290         true
13291 }
13292 run_test 150a "truncate/append tests"
13293
13294 test_150b() {
13295         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13296         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13297                 skip "Need OST version at least 2.13.53"
13298         touch $DIR/$tfile
13299         check_fallocate $DIR/$tfile || error "fallocate failed"
13300 }
13301 run_test 150b "Verify fallocate (prealloc) functionality"
13302
13303 test_150c() {
13304         local bytes
13305         local want
13306
13307         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13308         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13309                 skip "Need OST version at least 2.13.53"
13310
13311         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13312         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13313         sync; sync_all_data
13314         cancel_lru_locks $OSC
13315         sleep 5
13316         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13317         want=$((OSTCOUNT * 1048576))
13318
13319         # Must allocate all requested space, not more than 5% extra
13320         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13321                 error "bytes $bytes is not $want"
13322 }
13323 run_test 150c "Verify fallocate Size and Blocks"
13324
13325 test_150d() {
13326         local bytes
13327         local want
13328
13329         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13330         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13331                 skip "Need OST version at least 2.13.53"
13332
13333         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13334         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13335         sync; sync_all_data
13336         cancel_lru_locks $OSC
13337         sleep 5
13338         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13339         want=$((OSTCOUNT * 1048576))
13340
13341         # Must allocate all requested space, not more than 5% extra
13342         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13343                 error "bytes $bytes is not $want"
13344 }
13345 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13346
13347 #LU-2902 roc_hit was not able to read all values from lproc
13348 function roc_hit_init() {
13349         local list=$(comma_list $(osts_nodes))
13350         local dir=$DIR/$tdir-check
13351         local file=$dir/$tfile
13352         local BEFORE
13353         local AFTER
13354         local idx
13355
13356         test_mkdir $dir
13357         #use setstripe to do a write to every ost
13358         for i in $(seq 0 $((OSTCOUNT-1))); do
13359                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13360                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13361                 idx=$(printf %04x $i)
13362                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13363                         awk '$1 == "cache_access" {sum += $7}
13364                                 END { printf("%0.0f", sum) }')
13365
13366                 cancel_lru_locks osc
13367                 cat $file >/dev/null
13368
13369                 AFTER=$(get_osd_param $list *OST*$idx stats |
13370                         awk '$1 == "cache_access" {sum += $7}
13371                                 END { printf("%0.0f", sum) }')
13372
13373                 echo BEFORE:$BEFORE AFTER:$AFTER
13374                 if ! let "AFTER - BEFORE == 4"; then
13375                         rm -rf $dir
13376                         error "roc_hit is not safe to use"
13377                 fi
13378                 rm $file
13379         done
13380
13381         rm -rf $dir
13382 }
13383
13384 function roc_hit() {
13385         local list=$(comma_list $(osts_nodes))
13386         echo $(get_osd_param $list '' stats |
13387                 awk '$1 == "cache_hit" {sum += $7}
13388                         END { printf("%0.0f", sum) }')
13389 }
13390
13391 function set_cache() {
13392         local on=1
13393
13394         if [ "$2" == "off" ]; then
13395                 on=0;
13396         fi
13397         local list=$(comma_list $(osts_nodes))
13398         set_osd_param $list '' $1_cache_enable $on
13399
13400         cancel_lru_locks osc
13401 }
13402
13403 test_151() {
13404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13405         remote_ost_nodsh && skip "remote OST with nodsh"
13406
13407         local CPAGES=3
13408         local list=$(comma_list $(osts_nodes))
13409
13410         # check whether obdfilter is cache capable at all
13411         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13412                 skip "not cache-capable obdfilter"
13413         fi
13414
13415         # check cache is enabled on all obdfilters
13416         if get_osd_param $list '' read_cache_enable | grep 0; then
13417                 skip "oss cache is disabled"
13418         fi
13419
13420         set_osd_param $list '' writethrough_cache_enable 1
13421
13422         # check write cache is enabled on all obdfilters
13423         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13424                 skip "oss write cache is NOT enabled"
13425         fi
13426
13427         roc_hit_init
13428
13429         #define OBD_FAIL_OBD_NO_LRU  0x609
13430         do_nodes $list $LCTL set_param fail_loc=0x609
13431
13432         # pages should be in the case right after write
13433         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13434                 error "dd failed"
13435
13436         local BEFORE=$(roc_hit)
13437         cancel_lru_locks osc
13438         cat $DIR/$tfile >/dev/null
13439         local AFTER=$(roc_hit)
13440
13441         do_nodes $list $LCTL set_param fail_loc=0
13442
13443         if ! let "AFTER - BEFORE == CPAGES"; then
13444                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13445         fi
13446
13447         cancel_lru_locks osc
13448         # invalidates OST cache
13449         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13450         set_osd_param $list '' read_cache_enable 0
13451         cat $DIR/$tfile >/dev/null
13452
13453         # now data shouldn't be found in the cache
13454         BEFORE=$(roc_hit)
13455         cancel_lru_locks osc
13456         cat $DIR/$tfile >/dev/null
13457         AFTER=$(roc_hit)
13458         if let "AFTER - BEFORE != 0"; then
13459                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13460         fi
13461
13462         set_osd_param $list '' read_cache_enable 1
13463         rm -f $DIR/$tfile
13464 }
13465 run_test 151 "test cache on oss and controls ==============================="
13466
13467 test_152() {
13468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13469
13470         local TF="$TMP/$tfile"
13471
13472         # simulate ENOMEM during write
13473 #define OBD_FAIL_OST_NOMEM      0x226
13474         lctl set_param fail_loc=0x80000226
13475         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13476         cp $TF $DIR/$tfile
13477         sync || error "sync failed"
13478         lctl set_param fail_loc=0
13479
13480         # discard client's cache
13481         cancel_lru_locks osc
13482
13483         # simulate ENOMEM during read
13484         lctl set_param fail_loc=0x80000226
13485         cmp $TF $DIR/$tfile || error "cmp failed"
13486         lctl set_param fail_loc=0
13487
13488         rm -f $TF
13489 }
13490 run_test 152 "test read/write with enomem ============================"
13491
13492 test_153() {
13493         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13494 }
13495 run_test 153 "test if fdatasync does not crash ======================="
13496
13497 dot_lustre_fid_permission_check() {
13498         local fid=$1
13499         local ffid=$MOUNT/.lustre/fid/$fid
13500         local test_dir=$2
13501
13502         echo "stat fid $fid"
13503         stat $ffid > /dev/null || error "stat $ffid failed."
13504         echo "touch fid $fid"
13505         touch $ffid || error "touch $ffid failed."
13506         echo "write to fid $fid"
13507         cat /etc/hosts > $ffid || error "write $ffid failed."
13508         echo "read fid $fid"
13509         diff /etc/hosts $ffid || error "read $ffid failed."
13510         echo "append write to fid $fid"
13511         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13512         echo "rename fid $fid"
13513         mv $ffid $test_dir/$tfile.1 &&
13514                 error "rename $ffid to $tfile.1 should fail."
13515         touch $test_dir/$tfile.1
13516         mv $test_dir/$tfile.1 $ffid &&
13517                 error "rename $tfile.1 to $ffid should fail."
13518         rm -f $test_dir/$tfile.1
13519         echo "truncate fid $fid"
13520         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13521         echo "link fid $fid"
13522         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13523         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13524                 echo "setfacl fid $fid"
13525                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13526                 echo "getfacl fid $fid"
13527                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13528         fi
13529         echo "unlink fid $fid"
13530         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13531         echo "mknod fid $fid"
13532         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13533
13534         fid=[0xf00000400:0x1:0x0]
13535         ffid=$MOUNT/.lustre/fid/$fid
13536
13537         echo "stat non-exist fid $fid"
13538         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13539         echo "write to non-exist fid $fid"
13540         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13541         echo "link new fid $fid"
13542         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13543
13544         mkdir -p $test_dir/$tdir
13545         touch $test_dir/$tdir/$tfile
13546         fid=$($LFS path2fid $test_dir/$tdir)
13547         rc=$?
13548         [ $rc -ne 0 ] &&
13549                 error "error: could not get fid for $test_dir/$dir/$tfile."
13550
13551         ffid=$MOUNT/.lustre/fid/$fid
13552
13553         echo "ls $fid"
13554         ls $ffid > /dev/null || error "ls $ffid failed."
13555         echo "touch $fid/$tfile.1"
13556         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13557
13558         echo "touch $MOUNT/.lustre/fid/$tfile"
13559         touch $MOUNT/.lustre/fid/$tfile && \
13560                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13561
13562         echo "setxattr to $MOUNT/.lustre/fid"
13563         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13564
13565         echo "listxattr for $MOUNT/.lustre/fid"
13566         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13567
13568         echo "delxattr from $MOUNT/.lustre/fid"
13569         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13570
13571         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13572         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13573                 error "touch invalid fid should fail."
13574
13575         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13576         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13577                 error "touch non-normal fid should fail."
13578
13579         echo "rename $tdir to $MOUNT/.lustre/fid"
13580         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13581                 error "rename to $MOUNT/.lustre/fid should fail."
13582
13583         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13584         then            # LU-3547
13585                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13586                 local new_obf_mode=777
13587
13588                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13589                 chmod $new_obf_mode $DIR/.lustre/fid ||
13590                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13591
13592                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13593                 [ $obf_mode -eq $new_obf_mode ] ||
13594                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13595
13596                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13597                 chmod $old_obf_mode $DIR/.lustre/fid ||
13598                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13599         fi
13600
13601         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13602         fid=$($LFS path2fid $test_dir/$tfile-2)
13603
13604         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13605         then # LU-5424
13606                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13607                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13608                         error "create lov data thru .lustre failed"
13609         fi
13610         echo "cp /etc/passwd $test_dir/$tfile-2"
13611         cp /etc/passwd $test_dir/$tfile-2 ||
13612                 error "copy to $test_dir/$tfile-2 failed."
13613         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13614         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13615                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13616
13617         rm -rf $test_dir/tfile.lnk
13618         rm -rf $test_dir/$tfile-2
13619 }
13620
13621 test_154A() {
13622         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13623                 skip "Need MDS version at least 2.4.1"
13624
13625         local tf=$DIR/$tfile
13626         touch $tf
13627
13628         local fid=$($LFS path2fid $tf)
13629         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13630
13631         # check that we get the same pathname back
13632         local rootpath
13633         local found
13634         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13635                 echo "$rootpath $fid"
13636                 found=$($LFS fid2path $rootpath "$fid")
13637                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13638                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13639         done
13640
13641         # check wrong root path format
13642         rootpath=$MOUNT"_wrong"
13643         found=$($LFS fid2path $rootpath "$fid")
13644         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13645 }
13646 run_test 154A "lfs path2fid and fid2path basic checks"
13647
13648 test_154B() {
13649         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13650                 skip "Need MDS version at least 2.4.1"
13651
13652         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13653         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13654         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13655         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13656
13657         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13658         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13659
13660         # check that we get the same pathname
13661         echo "PFID: $PFID, name: $name"
13662         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13663         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13664         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13665                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13666
13667         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13668 }
13669 run_test 154B "verify the ll_decode_linkea tool"
13670
13671 test_154a() {
13672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13673         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13674         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13675                 skip "Need MDS version at least 2.2.51"
13676         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13677
13678         cp /etc/hosts $DIR/$tfile
13679
13680         fid=$($LFS path2fid $DIR/$tfile)
13681         rc=$?
13682         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13683
13684         dot_lustre_fid_permission_check "$fid" $DIR ||
13685                 error "dot lustre permission check $fid failed"
13686
13687         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13688
13689         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13690
13691         touch $MOUNT/.lustre/file &&
13692                 error "creation is not allowed under .lustre"
13693
13694         mkdir $MOUNT/.lustre/dir &&
13695                 error "mkdir is not allowed under .lustre"
13696
13697         rm -rf $DIR/$tfile
13698 }
13699 run_test 154a "Open-by-FID"
13700
13701 test_154b() {
13702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13703         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13704         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13705         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13706                 skip "Need MDS version at least 2.2.51"
13707
13708         local remote_dir=$DIR/$tdir/remote_dir
13709         local MDTIDX=1
13710         local rc=0
13711
13712         mkdir -p $DIR/$tdir
13713         $LFS mkdir -i $MDTIDX $remote_dir ||
13714                 error "create remote directory failed"
13715
13716         cp /etc/hosts $remote_dir/$tfile
13717
13718         fid=$($LFS path2fid $remote_dir/$tfile)
13719         rc=$?
13720         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13721
13722         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13723                 error "dot lustre permission check $fid failed"
13724         rm -rf $DIR/$tdir
13725 }
13726 run_test 154b "Open-by-FID for remote directory"
13727
13728 test_154c() {
13729         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13730                 skip "Need MDS version at least 2.4.1"
13731
13732         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13733         local FID1=$($LFS path2fid $DIR/$tfile.1)
13734         local FID2=$($LFS path2fid $DIR/$tfile.2)
13735         local FID3=$($LFS path2fid $DIR/$tfile.3)
13736
13737         local N=1
13738         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13739                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13740                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13741                 local want=FID$N
13742                 [ "$FID" = "${!want}" ] ||
13743                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13744                 N=$((N + 1))
13745         done
13746
13747         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13748         do
13749                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13750                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13751                 N=$((N + 1))
13752         done
13753 }
13754 run_test 154c "lfs path2fid and fid2path multiple arguments"
13755
13756 test_154d() {
13757         remote_mds_nodsh && skip "remote MDS with nodsh"
13758         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13759                 skip "Need MDS version at least 2.5.53"
13760
13761         if remote_mds; then
13762                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13763         else
13764                 nid="0@lo"
13765         fi
13766         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13767         local fd
13768         local cmd
13769
13770         rm -f $DIR/$tfile
13771         touch $DIR/$tfile
13772
13773         local fid=$($LFS path2fid $DIR/$tfile)
13774         # Open the file
13775         fd=$(free_fd)
13776         cmd="exec $fd<$DIR/$tfile"
13777         eval $cmd
13778         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13779         echo "$fid_list" | grep "$fid"
13780         rc=$?
13781
13782         cmd="exec $fd>/dev/null"
13783         eval $cmd
13784         if [ $rc -ne 0 ]; then
13785                 error "FID $fid not found in open files list $fid_list"
13786         fi
13787 }
13788 run_test 154d "Verify open file fid"
13789
13790 test_154e()
13791 {
13792         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13793                 skip "Need MDS version at least 2.6.50"
13794
13795         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13796                 error ".lustre returned by readdir"
13797         fi
13798 }
13799 run_test 154e ".lustre is not returned by readdir"
13800
13801 test_154f() {
13802         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13803
13804         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13805         test_mkdir -p -c1 $DIR/$tdir/d
13806         # test dirs inherit from its stripe
13807         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13808         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13809         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13810         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13811         touch $DIR/f
13812
13813         # get fid of parents
13814         local FID0=$($LFS path2fid $DIR/$tdir/d)
13815         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13816         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13817         local FID3=$($LFS path2fid $DIR)
13818
13819         # check that path2fid --parents returns expected <parent_fid>/name
13820         # 1) test for a directory (single parent)
13821         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13822         [ "$parent" == "$FID0/foo1" ] ||
13823                 error "expected parent: $FID0/foo1, got: $parent"
13824
13825         # 2) test for a file with nlink > 1 (multiple parents)
13826         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13827         echo "$parent" | grep -F "$FID1/$tfile" ||
13828                 error "$FID1/$tfile not returned in parent list"
13829         echo "$parent" | grep -F "$FID2/link" ||
13830                 error "$FID2/link not returned in parent list"
13831
13832         # 3) get parent by fid
13833         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13834         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13835         echo "$parent" | grep -F "$FID1/$tfile" ||
13836                 error "$FID1/$tfile not returned in parent list (by fid)"
13837         echo "$parent" | grep -F "$FID2/link" ||
13838                 error "$FID2/link not returned in parent list (by fid)"
13839
13840         # 4) test for entry in root directory
13841         parent=$($LFS path2fid --parents $DIR/f)
13842         echo "$parent" | grep -F "$FID3/f" ||
13843                 error "$FID3/f not returned in parent list"
13844
13845         # 5) test it on root directory
13846         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13847                 error "$MOUNT should not have parents"
13848
13849         # enable xattr caching and check that linkea is correctly updated
13850         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13851         save_lustre_params client "llite.*.xattr_cache" > $save
13852         lctl set_param llite.*.xattr_cache 1
13853
13854         # 6.1) linkea update on rename
13855         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13856
13857         # get parents by fid
13858         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13859         # foo1 should no longer be returned in parent list
13860         echo "$parent" | grep -F "$FID1" &&
13861                 error "$FID1 should no longer be in parent list"
13862         # the new path should appear
13863         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13864                 error "$FID2/$tfile.moved is not in parent list"
13865
13866         # 6.2) linkea update on unlink
13867         rm -f $DIR/$tdir/d/foo2/link
13868         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13869         # foo2/link should no longer be returned in parent list
13870         echo "$parent" | grep -F "$FID2/link" &&
13871                 error "$FID2/link should no longer be in parent list"
13872         true
13873
13874         rm -f $DIR/f
13875         restore_lustre_params < $save
13876         rm -f $save
13877 }
13878 run_test 154f "get parent fids by reading link ea"
13879
13880 test_154g()
13881 {
13882         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13883         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13884            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13885                 skip "Need MDS version at least 2.6.92"
13886
13887         mkdir -p $DIR/$tdir
13888         llapi_fid_test -d $DIR/$tdir
13889 }
13890 run_test 154g "various llapi FID tests"
13891
13892 test_155_small_load() {
13893     local temp=$TMP/$tfile
13894     local file=$DIR/$tfile
13895
13896     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13897         error "dd of=$temp bs=6096 count=1 failed"
13898     cp $temp $file
13899     cancel_lru_locks $OSC
13900     cmp $temp $file || error "$temp $file differ"
13901
13902     $TRUNCATE $temp 6000
13903     $TRUNCATE $file 6000
13904     cmp $temp $file || error "$temp $file differ (truncate1)"
13905
13906     echo "12345" >>$temp
13907     echo "12345" >>$file
13908     cmp $temp $file || error "$temp $file differ (append1)"
13909
13910     echo "12345" >>$temp
13911     echo "12345" >>$file
13912     cmp $temp $file || error "$temp $file differ (append2)"
13913
13914     rm -f $temp $file
13915     true
13916 }
13917
13918 test_155_big_load() {
13919         remote_ost_nodsh && skip "remote OST with nodsh"
13920
13921         local temp=$TMP/$tfile
13922         local file=$DIR/$tfile
13923
13924         free_min_max
13925         local cache_size=$(do_facet ost$((MAXI+1)) \
13926                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13927         local large_file_size=$((cache_size * 2))
13928
13929         echo "OSS cache size: $cache_size KB"
13930         echo "Large file size: $large_file_size KB"
13931
13932         [ $MAXV -le $large_file_size ] &&
13933                 skip_env "max available OST size needs > $large_file_size KB"
13934
13935         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13936
13937         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13938                 error "dd of=$temp bs=$large_file_size count=1k failed"
13939         cp $temp $file
13940         ls -lh $temp $file
13941         cancel_lru_locks osc
13942         cmp $temp $file || error "$temp $file differ"
13943
13944         rm -f $temp $file
13945         true
13946 }
13947
13948 save_writethrough() {
13949         local facets=$(get_facets OST)
13950
13951         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13952 }
13953
13954 test_155a() {
13955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13956
13957         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13958
13959         save_writethrough $p
13960
13961         set_cache read on
13962         set_cache writethrough on
13963         test_155_small_load
13964         restore_lustre_params < $p
13965         rm -f $p
13966 }
13967 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13968
13969 test_155b() {
13970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13971
13972         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13973
13974         save_writethrough $p
13975
13976         set_cache read on
13977         set_cache writethrough off
13978         test_155_small_load
13979         restore_lustre_params < $p
13980         rm -f $p
13981 }
13982 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
13983
13984 test_155c() {
13985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13986
13987         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13988
13989         save_writethrough $p
13990
13991         set_cache read off
13992         set_cache writethrough on
13993         test_155_small_load
13994         restore_lustre_params < $p
13995         rm -f $p
13996 }
13997 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
13998
13999 test_155d() {
14000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14001
14002         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14003
14004         save_writethrough $p
14005
14006         set_cache read off
14007         set_cache writethrough off
14008         test_155_small_load
14009         restore_lustre_params < $p
14010         rm -f $p
14011 }
14012 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14013
14014 test_155e() {
14015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14016
14017         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14018
14019         save_writethrough $p
14020
14021         set_cache read on
14022         set_cache writethrough on
14023         test_155_big_load
14024         restore_lustre_params < $p
14025         rm -f $p
14026 }
14027 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14028
14029 test_155f() {
14030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14031
14032         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14033
14034         save_writethrough $p
14035
14036         set_cache read on
14037         set_cache writethrough off
14038         test_155_big_load
14039         restore_lustre_params < $p
14040         rm -f $p
14041 }
14042 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14043
14044 test_155g() {
14045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14046
14047         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14048
14049         save_writethrough $p
14050
14051         set_cache read off
14052         set_cache writethrough on
14053         test_155_big_load
14054         restore_lustre_params < $p
14055         rm -f $p
14056 }
14057 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14058
14059 test_155h() {
14060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14061
14062         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14063
14064         save_writethrough $p
14065
14066         set_cache read off
14067         set_cache writethrough off
14068         test_155_big_load
14069         restore_lustre_params < $p
14070         rm -f $p
14071 }
14072 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14073
14074 test_156() {
14075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14076         remote_ost_nodsh && skip "remote OST with nodsh"
14077         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14078                 skip "stats not implemented on old servers"
14079         [ "$ost1_FSTYPE" = "zfs" ] &&
14080                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14081
14082         local CPAGES=3
14083         local BEFORE
14084         local AFTER
14085         local file="$DIR/$tfile"
14086         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14087
14088         save_writethrough $p
14089         roc_hit_init
14090
14091         log "Turn on read and write cache"
14092         set_cache read on
14093         set_cache writethrough on
14094
14095         log "Write data and read it back."
14096         log "Read should be satisfied from the cache."
14097         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14098         BEFORE=$(roc_hit)
14099         cancel_lru_locks osc
14100         cat $file >/dev/null
14101         AFTER=$(roc_hit)
14102         if ! let "AFTER - BEFORE == CPAGES"; then
14103                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14104         else
14105                 log "cache hits: before: $BEFORE, after: $AFTER"
14106         fi
14107
14108         log "Read again; it should be satisfied from the cache."
14109         BEFORE=$AFTER
14110         cancel_lru_locks osc
14111         cat $file >/dev/null
14112         AFTER=$(roc_hit)
14113         if ! let "AFTER - BEFORE == CPAGES"; then
14114                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14115         else
14116                 log "cache hits:: before: $BEFORE, after: $AFTER"
14117         fi
14118
14119         log "Turn off the read cache and turn on the write cache"
14120         set_cache read off
14121         set_cache writethrough on
14122
14123         log "Read again; it should be satisfied from the cache."
14124         BEFORE=$(roc_hit)
14125         cancel_lru_locks osc
14126         cat $file >/dev/null
14127         AFTER=$(roc_hit)
14128         if ! let "AFTER - BEFORE == CPAGES"; then
14129                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14130         else
14131                 log "cache hits:: before: $BEFORE, after: $AFTER"
14132         fi
14133
14134         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14135                 # > 2.12.56 uses pagecache if cached
14136                 log "Read again; it should not be satisfied from the cache."
14137                 BEFORE=$AFTER
14138                 cancel_lru_locks osc
14139                 cat $file >/dev/null
14140                 AFTER=$(roc_hit)
14141                 if ! let "AFTER - BEFORE == 0"; then
14142                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14143                 else
14144                         log "cache hits:: before: $BEFORE, after: $AFTER"
14145                 fi
14146         fi
14147
14148         log "Write data and read it back."
14149         log "Read should be satisfied from the cache."
14150         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14151         BEFORE=$(roc_hit)
14152         cancel_lru_locks osc
14153         cat $file >/dev/null
14154         AFTER=$(roc_hit)
14155         if ! let "AFTER - BEFORE == CPAGES"; then
14156                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14157         else
14158                 log "cache hits:: before: $BEFORE, after: $AFTER"
14159         fi
14160
14161         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14162                 # > 2.12.56 uses pagecache if cached
14163                 log "Read again; it should not be satisfied from the cache."
14164                 BEFORE=$AFTER
14165                 cancel_lru_locks osc
14166                 cat $file >/dev/null
14167                 AFTER=$(roc_hit)
14168                 if ! let "AFTER - BEFORE == 0"; then
14169                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14170                 else
14171                         log "cache hits:: before: $BEFORE, after: $AFTER"
14172                 fi
14173         fi
14174
14175         log "Turn off read and write cache"
14176         set_cache read off
14177         set_cache writethrough off
14178
14179         log "Write data and read it back"
14180         log "It should not be satisfied from the cache."
14181         rm -f $file
14182         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14183         cancel_lru_locks osc
14184         BEFORE=$(roc_hit)
14185         cat $file >/dev/null
14186         AFTER=$(roc_hit)
14187         if ! let "AFTER - BEFORE == 0"; then
14188                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14189         else
14190                 log "cache hits:: before: $BEFORE, after: $AFTER"
14191         fi
14192
14193         log "Turn on the read cache and turn off the write cache"
14194         set_cache read on
14195         set_cache writethrough off
14196
14197         log "Write data and read it back"
14198         log "It should not be satisfied from the cache."
14199         rm -f $file
14200         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14201         BEFORE=$(roc_hit)
14202         cancel_lru_locks osc
14203         cat $file >/dev/null
14204         AFTER=$(roc_hit)
14205         if ! let "AFTER - BEFORE == 0"; then
14206                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14207         else
14208                 log "cache hits:: before: $BEFORE, after: $AFTER"
14209         fi
14210
14211         log "Read again; it should be satisfied from the cache."
14212         BEFORE=$(roc_hit)
14213         cancel_lru_locks osc
14214         cat $file >/dev/null
14215         AFTER=$(roc_hit)
14216         if ! let "AFTER - BEFORE == CPAGES"; then
14217                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14218         else
14219                 log "cache hits:: before: $BEFORE, after: $AFTER"
14220         fi
14221
14222         restore_lustre_params < $p
14223         rm -f $p $file
14224 }
14225 run_test 156 "Verification of tunables"
14226
14227 test_160a() {
14228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14229         remote_mds_nodsh && skip "remote MDS with nodsh"
14230         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14231                 skip "Need MDS version at least 2.2.0"
14232
14233         changelog_register || error "changelog_register failed"
14234         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14235         changelog_users $SINGLEMDS | grep -q $cl_user ||
14236                 error "User $cl_user not found in changelog_users"
14237
14238         # change something
14239         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14240         changelog_clear 0 || error "changelog_clear failed"
14241         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14242         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14243         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14244         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14245         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14246         rm $DIR/$tdir/pics/desktop.jpg
14247
14248         changelog_dump | tail -10
14249
14250         echo "verifying changelog mask"
14251         changelog_chmask "-MKDIR"
14252         changelog_chmask "-CLOSE"
14253
14254         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14255         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14256
14257         changelog_chmask "+MKDIR"
14258         changelog_chmask "+CLOSE"
14259
14260         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14261         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14262
14263         changelog_dump | tail -10
14264         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14265         CLOSES=$(changelog_dump | grep -c "CLOSE")
14266         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14267         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14268
14269         # verify contents
14270         echo "verifying target fid"
14271         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14272         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14273         [ "$fidc" == "$fidf" ] ||
14274                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14275         echo "verifying parent fid"
14276         # The FID returned from the Changelog may be the directory shard on
14277         # a different MDT, and not the FID returned by path2fid on the parent.
14278         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14279         # since this is what will matter when recreating this file in the tree.
14280         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14281         local pathp=$($LFS fid2path $MOUNT "$fidp")
14282         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14283                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14284
14285         echo "getting records for $cl_user"
14286         changelog_users $SINGLEMDS
14287         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14288         local nclr=3
14289         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14290                 error "changelog_clear failed"
14291         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14292         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14293         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14294                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14295
14296         local min0_rec=$(changelog_users $SINGLEMDS |
14297                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14298         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14299                           awk '{ print $1; exit; }')
14300
14301         changelog_dump | tail -n 5
14302         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14303         [ $first_rec == $((min0_rec + 1)) ] ||
14304                 error "first index should be $min0_rec + 1 not $first_rec"
14305
14306         # LU-3446 changelog index reset on MDT restart
14307         local cur_rec1=$(changelog_users $SINGLEMDS |
14308                          awk '/^current.index:/ { print $NF }')
14309         changelog_clear 0 ||
14310                 error "clear all changelog records for $cl_user failed"
14311         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14312         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14313                 error "Fail to start $SINGLEMDS"
14314         local cur_rec2=$(changelog_users $SINGLEMDS |
14315                          awk '/^current.index:/ { print $NF }')
14316         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14317         [ $cur_rec1 == $cur_rec2 ] ||
14318                 error "current index should be $cur_rec1 not $cur_rec2"
14319
14320         echo "verifying users from this test are deregistered"
14321         changelog_deregister || error "changelog_deregister failed"
14322         changelog_users $SINGLEMDS | grep -q $cl_user &&
14323                 error "User '$cl_user' still in changelog_users"
14324
14325         # lctl get_param -n mdd.*.changelog_users
14326         # current index: 144
14327         # ID    index (idle seconds)
14328         # cl3   144 (2)
14329         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14330                 # this is the normal case where all users were deregistered
14331                 # make sure no new records are added when no users are present
14332                 local last_rec1=$(changelog_users $SINGLEMDS |
14333                                   awk '/^current.index:/ { print $NF }')
14334                 touch $DIR/$tdir/chloe
14335                 local last_rec2=$(changelog_users $SINGLEMDS |
14336                                   awk '/^current.index:/ { print $NF }')
14337                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14338                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14339         else
14340                 # any changelog users must be leftovers from a previous test
14341                 changelog_users $SINGLEMDS
14342                 echo "other changelog users; can't verify off"
14343         fi
14344 }
14345 run_test 160a "changelog sanity"
14346
14347 test_160b() { # LU-3587
14348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14349         remote_mds_nodsh && skip "remote MDS with nodsh"
14350         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14351                 skip "Need MDS version at least 2.2.0"
14352
14353         changelog_register || error "changelog_register failed"
14354         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14355         changelog_users $SINGLEMDS | grep -q $cl_user ||
14356                 error "User '$cl_user' not found in changelog_users"
14357
14358         local longname1=$(str_repeat a 255)
14359         local longname2=$(str_repeat b 255)
14360
14361         cd $DIR
14362         echo "creating very long named file"
14363         touch $longname1 || error "create of '$longname1' failed"
14364         echo "renaming very long named file"
14365         mv $longname1 $longname2
14366
14367         changelog_dump | grep RENME | tail -n 5
14368         rm -f $longname2
14369 }
14370 run_test 160b "Verify that very long rename doesn't crash in changelog"
14371
14372 test_160c() {
14373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14374         remote_mds_nodsh && skip "remote MDS with nodsh"
14375
14376         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14377                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14378                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14379                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14380
14381         local rc=0
14382
14383         # Registration step
14384         changelog_register || error "changelog_register failed"
14385
14386         rm -rf $DIR/$tdir
14387         mkdir -p $DIR/$tdir
14388         $MCREATE $DIR/$tdir/foo_160c
14389         changelog_chmask "-TRUNC"
14390         $TRUNCATE $DIR/$tdir/foo_160c 200
14391         changelog_chmask "+TRUNC"
14392         $TRUNCATE $DIR/$tdir/foo_160c 199
14393         changelog_dump | tail -n 5
14394         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14395         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14396 }
14397 run_test 160c "verify that changelog log catch the truncate event"
14398
14399 test_160d() {
14400         remote_mds_nodsh && skip "remote MDS with nodsh"
14401         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14403         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14404                 skip "Need MDS version at least 2.7.60"
14405
14406         # Registration step
14407         changelog_register || error "changelog_register failed"
14408
14409         mkdir -p $DIR/$tdir/migrate_dir
14410         changelog_clear 0 || error "changelog_clear failed"
14411
14412         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14413         changelog_dump | tail -n 5
14414         local migrates=$(changelog_dump | grep -c "MIGRT")
14415         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14416 }
14417 run_test 160d "verify that changelog log catch the migrate event"
14418
14419 test_160e() {
14420         remote_mds_nodsh && skip "remote MDS with nodsh"
14421
14422         # Create a user
14423         changelog_register || error "changelog_register failed"
14424
14425         # Delete a future user (expect fail)
14426         local MDT0=$(facet_svc $SINGLEMDS)
14427         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14428         local rc=$?
14429
14430         if [ $rc -eq 0 ]; then
14431                 error "Deleted non-existant user cl77"
14432         elif [ $rc -ne 2 ]; then
14433                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14434         fi
14435
14436         # Clear to a bad index (1 billion should be safe)
14437         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14438         rc=$?
14439
14440         if [ $rc -eq 0 ]; then
14441                 error "Successfully cleared to invalid CL index"
14442         elif [ $rc -ne 22 ]; then
14443                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14444         fi
14445 }
14446 run_test 160e "changelog negative testing (should return errors)"
14447
14448 test_160f() {
14449         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14450         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14451                 skip "Need MDS version at least 2.10.56"
14452
14453         local mdts=$(comma_list $(mdts_nodes))
14454
14455         # Create a user
14456         changelog_register || error "first changelog_register failed"
14457         changelog_register || error "second changelog_register failed"
14458         local cl_users
14459         declare -A cl_user1
14460         declare -A cl_user2
14461         local user_rec1
14462         local user_rec2
14463         local i
14464
14465         # generate some changelog records to accumulate on each MDT
14466         # use fnv1a because created files should be evenly distributed
14467         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14468                 error "test_mkdir $tdir failed"
14469         log "$(date +%s): creating first files"
14470         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14471                 error "create $DIR/$tdir/$tfile failed"
14472
14473         # check changelogs have been generated
14474         local start=$SECONDS
14475         local idle_time=$((MDSCOUNT * 5 + 5))
14476         local nbcl=$(changelog_dump | wc -l)
14477         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14478
14479         for param in "changelog_max_idle_time=$idle_time" \
14480                      "changelog_gc=1" \
14481                      "changelog_min_gc_interval=2" \
14482                      "changelog_min_free_cat_entries=3"; do
14483                 local MDT0=$(facet_svc $SINGLEMDS)
14484                 local var="${param%=*}"
14485                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14486
14487                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14488                 do_nodes $mdts $LCTL set_param mdd.*.$param
14489         done
14490
14491         # force cl_user2 to be idle (1st part), but also cancel the
14492         # cl_user1 records so that it is not evicted later in the test.
14493         local sleep1=$((idle_time / 2))
14494         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14495         sleep $sleep1
14496
14497         # simulate changelog catalog almost full
14498         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14499         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14500
14501         for i in $(seq $MDSCOUNT); do
14502                 cl_users=(${CL_USERS[mds$i]})
14503                 cl_user1[mds$i]="${cl_users[0]}"
14504                 cl_user2[mds$i]="${cl_users[1]}"
14505
14506                 [ -n "${cl_user1[mds$i]}" ] ||
14507                         error "mds$i: no user registered"
14508                 [ -n "${cl_user2[mds$i]}" ] ||
14509                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14510
14511                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14512                 [ -n "$user_rec1" ] ||
14513                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14514                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14515                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14516                 [ -n "$user_rec2" ] ||
14517                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14518                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14519                      "$user_rec1 + 2 == $user_rec2"
14520                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14521                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14522                               "$user_rec1 + 2, but is $user_rec2"
14523                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14524                 [ -n "$user_rec2" ] ||
14525                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14526                 [ $user_rec1 == $user_rec2 ] ||
14527                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14528                               "$user_rec1, but is $user_rec2"
14529         done
14530
14531         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14532         local sleep2=$((idle_time - (SECONDS - start) + 1))
14533         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14534         sleep $sleep2
14535
14536         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14537         # cl_user1 should be OK because it recently processed records.
14538         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14539         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14540                 error "create $DIR/$tdir/${tfile}b failed"
14541
14542         # ensure gc thread is done
14543         for i in $(mdts_nodes); do
14544                 wait_update $i \
14545                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14546                         error "$i: GC-thread not done"
14547         done
14548
14549         local first_rec
14550         for i in $(seq $MDSCOUNT); do
14551                 # check cl_user1 still registered
14552                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14553                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14554                 # check cl_user2 unregistered
14555                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14556                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14557
14558                 # check changelogs are present and starting at $user_rec1 + 1
14559                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14560                 [ -n "$user_rec1" ] ||
14561                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14562                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14563                             awk '{ print $1; exit; }')
14564
14565                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14566                 [ $((user_rec1 + 1)) == $first_rec ] ||
14567                         error "mds$i: first index should be $user_rec1 + 1, " \
14568                               "but is $first_rec"
14569         done
14570 }
14571 run_test 160f "changelog garbage collect (timestamped users)"
14572
14573 test_160g() {
14574         remote_mds_nodsh && skip "remote MDS with nodsh"
14575         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14576                 skip "Need MDS version at least 2.10.56"
14577
14578         local mdts=$(comma_list $(mdts_nodes))
14579
14580         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14581         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14582
14583         # Create a user
14584         changelog_register || error "first changelog_register failed"
14585         changelog_register || error "second changelog_register failed"
14586         local cl_users
14587         declare -A cl_user1
14588         declare -A cl_user2
14589         local user_rec1
14590         local user_rec2
14591         local i
14592
14593         # generate some changelog records to accumulate on each MDT
14594         # use fnv1a because created files should be evenly distributed
14595         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14596                 error "mkdir $tdir failed"
14597         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14598                 error "create $DIR/$tdir/$tfile failed"
14599
14600         # check changelogs have been generated
14601         local nbcl=$(changelog_dump | wc -l)
14602         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14603
14604         # reduce the max_idle_indexes value to make sure we exceed it
14605         max_ndx=$((nbcl / 2 - 1))
14606
14607         for param in "changelog_max_idle_indexes=$max_ndx" \
14608                      "changelog_gc=1" \
14609                      "changelog_min_gc_interval=2" \
14610                      "changelog_min_free_cat_entries=3"; do
14611                 local MDT0=$(facet_svc $SINGLEMDS)
14612                 local var="${param%=*}"
14613                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14614
14615                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14616                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14617                         error "unable to set mdd.*.$param"
14618         done
14619
14620         # simulate changelog catalog almost full
14621         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14622         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14623
14624         for i in $(seq $MDSCOUNT); do
14625                 cl_users=(${CL_USERS[mds$i]})
14626                 cl_user1[mds$i]="${cl_users[0]}"
14627                 cl_user2[mds$i]="${cl_users[1]}"
14628
14629                 [ -n "${cl_user1[mds$i]}" ] ||
14630                         error "mds$i: no user registered"
14631                 [ -n "${cl_user2[mds$i]}" ] ||
14632                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14633
14634                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14635                 [ -n "$user_rec1" ] ||
14636                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14637                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14638                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14639                 [ -n "$user_rec2" ] ||
14640                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14641                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14642                      "$user_rec1 + 2 == $user_rec2"
14643                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14644                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14645                               "$user_rec1 + 2, but is $user_rec2"
14646                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14647                 [ -n "$user_rec2" ] ||
14648                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14649                 [ $user_rec1 == $user_rec2 ] ||
14650                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14651                               "$user_rec1, but is $user_rec2"
14652         done
14653
14654         # ensure we are past the previous changelog_min_gc_interval set above
14655         sleep 2
14656
14657         # generate one more changelog to trigger fail_loc
14658         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14659                 error "create $DIR/$tdir/${tfile}bis failed"
14660
14661         # ensure gc thread is done
14662         for i in $(mdts_nodes); do
14663                 wait_update $i \
14664                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14665                         error "$i: GC-thread not done"
14666         done
14667
14668         local first_rec
14669         for i in $(seq $MDSCOUNT); do
14670                 # check cl_user1 still registered
14671                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14672                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14673                 # check cl_user2 unregistered
14674                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14675                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14676
14677                 # check changelogs are present and starting at $user_rec1 + 1
14678                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14679                 [ -n "$user_rec1" ] ||
14680                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14681                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14682                             awk '{ print $1; exit; }')
14683
14684                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14685                 [ $((user_rec1 + 1)) == $first_rec ] ||
14686                         error "mds$i: first index should be $user_rec1 + 1, " \
14687                               "but is $first_rec"
14688         done
14689 }
14690 run_test 160g "changelog garbage collect (old users)"
14691
14692 test_160h() {
14693         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14694         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14695                 skip "Need MDS version at least 2.10.56"
14696
14697         local mdts=$(comma_list $(mdts_nodes))
14698
14699         # Create a user
14700         changelog_register || error "first changelog_register failed"
14701         changelog_register || error "second changelog_register failed"
14702         local cl_users
14703         declare -A cl_user1
14704         declare -A cl_user2
14705         local user_rec1
14706         local user_rec2
14707         local i
14708
14709         # generate some changelog records to accumulate on each MDT
14710         # use fnv1a because created files should be evenly distributed
14711         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14712                 error "test_mkdir $tdir failed"
14713         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14714                 error "create $DIR/$tdir/$tfile failed"
14715
14716         # check changelogs have been generated
14717         local nbcl=$(changelog_dump | wc -l)
14718         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14719
14720         for param in "changelog_max_idle_time=10" \
14721                      "changelog_gc=1" \
14722                      "changelog_min_gc_interval=2"; do
14723                 local MDT0=$(facet_svc $SINGLEMDS)
14724                 local var="${param%=*}"
14725                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14726
14727                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14728                 do_nodes $mdts $LCTL set_param mdd.*.$param
14729         done
14730
14731         # force cl_user2 to be idle (1st part)
14732         sleep 9
14733
14734         for i in $(seq $MDSCOUNT); do
14735                 cl_users=(${CL_USERS[mds$i]})
14736                 cl_user1[mds$i]="${cl_users[0]}"
14737                 cl_user2[mds$i]="${cl_users[1]}"
14738
14739                 [ -n "${cl_user1[mds$i]}" ] ||
14740                         error "mds$i: no user registered"
14741                 [ -n "${cl_user2[mds$i]}" ] ||
14742                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14743
14744                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14745                 [ -n "$user_rec1" ] ||
14746                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14747                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14748                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14749                 [ -n "$user_rec2" ] ||
14750                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14751                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14752                      "$user_rec1 + 2 == $user_rec2"
14753                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14754                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14755                               "$user_rec1 + 2, but is $user_rec2"
14756                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14757                 [ -n "$user_rec2" ] ||
14758                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14759                 [ $user_rec1 == $user_rec2 ] ||
14760                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14761                               "$user_rec1, but is $user_rec2"
14762         done
14763
14764         # force cl_user2 to be idle (2nd part) and to reach
14765         # changelog_max_idle_time
14766         sleep 2
14767
14768         # force each GC-thread start and block then
14769         # one per MDT/MDD, set fail_val accordingly
14770         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14771         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14772
14773         # generate more changelogs to trigger fail_loc
14774         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14775                 error "create $DIR/$tdir/${tfile}bis failed"
14776
14777         # stop MDT to stop GC-thread, should be done in back-ground as it will
14778         # block waiting for the thread to be released and exit
14779         declare -A stop_pids
14780         for i in $(seq $MDSCOUNT); do
14781                 stop mds$i &
14782                 stop_pids[mds$i]=$!
14783         done
14784
14785         for i in $(mdts_nodes); do
14786                 local facet
14787                 local nb=0
14788                 local facets=$(facets_up_on_host $i)
14789
14790                 for facet in ${facets//,/ }; do
14791                         if [[ $facet == mds* ]]; then
14792                                 nb=$((nb + 1))
14793                         fi
14794                 done
14795                 # ensure each MDS's gc threads are still present and all in "R"
14796                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14797                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14798                         error "$i: expected $nb GC-thread"
14799                 wait_update $i \
14800                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14801                         "R" 20 ||
14802                         error "$i: GC-thread not found in R-state"
14803                 # check umounts of each MDT on MDS have reached kthread_stop()
14804                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14805                         error "$i: expected $nb umount"
14806                 wait_update $i \
14807                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14808                         error "$i: umount not found in D-state"
14809         done
14810
14811         # release all GC-threads
14812         do_nodes $mdts $LCTL set_param fail_loc=0
14813
14814         # wait for MDT stop to complete
14815         for i in $(seq $MDSCOUNT); do
14816                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14817         done
14818
14819         # XXX
14820         # may try to check if any orphan changelog records are present
14821         # via ldiskfs/zfs and llog_reader...
14822
14823         # re-start/mount MDTs
14824         for i in $(seq $MDSCOUNT); do
14825                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14826                         error "Fail to start mds$i"
14827         done
14828
14829         local first_rec
14830         for i in $(seq $MDSCOUNT); do
14831                 # check cl_user1 still registered
14832                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14833                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14834                 # check cl_user2 unregistered
14835                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14836                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14837
14838                 # check changelogs are present and starting at $user_rec1 + 1
14839                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14840                 [ -n "$user_rec1" ] ||
14841                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14842                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14843                             awk '{ print $1; exit; }')
14844
14845                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14846                 [ $((user_rec1 + 1)) == $first_rec ] ||
14847                         error "mds$i: first index should be $user_rec1 + 1, " \
14848                               "but is $first_rec"
14849         done
14850 }
14851 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14852               "during mount"
14853
14854 test_160i() {
14855
14856         local mdts=$(comma_list $(mdts_nodes))
14857
14858         changelog_register || error "first changelog_register failed"
14859
14860         # generate some changelog records to accumulate on each MDT
14861         # use fnv1a because created files should be evenly distributed
14862         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14863                 error "mkdir $tdir failed"
14864         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14865                 error "create $DIR/$tdir/$tfile failed"
14866
14867         # check changelogs have been generated
14868         local nbcl=$(changelog_dump | wc -l)
14869         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14870
14871         # simulate race between register and unregister
14872         # XXX as fail_loc is set per-MDS, with DNE configs the race
14873         # simulation will only occur for one MDT per MDS and for the
14874         # others the normal race scenario will take place
14875         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14876         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14877         do_nodes $mdts $LCTL set_param fail_val=1
14878
14879         # unregister 1st user
14880         changelog_deregister &
14881         local pid1=$!
14882         # wait some time for deregister work to reach race rdv
14883         sleep 2
14884         # register 2nd user
14885         changelog_register || error "2nd user register failed"
14886
14887         wait $pid1 || error "1st user deregister failed"
14888
14889         local i
14890         local last_rec
14891         declare -A LAST_REC
14892         for i in $(seq $MDSCOUNT); do
14893                 if changelog_users mds$i | grep "^cl"; then
14894                         # make sure new records are added with one user present
14895                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14896                                           awk '/^current.index:/ { print $NF }')
14897                 else
14898                         error "mds$i has no user registered"
14899                 fi
14900         done
14901
14902         # generate more changelog records to accumulate on each MDT
14903         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14904                 error "create $DIR/$tdir/${tfile}bis failed"
14905
14906         for i in $(seq $MDSCOUNT); do
14907                 last_rec=$(changelog_users $SINGLEMDS |
14908                            awk '/^current.index:/ { print $NF }')
14909                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14910                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14911                         error "changelogs are off on mds$i"
14912         done
14913 }
14914 run_test 160i "changelog user register/unregister race"
14915
14916 test_160j() {
14917         remote_mds_nodsh && skip "remote MDS with nodsh"
14918         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14919                 skip "Need MDS version at least 2.12.56"
14920
14921         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14922         stack_trap "umount $MOUNT2" EXIT
14923
14924         changelog_register || error "first changelog_register failed"
14925         stack_trap "changelog_deregister" EXIT
14926
14927         # generate some changelog
14928         # use fnv1a because created files should be evenly distributed
14929         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14930                 error "mkdir $tdir failed"
14931         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14932                 error "create $DIR/$tdir/${tfile}bis failed"
14933
14934         # open the changelog device
14935         exec 3>/dev/changelog-$FSNAME-MDT0000
14936         stack_trap "exec 3>&-" EXIT
14937         exec 4</dev/changelog-$FSNAME-MDT0000
14938         stack_trap "exec 4<&-" EXIT
14939
14940         # umount the first lustre mount
14941         umount $MOUNT
14942         stack_trap "mount_client $MOUNT" EXIT
14943
14944         # read changelog
14945         cat <&4 >/dev/null || error "read changelog failed"
14946
14947         # clear changelog
14948         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14949         changelog_users $SINGLEMDS | grep -q $cl_user ||
14950                 error "User $cl_user not found in changelog_users"
14951
14952         printf 'clear:'$cl_user':0' >&3
14953 }
14954 run_test 160j "client can be umounted  while its chanangelog is being used"
14955
14956 test_160k() {
14957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14958         remote_mds_nodsh && skip "remote MDS with nodsh"
14959
14960         mkdir -p $DIR/$tdir/1/1
14961
14962         changelog_register || error "changelog_register failed"
14963         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14964
14965         changelog_users $SINGLEMDS | grep -q $cl_user ||
14966                 error "User '$cl_user' not found in changelog_users"
14967 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14968         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
14969         rmdir $DIR/$tdir/1/1 & sleep 1
14970         mkdir $DIR/$tdir/2
14971         touch $DIR/$tdir/2/2
14972         rm -rf $DIR/$tdir/2
14973
14974         wait
14975         sleep 4
14976
14977         changelog_dump | grep rmdir || error "rmdir not recorded"
14978
14979         rm -rf $DIR/$tdir
14980         changelog_deregister
14981 }
14982 run_test 160k "Verify that changelog records are not lost"
14983
14984 # Verifies that a file passed as a parameter has recently had an operation
14985 # performed on it that has generated an MTIME changelog which contains the
14986 # correct parent FID. As files might reside on a different MDT from the
14987 # parent directory in DNE configurations, the FIDs are translated to paths
14988 # before being compared, which should be identical
14989 compare_mtime_changelog() {
14990         local file="${1}"
14991         local mdtidx
14992         local mtime
14993         local cl_fid
14994         local pdir
14995         local dir
14996
14997         mdtidx=$($LFS getstripe --mdt-index $file)
14998         mdtidx=$(printf "%04x" $mdtidx)
14999
15000         # Obtain the parent FID from the MTIME changelog
15001         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15002         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15003
15004         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15005         [ -z "$cl_fid" ] && error "parent FID not present"
15006
15007         # Verify that the path for the parent FID is the same as the path for
15008         # the test directory
15009         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15010
15011         dir=$(dirname $1)
15012
15013         [[ "${pdir%/}" == "$dir" ]] ||
15014                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15015 }
15016
15017 test_160l() {
15018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15019
15020         remote_mds_nodsh && skip "remote MDS with nodsh"
15021         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15022                 skip "Need MDS version at least 2.13.55"
15023
15024         local cl_user
15025
15026         changelog_register || error "changelog_register failed"
15027         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15028
15029         changelog_users $SINGLEMDS | grep -q $cl_user ||
15030                 error "User '$cl_user' not found in changelog_users"
15031
15032         # Clear some types so that MTIME changelogs are generated
15033         changelog_chmask "-CREAT"
15034         changelog_chmask "-CLOSE"
15035
15036         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15037
15038         # Test CL_MTIME during setattr
15039         touch $DIR/$tdir/$tfile
15040         compare_mtime_changelog $DIR/$tdir/$tfile
15041
15042         # Test CL_MTIME during close
15043         dd if=/dev/urandom of=$DIR/$tdir/${tfile}_2 bs=1M count=64 ||
15044                 error "cannot create file $DIR/$tdir/${tfile}_2"
15045         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15046 }
15047 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15048
15049 test_161a() {
15050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15051
15052         test_mkdir -c1 $DIR/$tdir
15053         cp /etc/hosts $DIR/$tdir/$tfile
15054         test_mkdir -c1 $DIR/$tdir/foo1
15055         test_mkdir -c1 $DIR/$tdir/foo2
15056         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15057         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15058         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15059         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15060         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15061         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15062                 $LFS fid2path $DIR $FID
15063                 error "bad link ea"
15064         fi
15065         # middle
15066         rm $DIR/$tdir/foo2/zachary
15067         # last
15068         rm $DIR/$tdir/foo2/thor
15069         # first
15070         rm $DIR/$tdir/$tfile
15071         # rename
15072         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15073         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15074                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15075         rm $DIR/$tdir/foo2/maggie
15076
15077         # overflow the EA
15078         local longname=$tfile.avg_len_is_thirty_two_
15079         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15080                 error_noexit 'failed to unlink many hardlinks'" EXIT
15081         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15082                 error "failed to hardlink many files"
15083         links=$($LFS fid2path $DIR $FID | wc -l)
15084         echo -n "${links}/1000 links in link EA"
15085         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15086 }
15087 run_test 161a "link ea sanity"
15088
15089 test_161b() {
15090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15091         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15092
15093         local MDTIDX=1
15094         local remote_dir=$DIR/$tdir/remote_dir
15095
15096         mkdir -p $DIR/$tdir
15097         $LFS mkdir -i $MDTIDX $remote_dir ||
15098                 error "create remote directory failed"
15099
15100         cp /etc/hosts $remote_dir/$tfile
15101         mkdir -p $remote_dir/foo1
15102         mkdir -p $remote_dir/foo2
15103         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15104         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15105         ln $remote_dir/$tfile $remote_dir/foo1/luna
15106         ln $remote_dir/$tfile $remote_dir/foo2/thor
15107
15108         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15109                      tr -d ']')
15110         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15111                 $LFS fid2path $DIR $FID
15112                 error "bad link ea"
15113         fi
15114         # middle
15115         rm $remote_dir/foo2/zachary
15116         # last
15117         rm $remote_dir/foo2/thor
15118         # first
15119         rm $remote_dir/$tfile
15120         # rename
15121         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15122         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15123         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15124                 $LFS fid2path $DIR $FID
15125                 error "bad link rename"
15126         fi
15127         rm $remote_dir/foo2/maggie
15128
15129         # overflow the EA
15130         local longname=filename_avg_len_is_thirty_two_
15131         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15132                 error "failed to hardlink many files"
15133         links=$($LFS fid2path $DIR $FID | wc -l)
15134         echo -n "${links}/1000 links in link EA"
15135         [[ ${links} -gt 60 ]] ||
15136                 error "expected at least 60 links in link EA"
15137         unlinkmany $remote_dir/foo2/$longname 1000 ||
15138         error "failed to unlink many hardlinks"
15139 }
15140 run_test 161b "link ea sanity under remote directory"
15141
15142 test_161c() {
15143         remote_mds_nodsh && skip "remote MDS with nodsh"
15144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15145         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15146                 skip "Need MDS version at least 2.1.5"
15147
15148         # define CLF_RENAME_LAST 0x0001
15149         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15150         changelog_register || error "changelog_register failed"
15151
15152         rm -rf $DIR/$tdir
15153         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15154         touch $DIR/$tdir/foo_161c
15155         touch $DIR/$tdir/bar_161c
15156         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15157         changelog_dump | grep RENME | tail -n 5
15158         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15159         changelog_clear 0 || error "changelog_clear failed"
15160         if [ x$flags != "x0x1" ]; then
15161                 error "flag $flags is not 0x1"
15162         fi
15163
15164         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15165         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15166         touch $DIR/$tdir/foo_161c
15167         touch $DIR/$tdir/bar_161c
15168         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15169         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15170         changelog_dump | grep RENME | tail -n 5
15171         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15172         changelog_clear 0 || error "changelog_clear failed"
15173         if [ x$flags != "x0x0" ]; then
15174                 error "flag $flags is not 0x0"
15175         fi
15176         echo "rename overwrite a target having nlink > 1," \
15177                 "changelog record has flags of $flags"
15178
15179         # rename doesn't overwrite a target (changelog flag 0x0)
15180         touch $DIR/$tdir/foo_161c
15181         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15182         changelog_dump | grep RENME | tail -n 5
15183         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15184         changelog_clear 0 || error "changelog_clear failed"
15185         if [ x$flags != "x0x0" ]; then
15186                 error "flag $flags is not 0x0"
15187         fi
15188         echo "rename doesn't overwrite a target," \
15189                 "changelog record has flags of $flags"
15190
15191         # define CLF_UNLINK_LAST 0x0001
15192         # unlink a file having nlink = 1 (changelog flag 0x1)
15193         rm -f $DIR/$tdir/foo2_161c
15194         changelog_dump | grep UNLNK | tail -n 5
15195         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15196         changelog_clear 0 || error "changelog_clear failed"
15197         if [ x$flags != "x0x1" ]; then
15198                 error "flag $flags is not 0x1"
15199         fi
15200         echo "unlink a file having nlink = 1," \
15201                 "changelog record has flags of $flags"
15202
15203         # unlink a file having nlink > 1 (changelog flag 0x0)
15204         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15205         rm -f $DIR/$tdir/foobar_161c
15206         changelog_dump | grep UNLNK | tail -n 5
15207         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15208         changelog_clear 0 || error "changelog_clear failed"
15209         if [ x$flags != "x0x0" ]; then
15210                 error "flag $flags is not 0x0"
15211         fi
15212         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15213 }
15214 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15215
15216 test_161d() {
15217         remote_mds_nodsh && skip "remote MDS with nodsh"
15218         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15219
15220         local pid
15221         local fid
15222
15223         changelog_register || error "changelog_register failed"
15224
15225         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15226         # interfer with $MOUNT/.lustre/fid/ access
15227         mkdir $DIR/$tdir
15228         [[ $? -eq 0 ]] || error "mkdir failed"
15229
15230         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15231         $LCTL set_param fail_loc=0x8000140c
15232         # 5s pause
15233         $LCTL set_param fail_val=5
15234
15235         # create file
15236         echo foofoo > $DIR/$tdir/$tfile &
15237         pid=$!
15238
15239         # wait for create to be delayed
15240         sleep 2
15241
15242         ps -p $pid
15243         [[ $? -eq 0 ]] || error "create should be blocked"
15244
15245         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15246         stack_trap "rm -f $tempfile"
15247         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15248         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15249         # some delay may occur during ChangeLog publishing and file read just
15250         # above, that could allow file write to happen finally
15251         [[ -s $tempfile ]] && echo "file should be empty"
15252
15253         $LCTL set_param fail_loc=0
15254
15255         wait $pid
15256         [[ $? -eq 0 ]] || error "create failed"
15257 }
15258 run_test 161d "create with concurrent .lustre/fid access"
15259
15260 check_path() {
15261         local expected="$1"
15262         shift
15263         local fid="$2"
15264
15265         local path
15266         path=$($LFS fid2path "$@")
15267         local rc=$?
15268
15269         if [ $rc -ne 0 ]; then
15270                 error "path looked up of '$expected' failed: rc=$rc"
15271         elif [ "$path" != "$expected" ]; then
15272                 error "path looked up '$path' instead of '$expected'"
15273         else
15274                 echo "FID '$fid' resolves to path '$path' as expected"
15275         fi
15276 }
15277
15278 test_162a() { # was test_162
15279         test_mkdir -p -c1 $DIR/$tdir/d2
15280         touch $DIR/$tdir/d2/$tfile
15281         touch $DIR/$tdir/d2/x1
15282         touch $DIR/$tdir/d2/x2
15283         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15284         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15285         # regular file
15286         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15287         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15288
15289         # softlink
15290         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15291         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15292         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15293
15294         # softlink to wrong file
15295         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15296         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15297         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15298
15299         # hardlink
15300         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15301         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15302         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15303         # fid2path dir/fsname should both work
15304         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15305         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15306
15307         # hardlink count: check that there are 2 links
15308         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15309         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15310
15311         # hardlink indexing: remove the first link
15312         rm $DIR/$tdir/d2/p/q/r/hlink
15313         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15314 }
15315 run_test 162a "path lookup sanity"
15316
15317 test_162b() {
15318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15319         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15320
15321         mkdir $DIR/$tdir
15322         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15323                                 error "create striped dir failed"
15324
15325         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15326                                         tail -n 1 | awk '{print $2}')
15327         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15328
15329         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15330         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15331
15332         # regular file
15333         for ((i=0;i<5;i++)); do
15334                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15335                         error "get fid for f$i failed"
15336                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15337
15338                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15339                         error "get fid for d$i failed"
15340                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15341         done
15342
15343         return 0
15344 }
15345 run_test 162b "striped directory path lookup sanity"
15346
15347 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15348 test_162c() {
15349         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15350                 skip "Need MDS version at least 2.7.51"
15351
15352         local lpath=$tdir.local
15353         local rpath=$tdir.remote
15354
15355         test_mkdir $DIR/$lpath
15356         test_mkdir $DIR/$rpath
15357
15358         for ((i = 0; i <= 101; i++)); do
15359                 lpath="$lpath/$i"
15360                 mkdir $DIR/$lpath
15361                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15362                         error "get fid for local directory $DIR/$lpath failed"
15363                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15364
15365                 rpath="$rpath/$i"
15366                 test_mkdir $DIR/$rpath
15367                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15368                         error "get fid for remote directory $DIR/$rpath failed"
15369                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15370         done
15371
15372         return 0
15373 }
15374 run_test 162c "fid2path works with paths 100 or more directories deep"
15375
15376 oalr_event_count() {
15377         local event="${1}"
15378         local trace="${2}"
15379
15380         awk -v name="${FSNAME}-OST0000" \
15381             -v event="${event}" \
15382             '$1 == "TRACE" && $2 == event && $3 == name' \
15383             "${trace}" |
15384         wc -l
15385 }
15386
15387 oalr_expect_event_count() {
15388         local event="${1}"
15389         local trace="${2}"
15390         local expect="${3}"
15391         local count
15392
15393         count=$(oalr_event_count "${event}" "${trace}")
15394         if ((count == expect)); then
15395                 return 0
15396         fi
15397
15398         error_noexit "${event} event count was '${count}', expected ${expect}"
15399         cat "${trace}" >&2
15400         exit 1
15401 }
15402
15403 cleanup_165() {
15404         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15405         stop ost1
15406         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15407 }
15408
15409 setup_165() {
15410         sync # Flush previous IOs so we can count log entries.
15411         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15412         stack_trap cleanup_165 EXIT
15413 }
15414
15415 test_165a() {
15416         local trace="/tmp/${tfile}.trace"
15417         local rc
15418         local count
15419
15420         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15421         setup_165
15422         sleep 5
15423
15424         do_facet ost1 ofd_access_log_reader --list
15425         stop ost1
15426
15427         do_facet ost1 killall -TERM ofd_access_log_reader
15428         wait
15429         rc=$?
15430
15431         if ((rc != 0)); then
15432                 error "ofd_access_log_reader exited with rc = '${rc}'"
15433         fi
15434
15435         # Parse trace file for discovery events:
15436         oalr_expect_event_count alr_log_add "${trace}" 1
15437         oalr_expect_event_count alr_log_eof "${trace}" 1
15438         oalr_expect_event_count alr_log_free "${trace}" 1
15439 }
15440 run_test 165a "ofd access log discovery"
15441
15442 test_165b() {
15443         local trace="/tmp/${tfile}.trace"
15444         local file="${DIR}/${tfile}"
15445         local pfid1
15446         local pfid2
15447         local -a entry
15448         local rc
15449         local count
15450         local size
15451         local flags
15452
15453         setup_165
15454
15455         lfs setstripe -c 1 -i 0 "${file}"
15456         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15457         do_facet ost1 ofd_access_log_reader --list
15458
15459         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15460         sleep 5
15461         do_facet ost1 killall -TERM ofd_access_log_reader
15462         wait
15463         rc=$?
15464
15465         if ((rc != 0)); then
15466                 error "ofd_access_log_reader exited with rc = '${rc}'"
15467         fi
15468
15469         oalr_expect_event_count alr_log_entry "${trace}" 1
15470
15471         pfid1=$($LFS path2fid "${file}")
15472
15473         # 1     2             3   4    5     6   7    8    9     10
15474         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15475         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15476
15477         echo "entry = '${entry[*]}'" >&2
15478
15479         pfid2=${entry[4]}
15480         if [[ "${pfid1}" != "${pfid2}" ]]; then
15481                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15482         fi
15483
15484         size=${entry[8]}
15485         if ((size != 1048576)); then
15486                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15487         fi
15488
15489         flags=${entry[10]}
15490         if [[ "${flags}" != "w" ]]; then
15491                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15492         fi
15493
15494         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15495         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c || error "cannot read '${file}'"
15496         sleep 5
15497         do_facet ost1 killall -TERM ofd_access_log_reader
15498         wait
15499         rc=$?
15500
15501         if ((rc != 0)); then
15502                 error "ofd_access_log_reader exited with rc = '${rc}'"
15503         fi
15504
15505         oalr_expect_event_count alr_log_entry "${trace}" 1
15506
15507         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
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 != 524288)); then
15517                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15518         fi
15519
15520         flags=${entry[10]}
15521         if [[ "${flags}" != "r" ]]; then
15522                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15523         fi
15524 }
15525 run_test 165b "ofd access log entries are produced and consumed"
15526
15527 test_165c() {
15528         local file="${DIR}/${tdir}/${tfile}"
15529         test_mkdir "${DIR}/${tdir}"
15530
15531         setup_165
15532
15533         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15534
15535         # 4096 / 64 = 64. Create twice as many entries.
15536         for ((i = 0; i < 128; i++)); do
15537                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c || error "cannot create file"
15538         done
15539
15540         sync
15541         do_facet ost1 ofd_access_log_reader --list
15542         unlinkmany  "${file}-%d" 128
15543 }
15544 run_test 165c "full ofd access logs do not block IOs"
15545
15546 oal_peek_entry_count() {
15547         do_facet ost1 ofd_access_log_reader --list | awk '$1 == "_entry_count:" { print $2; }'
15548 }
15549
15550 oal_expect_entry_count() {
15551         local entry_count=$(oal_peek_entry_count)
15552         local expect="$1"
15553
15554         if ((entry_count == expect)); then
15555                 return 0
15556         fi
15557
15558         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15559         do_facet ost1 ofd_access_log_reader --list >&2
15560         exit 1
15561 }
15562
15563 test_165d() {
15564         local trace="/tmp/${tfile}.trace"
15565         local file="${DIR}/${tdir}/${tfile}"
15566         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15567         local entry_count
15568         test_mkdir "${DIR}/${tdir}"
15569
15570         setup_165
15571         lfs setstripe -c 1 -i 0 "${file}"
15572
15573         do_facet ost1 lctl set_param "${param}=rw"
15574         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15575         oal_expect_entry_count 1
15576
15577         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15578         oal_expect_entry_count 2
15579
15580         do_facet ost1 lctl set_param "${param}=r"
15581         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15582         oal_expect_entry_count 2
15583
15584         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15585         oal_expect_entry_count 3
15586
15587         do_facet ost1 lctl set_param "${param}=w"
15588         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15589         oal_expect_entry_count 4
15590
15591         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15592         oal_expect_entry_count 4
15593
15594         do_facet ost1 lctl set_param "${param}=0"
15595         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15596         oal_expect_entry_count 4
15597
15598         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15599         oal_expect_entry_count 4
15600 }
15601 run_test 165d "ofd_access_log mask works"
15602
15603 test_169() {
15604         # do directio so as not to populate the page cache
15605         log "creating a 10 Mb file"
15606         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15607         log "starting reads"
15608         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15609         log "truncating the file"
15610         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15611         log "killing dd"
15612         kill %+ || true # reads might have finished
15613         echo "wait until dd is finished"
15614         wait
15615         log "removing the temporary file"
15616         rm -rf $DIR/$tfile || error "tmp file removal failed"
15617 }
15618 run_test 169 "parallel read and truncate should not deadlock"
15619
15620 test_170() {
15621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15622
15623         $LCTL clear     # bug 18514
15624         $LCTL debug_daemon start $TMP/${tfile}_log_good
15625         touch $DIR/$tfile
15626         $LCTL debug_daemon stop
15627         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15628                 error "sed failed to read log_good"
15629
15630         $LCTL debug_daemon start $TMP/${tfile}_log_good
15631         rm -rf $DIR/$tfile
15632         $LCTL debug_daemon stop
15633
15634         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15635                error "lctl df log_bad failed"
15636
15637         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15638         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15639
15640         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15641         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15642
15643         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15644                 error "bad_line good_line1 good_line2 are empty"
15645
15646         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15647         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15648         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15649
15650         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15651         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15652         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15653
15654         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15655                 error "bad_line_new good_line_new are empty"
15656
15657         local expected_good=$((good_line1 + good_line2*2))
15658
15659         rm -f $TMP/${tfile}*
15660         # LU-231, short malformed line may not be counted into bad lines
15661         if [ $bad_line -ne $bad_line_new ] &&
15662                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15663                 error "expected $bad_line bad lines, but got $bad_line_new"
15664                 return 1
15665         fi
15666
15667         if [ $expected_good -ne $good_line_new ]; then
15668                 error "expected $expected_good good lines, but got $good_line_new"
15669                 return 2
15670         fi
15671         true
15672 }
15673 run_test 170 "test lctl df to handle corrupted log ====================="
15674
15675 test_171() { # bug20592
15676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15677
15678         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15679         $LCTL set_param fail_loc=0x50e
15680         $LCTL set_param fail_val=3000
15681         multiop_bg_pause $DIR/$tfile O_s || true
15682         local MULTIPID=$!
15683         kill -USR1 $MULTIPID
15684         # cause log dump
15685         sleep 3
15686         wait $MULTIPID
15687         if dmesg | grep "recursive fault"; then
15688                 error "caught a recursive fault"
15689         fi
15690         $LCTL set_param fail_loc=0
15691         true
15692 }
15693 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15694
15695 # it would be good to share it with obdfilter-survey/iokit-libecho code
15696 setup_obdecho_osc () {
15697         local rc=0
15698         local ost_nid=$1
15699         local obdfilter_name=$2
15700         echo "Creating new osc for $obdfilter_name on $ost_nid"
15701         # make sure we can find loopback nid
15702         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15703
15704         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15705                            ${obdfilter_name}_osc_UUID || rc=2; }
15706         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15707                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15708         return $rc
15709 }
15710
15711 cleanup_obdecho_osc () {
15712         local obdfilter_name=$1
15713         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15714         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15715         return 0
15716 }
15717
15718 obdecho_test() {
15719         local OBD=$1
15720         local node=$2
15721         local pages=${3:-64}
15722         local rc=0
15723         local id
15724
15725         local count=10
15726         local obd_size=$(get_obd_size $node $OBD)
15727         local page_size=$(get_page_size $node)
15728         if [[ -n "$obd_size" ]]; then
15729                 local new_count=$((obd_size / (pages * page_size / 1024)))
15730                 [[ $new_count -ge $count ]] || count=$new_count
15731         fi
15732
15733         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15734         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15735                            rc=2; }
15736         if [ $rc -eq 0 ]; then
15737             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15738             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15739         fi
15740         echo "New object id is $id"
15741         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15742                            rc=4; }
15743         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15744                            "test_brw $count w v $pages $id" || rc=4; }
15745         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15746                            rc=4; }
15747         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15748                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15749         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15750                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15751         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15752         return $rc
15753 }
15754
15755 test_180a() {
15756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15757
15758         if ! module_loaded obdecho; then
15759                 load_module obdecho/obdecho &&
15760                         stack_trap "rmmod obdecho" EXIT ||
15761                         error "unable to load obdecho on client"
15762         fi
15763
15764         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15765         local host=$($LCTL get_param -n osc.$osc.import |
15766                      awk '/current_connection:/ { print $2 }' )
15767         local target=$($LCTL get_param -n osc.$osc.import |
15768                        awk '/target:/ { print $2 }' )
15769         target=${target%_UUID}
15770
15771         if [ -n "$target" ]; then
15772                 setup_obdecho_osc $host $target &&
15773                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15774                         { error "obdecho setup failed with $?"; return; }
15775
15776                 obdecho_test ${target}_osc client ||
15777                         error "obdecho_test failed on ${target}_osc"
15778         else
15779                 $LCTL get_param osc.$osc.import
15780                 error "there is no osc.$osc.import target"
15781         fi
15782 }
15783 run_test 180a "test obdecho on osc"
15784
15785 test_180b() {
15786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15787         remote_ost_nodsh && skip "remote OST with nodsh"
15788
15789         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15790                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15791                 error "failed to load module obdecho"
15792
15793         local target=$(do_facet ost1 $LCTL dl |
15794                        awk '/obdfilter/ { print $4; exit; }')
15795
15796         if [ -n "$target" ]; then
15797                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15798         else
15799                 do_facet ost1 $LCTL dl
15800                 error "there is no obdfilter target on ost1"
15801         fi
15802 }
15803 run_test 180b "test obdecho directly on obdfilter"
15804
15805 test_180c() { # LU-2598
15806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15807         remote_ost_nodsh && skip "remote OST with nodsh"
15808         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15809                 skip "Need MDS version at least 2.4.0"
15810
15811         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15812                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15813                 error "failed to load module obdecho"
15814
15815         local target=$(do_facet ost1 $LCTL dl |
15816                        awk '/obdfilter/ { print $4; exit; }')
15817
15818         if [ -n "$target" ]; then
15819                 local pages=16384 # 64MB bulk I/O RPC size
15820
15821                 obdecho_test "$target" ost1 "$pages" ||
15822                         error "obdecho_test with pages=$pages failed with $?"
15823         else
15824                 do_facet ost1 $LCTL dl
15825                 error "there is no obdfilter target on ost1"
15826         fi
15827 }
15828 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15829
15830 test_181() { # bug 22177
15831         test_mkdir $DIR/$tdir
15832         # create enough files to index the directory
15833         createmany -o $DIR/$tdir/foobar 4000
15834         # print attributes for debug purpose
15835         lsattr -d .
15836         # open dir
15837         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15838         MULTIPID=$!
15839         # remove the files & current working dir
15840         unlinkmany $DIR/$tdir/foobar 4000
15841         rmdir $DIR/$tdir
15842         kill -USR1 $MULTIPID
15843         wait $MULTIPID
15844         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15845         return 0
15846 }
15847 run_test 181 "Test open-unlinked dir ========================"
15848
15849 test_182() {
15850         local fcount=1000
15851         local tcount=10
15852
15853         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15854
15855         $LCTL set_param mdc.*.rpc_stats=clear
15856
15857         for (( i = 0; i < $tcount; i++ )) ; do
15858                 mkdir $DIR/$tdir/$i
15859         done
15860
15861         for (( i = 0; i < $tcount; i++ )) ; do
15862                 createmany -o $DIR/$tdir/$i/f- $fcount &
15863         done
15864         wait
15865
15866         for (( i = 0; i < $tcount; i++ )) ; do
15867                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15868         done
15869         wait
15870
15871         $LCTL get_param mdc.*.rpc_stats
15872
15873         rm -rf $DIR/$tdir
15874 }
15875 run_test 182 "Test parallel modify metadata operations ================"
15876
15877 test_183() { # LU-2275
15878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15879         remote_mds_nodsh && skip "remote MDS with nodsh"
15880         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15881                 skip "Need MDS version at least 2.3.56"
15882
15883         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15884         echo aaa > $DIR/$tdir/$tfile
15885
15886 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
15887         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
15888
15889         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
15890         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
15891
15892         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15893
15894         # Flush negative dentry cache
15895         touch $DIR/$tdir/$tfile
15896
15897         # We are not checking for any leaked references here, they'll
15898         # become evident next time we do cleanup with module unload.
15899         rm -rf $DIR/$tdir
15900 }
15901 run_test 183 "No crash or request leak in case of strange dispositions ========"
15902
15903 # test suite 184 is for LU-2016, LU-2017
15904 test_184a() {
15905         check_swap_layouts_support
15906
15907         dir0=$DIR/$tdir/$testnum
15908         test_mkdir -p -c1 $dir0
15909         ref1=/etc/passwd
15910         ref2=/etc/group
15911         file1=$dir0/f1
15912         file2=$dir0/f2
15913         $LFS setstripe -c1 $file1
15914         cp $ref1 $file1
15915         $LFS setstripe -c2 $file2
15916         cp $ref2 $file2
15917         gen1=$($LFS getstripe -g $file1)
15918         gen2=$($LFS getstripe -g $file2)
15919
15920         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
15921         gen=$($LFS getstripe -g $file1)
15922         [[ $gen1 != $gen ]] ||
15923                 "Layout generation on $file1 does not change"
15924         gen=$($LFS getstripe -g $file2)
15925         [[ $gen2 != $gen ]] ||
15926                 "Layout generation on $file2 does not change"
15927
15928         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
15929         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15930
15931         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
15932 }
15933 run_test 184a "Basic layout swap"
15934
15935 test_184b() {
15936         check_swap_layouts_support
15937
15938         dir0=$DIR/$tdir/$testnum
15939         mkdir -p $dir0 || error "creating dir $dir0"
15940         file1=$dir0/f1
15941         file2=$dir0/f2
15942         file3=$dir0/f3
15943         dir1=$dir0/d1
15944         dir2=$dir0/d2
15945         mkdir $dir1 $dir2
15946         $LFS setstripe -c1 $file1
15947         $LFS setstripe -c2 $file2
15948         $LFS setstripe -c1 $file3
15949         chown $RUNAS_ID $file3
15950         gen1=$($LFS getstripe -g $file1)
15951         gen2=$($LFS getstripe -g $file2)
15952
15953         $LFS swap_layouts $dir1 $dir2 &&
15954                 error "swap of directories layouts should fail"
15955         $LFS swap_layouts $dir1 $file1 &&
15956                 error "swap of directory and file layouts should fail"
15957         $RUNAS $LFS swap_layouts $file1 $file2 &&
15958                 error "swap of file we cannot write should fail"
15959         $LFS swap_layouts $file1 $file3 &&
15960                 error "swap of file with different owner should fail"
15961         /bin/true # to clear error code
15962 }
15963 run_test 184b "Forbidden layout swap (will generate errors)"
15964
15965 test_184c() {
15966         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
15967         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
15968         check_swap_layouts_support
15969         check_swap_layout_no_dom $DIR
15970
15971         local dir0=$DIR/$tdir/$testnum
15972         mkdir -p $dir0 || error "creating dir $dir0"
15973
15974         local ref1=$dir0/ref1
15975         local ref2=$dir0/ref2
15976         local file1=$dir0/file1
15977         local file2=$dir0/file2
15978         # create a file large enough for the concurrent test
15979         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
15980         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
15981         echo "ref file size: ref1($(stat -c %s $ref1))," \
15982              "ref2($(stat -c %s $ref2))"
15983
15984         cp $ref2 $file2
15985         dd if=$ref1 of=$file1 bs=16k &
15986         local DD_PID=$!
15987
15988         # Make sure dd starts to copy file
15989         while [ ! -f $file1 ]; do sleep 0.1; done
15990
15991         $LFS swap_layouts $file1 $file2
15992         local rc=$?
15993         wait $DD_PID
15994         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
15995         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
15996
15997         # how many bytes copied before swapping layout
15998         local copied=$(stat -c %s $file2)
15999         local remaining=$(stat -c %s $ref1)
16000         remaining=$((remaining - copied))
16001         echo "Copied $copied bytes before swapping layout..."
16002
16003         cmp -n $copied $file1 $ref2 | grep differ &&
16004                 error "Content mismatch [0, $copied) of ref2 and file1"
16005         cmp -n $copied $file2 $ref1 ||
16006                 error "Content mismatch [0, $copied) of ref1 and file2"
16007         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16008                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16009
16010         # clean up
16011         rm -f $ref1 $ref2 $file1 $file2
16012 }
16013 run_test 184c "Concurrent write and layout swap"
16014
16015 test_184d() {
16016         check_swap_layouts_support
16017         check_swap_layout_no_dom $DIR
16018         [ -z "$(which getfattr 2>/dev/null)" ] &&
16019                 skip_env "no getfattr command"
16020
16021         local file1=$DIR/$tdir/$tfile-1
16022         local file2=$DIR/$tdir/$tfile-2
16023         local file3=$DIR/$tdir/$tfile-3
16024         local lovea1
16025         local lovea2
16026
16027         mkdir -p $DIR/$tdir
16028         touch $file1 || error "create $file1 failed"
16029         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16030                 error "create $file2 failed"
16031         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16032                 error "create $file3 failed"
16033         lovea1=$(get_layout_param $file1)
16034
16035         $LFS swap_layouts $file2 $file3 ||
16036                 error "swap $file2 $file3 layouts failed"
16037         $LFS swap_layouts $file1 $file2 ||
16038                 error "swap $file1 $file2 layouts failed"
16039
16040         lovea2=$(get_layout_param $file2)
16041         echo "$lovea1"
16042         echo "$lovea2"
16043         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16044
16045         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16046         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16047 }
16048 run_test 184d "allow stripeless layouts swap"
16049
16050 test_184e() {
16051         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16052                 skip "Need MDS version at least 2.6.94"
16053         check_swap_layouts_support
16054         check_swap_layout_no_dom $DIR
16055         [ -z "$(which getfattr 2>/dev/null)" ] &&
16056                 skip_env "no getfattr command"
16057
16058         local file1=$DIR/$tdir/$tfile-1
16059         local file2=$DIR/$tdir/$tfile-2
16060         local file3=$DIR/$tdir/$tfile-3
16061         local lovea
16062
16063         mkdir -p $DIR/$tdir
16064         touch $file1 || error "create $file1 failed"
16065         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16066                 error "create $file2 failed"
16067         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16068                 error "create $file3 failed"
16069
16070         $LFS swap_layouts $file1 $file2 ||
16071                 error "swap $file1 $file2 layouts failed"
16072
16073         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16074         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16075
16076         echo 123 > $file1 || error "Should be able to write into $file1"
16077
16078         $LFS swap_layouts $file1 $file3 ||
16079                 error "swap $file1 $file3 layouts failed"
16080
16081         echo 123 > $file1 || error "Should be able to write into $file1"
16082
16083         rm -rf $file1 $file2 $file3
16084 }
16085 run_test 184e "Recreate layout after stripeless layout swaps"
16086
16087 test_184f() {
16088         # Create a file with name longer than sizeof(struct stat) ==
16089         # 144 to see if we can get chars from the file name to appear
16090         # in the returned striping. Note that 'f' == 0x66.
16091         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16092
16093         mkdir -p $DIR/$tdir
16094         mcreate $DIR/$tdir/$file
16095         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16096                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16097         fi
16098 }
16099 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16100
16101 test_185() { # LU-2441
16102         # LU-3553 - no volatile file support in old servers
16103         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16104                 skip "Need MDS version at least 2.3.60"
16105
16106         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16107         touch $DIR/$tdir/spoo
16108         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16109         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16110                 error "cannot create/write a volatile file"
16111         [ "$FILESET" == "" ] &&
16112         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16113                 error "FID is still valid after close"
16114
16115         multiop_bg_pause $DIR/$tdir vVw4096_c
16116         local multi_pid=$!
16117
16118         local OLD_IFS=$IFS
16119         IFS=":"
16120         local fidv=($fid)
16121         IFS=$OLD_IFS
16122         # assume that the next FID for this client is sequential, since stdout
16123         # is unfortunately eaten by multiop_bg_pause
16124         local n=$((${fidv[1]} + 1))
16125         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16126         if [ "$FILESET" == "" ]; then
16127                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16128                         error "FID is missing before close"
16129         fi
16130         kill -USR1 $multi_pid
16131         # 1 second delay, so if mtime change we will see it
16132         sleep 1
16133         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16134         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16135 }
16136 run_test 185 "Volatile file support"
16137
16138 function create_check_volatile() {
16139         local idx=$1
16140         local tgt
16141
16142         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16143         local PID=$!
16144         sleep 1
16145         local FID=$(cat /tmp/${tfile}.fid)
16146         [ "$FID" == "" ] && error "can't get FID for volatile"
16147         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16148         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16149         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16150         kill -USR1 $PID
16151         wait
16152         sleep 1
16153         cancel_lru_locks mdc # flush opencache
16154         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16155         return 0
16156 }
16157
16158 test_185a(){
16159         # LU-12516 - volatile creation via .lustre
16160         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16161                 skip "Need MDS version at least 2.3.55"
16162
16163         create_check_volatile 0
16164         [ $MDSCOUNT -lt 2 ] && return 0
16165
16166         # DNE case
16167         create_check_volatile 1
16168
16169         return 0
16170 }
16171 run_test 185a "Volatile file creation in .lustre/fid/"
16172
16173 test_187a() {
16174         remote_mds_nodsh && skip "remote MDS with nodsh"
16175         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16176                 skip "Need MDS version at least 2.3.0"
16177
16178         local dir0=$DIR/$tdir/$testnum
16179         mkdir -p $dir0 || error "creating dir $dir0"
16180
16181         local file=$dir0/file1
16182         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16183         local dv1=$($LFS data_version $file)
16184         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16185         local dv2=$($LFS data_version $file)
16186         [[ $dv1 != $dv2 ]] ||
16187                 error "data version did not change on write $dv1 == $dv2"
16188
16189         # clean up
16190         rm -f $file1
16191 }
16192 run_test 187a "Test data version change"
16193
16194 test_187b() {
16195         remote_mds_nodsh && skip "remote MDS with nodsh"
16196         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16197                 skip "Need MDS version at least 2.3.0"
16198
16199         local dir0=$DIR/$tdir/$testnum
16200         mkdir -p $dir0 || error "creating dir $dir0"
16201
16202         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16203         [[ ${DV[0]} != ${DV[1]} ]] ||
16204                 error "data version did not change on write"\
16205                       " ${DV[0]} == ${DV[1]}"
16206
16207         # clean up
16208         rm -f $file1
16209 }
16210 run_test 187b "Test data version change on volatile file"
16211
16212 test_200() {
16213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16214         remote_mgs_nodsh && skip "remote MGS with nodsh"
16215         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16216
16217         local POOL=${POOL:-cea1}
16218         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16219         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16220         # Pool OST targets
16221         local first_ost=0
16222         local last_ost=$(($OSTCOUNT - 1))
16223         local ost_step=2
16224         local ost_list=$(seq $first_ost $ost_step $last_ost)
16225         local ost_range="$first_ost $last_ost $ost_step"
16226         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16227         local file_dir=$POOL_ROOT/file_tst
16228         local subdir=$test_path/subdir
16229         local rc=0
16230
16231         while : ; do
16232                 # former test_200a test_200b
16233                 pool_add $POOL                          || { rc=$? ; break; }
16234                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16235                 # former test_200c test_200d
16236                 mkdir -p $test_path
16237                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16238                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16239                 mkdir -p $subdir
16240                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16241                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16242                                                         || { rc=$? ; break; }
16243                 # former test_200e test_200f
16244                 local files=$((OSTCOUNT*3))
16245                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16246                                                         || { rc=$? ; break; }
16247                 pool_create_files $POOL $file_dir $files "$ost_list" \
16248                                                         || { rc=$? ; break; }
16249                 # former test_200g test_200h
16250                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16251                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16252
16253                 # former test_201a test_201b test_201c
16254                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16255
16256                 local f=$test_path/$tfile
16257                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16258                 pool_remove $POOL $f                    || { rc=$? ; break; }
16259                 break
16260         done
16261
16262         destroy_test_pools
16263
16264         return $rc
16265 }
16266 run_test 200 "OST pools"
16267
16268 # usage: default_attr <count | size | offset>
16269 default_attr() {
16270         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16271 }
16272
16273 # usage: check_default_stripe_attr
16274 check_default_stripe_attr() {
16275         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16276         case $1 in
16277         --stripe-count|-c)
16278                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16279         --stripe-size|-S)
16280                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16281         --stripe-index|-i)
16282                 EXPECTED=-1;;
16283         *)
16284                 error "unknown getstripe attr '$1'"
16285         esac
16286
16287         [ $ACTUAL == $EXPECTED ] ||
16288                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16289 }
16290
16291 test_204a() {
16292         test_mkdir $DIR/$tdir
16293         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16294
16295         check_default_stripe_attr --stripe-count
16296         check_default_stripe_attr --stripe-size
16297         check_default_stripe_attr --stripe-index
16298 }
16299 run_test 204a "Print default stripe attributes"
16300
16301 test_204b() {
16302         test_mkdir $DIR/$tdir
16303         $LFS setstripe --stripe-count 1 $DIR/$tdir
16304
16305         check_default_stripe_attr --stripe-size
16306         check_default_stripe_attr --stripe-index
16307 }
16308 run_test 204b "Print default stripe size and offset"
16309
16310 test_204c() {
16311         test_mkdir $DIR/$tdir
16312         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16313
16314         check_default_stripe_attr --stripe-count
16315         check_default_stripe_attr --stripe-index
16316 }
16317 run_test 204c "Print default stripe count and offset"
16318
16319 test_204d() {
16320         test_mkdir $DIR/$tdir
16321         $LFS setstripe --stripe-index 0 $DIR/$tdir
16322
16323         check_default_stripe_attr --stripe-count
16324         check_default_stripe_attr --stripe-size
16325 }
16326 run_test 204d "Print default stripe count and size"
16327
16328 test_204e() {
16329         test_mkdir $DIR/$tdir
16330         $LFS setstripe -d $DIR/$tdir
16331
16332         check_default_stripe_attr --stripe-count --raw
16333         check_default_stripe_attr --stripe-size --raw
16334         check_default_stripe_attr --stripe-index --raw
16335 }
16336 run_test 204e "Print raw stripe attributes"
16337
16338 test_204f() {
16339         test_mkdir $DIR/$tdir
16340         $LFS setstripe --stripe-count 1 $DIR/$tdir
16341
16342         check_default_stripe_attr --stripe-size --raw
16343         check_default_stripe_attr --stripe-index --raw
16344 }
16345 run_test 204f "Print raw stripe size and offset"
16346
16347 test_204g() {
16348         test_mkdir $DIR/$tdir
16349         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16350
16351         check_default_stripe_attr --stripe-count --raw
16352         check_default_stripe_attr --stripe-index --raw
16353 }
16354 run_test 204g "Print raw stripe count and offset"
16355
16356 test_204h() {
16357         test_mkdir $DIR/$tdir
16358         $LFS setstripe --stripe-index 0 $DIR/$tdir
16359
16360         check_default_stripe_attr --stripe-count --raw
16361         check_default_stripe_attr --stripe-size --raw
16362 }
16363 run_test 204h "Print raw stripe count and size"
16364
16365 # Figure out which job scheduler is being used, if any,
16366 # or use a fake one
16367 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16368         JOBENV=SLURM_JOB_ID
16369 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16370         JOBENV=LSB_JOBID
16371 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16372         JOBENV=PBS_JOBID
16373 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16374         JOBENV=LOADL_STEP_ID
16375 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16376         JOBENV=JOB_ID
16377 else
16378         $LCTL list_param jobid_name > /dev/null 2>&1
16379         if [ $? -eq 0 ]; then
16380                 JOBENV=nodelocal
16381         else
16382                 JOBENV=FAKE_JOBID
16383         fi
16384 fi
16385 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16386
16387 verify_jobstats() {
16388         local cmd=($1)
16389         shift
16390         local facets="$@"
16391
16392 # we don't really need to clear the stats for this test to work, since each
16393 # command has a unique jobid, but it makes debugging easier if needed.
16394 #       for facet in $facets; do
16395 #               local dev=$(convert_facet2label $facet)
16396 #               # clear old jobstats
16397 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16398 #       done
16399
16400         # use a new JobID for each test, or we might see an old one
16401         [ "$JOBENV" = "FAKE_JOBID" ] &&
16402                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16403
16404         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16405
16406         [ "$JOBENV" = "nodelocal" ] && {
16407                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16408                 $LCTL set_param jobid_name=$FAKE_JOBID
16409                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16410         }
16411
16412         log "Test: ${cmd[*]}"
16413         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16414
16415         if [ $JOBENV = "FAKE_JOBID" ]; then
16416                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16417         else
16418                 ${cmd[*]}
16419         fi
16420
16421         # all files are created on OST0000
16422         for facet in $facets; do
16423                 local stats="*.$(convert_facet2label $facet).job_stats"
16424
16425                 # strip out libtool wrappers for in-tree executables
16426                 if [ $(do_facet $facet lctl get_param $stats |
16427                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16428                         do_facet $facet lctl get_param $stats
16429                         error "No jobstats for $JOBVAL found on $facet::$stats"
16430                 fi
16431         done
16432 }
16433
16434 jobstats_set() {
16435         local new_jobenv=$1
16436
16437         set_persistent_param_and_check client "jobid_var" \
16438                 "$FSNAME.sys.jobid_var" $new_jobenv
16439 }
16440
16441 test_205a() { # Job stats
16442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16443         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16444                 skip "Need MDS version with at least 2.7.1"
16445         remote_mgs_nodsh && skip "remote MGS with nodsh"
16446         remote_mds_nodsh && skip "remote MDS with nodsh"
16447         remote_ost_nodsh && skip "remote OST with nodsh"
16448         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16449                 skip "Server doesn't support jobstats"
16450         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16451
16452         local old_jobenv=$($LCTL get_param -n jobid_var)
16453         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16454
16455         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16456                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16457         else
16458                 stack_trap "do_facet mgs $PERM_CMD \
16459                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16460         fi
16461         changelog_register
16462
16463         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16464                                 mdt.*.job_cleanup_interval | head -n 1)
16465         local new_interval=5
16466         do_facet $SINGLEMDS \
16467                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16468         stack_trap "do_facet $SINGLEMDS \
16469                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16470         local start=$SECONDS
16471
16472         local cmd
16473         # mkdir
16474         cmd="mkdir $DIR/$tdir"
16475         verify_jobstats "$cmd" "$SINGLEMDS"
16476         # rmdir
16477         cmd="rmdir $DIR/$tdir"
16478         verify_jobstats "$cmd" "$SINGLEMDS"
16479         # mkdir on secondary MDT
16480         if [ $MDSCOUNT -gt 1 ]; then
16481                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16482                 verify_jobstats "$cmd" "mds2"
16483         fi
16484         # mknod
16485         cmd="mknod $DIR/$tfile c 1 3"
16486         verify_jobstats "$cmd" "$SINGLEMDS"
16487         # unlink
16488         cmd="rm -f $DIR/$tfile"
16489         verify_jobstats "$cmd" "$SINGLEMDS"
16490         # create all files on OST0000 so verify_jobstats can find OST stats
16491         # open & close
16492         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16493         verify_jobstats "$cmd" "$SINGLEMDS"
16494         # setattr
16495         cmd="touch $DIR/$tfile"
16496         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16497         # write
16498         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16499         verify_jobstats "$cmd" "ost1"
16500         # read
16501         cancel_lru_locks osc
16502         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16503         verify_jobstats "$cmd" "ost1"
16504         # truncate
16505         cmd="$TRUNCATE $DIR/$tfile 0"
16506         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16507         # rename
16508         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16509         verify_jobstats "$cmd" "$SINGLEMDS"
16510         # jobstats expiry - sleep until old stats should be expired
16511         local left=$((new_interval + 5 - (SECONDS - start)))
16512         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16513                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16514                         "0" $left
16515         cmd="mkdir $DIR/$tdir.expire"
16516         verify_jobstats "$cmd" "$SINGLEMDS"
16517         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16518             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16519
16520         # Ensure that jobid are present in changelog (if supported by MDS)
16521         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16522                 changelog_dump | tail -10
16523                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16524                 [ $jobids -eq 9 ] ||
16525                         error "Wrong changelog jobid count $jobids != 9"
16526
16527                 # LU-5862
16528                 JOBENV="disable"
16529                 jobstats_set $JOBENV
16530                 touch $DIR/$tfile
16531                 changelog_dump | grep $tfile
16532                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16533                 [ $jobids -eq 0 ] ||
16534                         error "Unexpected jobids when jobid_var=$JOBENV"
16535         fi
16536
16537         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
16538         JOBENV="JOBCOMPLEX"
16539         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16540
16541         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16542 }
16543 run_test 205a "Verify job stats"
16544
16545 # LU-13117, LU-13597
16546 test_205b() {
16547         job_stats="mdt.*.job_stats"
16548         $LCTL set_param $job_stats=clear
16549         $LCTL set_param jobid_var=USER jobid_name="%e.%u"
16550         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16551         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16552                 grep "job_id:.*foolish" &&
16553                         error "Unexpected jobid found"
16554         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16555                 grep "open:.*min.*max.*sum" ||
16556                         error "wrong job_stats format found"
16557 }
16558 run_test 205b "Verify job stats jobid and output format"
16559
16560 # LU-13733
16561 test_205c() {
16562         $LCTL set_param llite.*.stats=0
16563         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16564         $LCTL get_param llite.*.stats
16565         $LCTL get_param llite.*.stats | grep \
16566                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16567                         error "wrong client stats format found"
16568 }
16569 run_test 205c "Verify client stats format"
16570
16571 # LU-1480, LU-1773 and LU-1657
16572 test_206() {
16573         mkdir -p $DIR/$tdir
16574         $LFS setstripe -c -1 $DIR/$tdir
16575 #define OBD_FAIL_LOV_INIT 0x1403
16576         $LCTL set_param fail_loc=0xa0001403
16577         $LCTL set_param fail_val=1
16578         touch $DIR/$tdir/$tfile || true
16579 }
16580 run_test 206 "fail lov_init_raid0() doesn't lbug"
16581
16582 test_207a() {
16583         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16584         local fsz=`stat -c %s $DIR/$tfile`
16585         cancel_lru_locks mdc
16586
16587         # do not return layout in getattr intent
16588 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16589         $LCTL set_param fail_loc=0x170
16590         local sz=`stat -c %s $DIR/$tfile`
16591
16592         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16593
16594         rm -rf $DIR/$tfile
16595 }
16596 run_test 207a "can refresh layout at glimpse"
16597
16598 test_207b() {
16599         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16600         local cksum=`md5sum $DIR/$tfile`
16601         local fsz=`stat -c %s $DIR/$tfile`
16602         cancel_lru_locks mdc
16603         cancel_lru_locks osc
16604
16605         # do not return layout in getattr intent
16606 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16607         $LCTL set_param fail_loc=0x171
16608
16609         # it will refresh layout after the file is opened but before read issues
16610         echo checksum is "$cksum"
16611         echo "$cksum" |md5sum -c --quiet || error "file differs"
16612
16613         rm -rf $DIR/$tfile
16614 }
16615 run_test 207b "can refresh layout at open"
16616
16617 test_208() {
16618         # FIXME: in this test suite, only RD lease is used. This is okay
16619         # for now as only exclusive open is supported. After generic lease
16620         # is done, this test suite should be revised. - Jinshan
16621
16622         remote_mds_nodsh && skip "remote MDS with nodsh"
16623         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16624                 skip "Need MDS version at least 2.4.52"
16625
16626         echo "==== test 1: verify get lease work"
16627         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16628
16629         echo "==== test 2: verify lease can be broken by upcoming open"
16630         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16631         local PID=$!
16632         sleep 1
16633
16634         $MULTIOP $DIR/$tfile oO_RDONLY:c
16635         kill -USR1 $PID && wait $PID || error "break lease error"
16636
16637         echo "==== test 3: verify lease can't be granted if an open already exists"
16638         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16639         local PID=$!
16640         sleep 1
16641
16642         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16643         kill -USR1 $PID && wait $PID || error "open file error"
16644
16645         echo "==== test 4: lease can sustain over recovery"
16646         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16647         PID=$!
16648         sleep 1
16649
16650         fail mds1
16651
16652         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16653
16654         echo "==== test 5: lease broken can't be regained by replay"
16655         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16656         PID=$!
16657         sleep 1
16658
16659         # open file to break lease and then recovery
16660         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16661         fail mds1
16662
16663         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16664
16665         rm -f $DIR/$tfile
16666 }
16667 run_test 208 "Exclusive open"
16668
16669 test_209() {
16670         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16671                 skip_env "must have disp_stripe"
16672
16673         touch $DIR/$tfile
16674         sync; sleep 5; sync;
16675
16676         echo 3 > /proc/sys/vm/drop_caches
16677         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16678                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16679         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16680
16681         # open/close 500 times
16682         for i in $(seq 500); do
16683                 cat $DIR/$tfile
16684         done
16685
16686         echo 3 > /proc/sys/vm/drop_caches
16687         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16688                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16689         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16690
16691         echo "before: $req_before, after: $req_after"
16692         [ $((req_after - req_before)) -ge 300 ] &&
16693                 error "open/close requests are not freed"
16694         return 0
16695 }
16696 run_test 209 "read-only open/close requests should be freed promptly"
16697
16698 test_210() {
16699         local pid
16700
16701         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16702         pid=$!
16703         sleep 1
16704
16705         $LFS getstripe $DIR/$tfile
16706         kill -USR1 $pid
16707         wait $pid || error "multiop failed"
16708
16709         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16710         pid=$!
16711         sleep 1
16712
16713         $LFS getstripe $DIR/$tfile
16714         kill -USR1 $pid
16715         wait $pid || error "multiop failed"
16716 }
16717 run_test 210 "lfs getstripe does not break leases"
16718
16719 test_212() {
16720         size=`date +%s`
16721         size=$((size % 8192 + 1))
16722         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16723         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16724         rm -f $DIR/f212 $DIR/f212.xyz
16725 }
16726 run_test 212 "Sendfile test ============================================"
16727
16728 test_213() {
16729         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16730         cancel_lru_locks osc
16731         lctl set_param fail_loc=0x8000040f
16732         # generate a read lock
16733         cat $DIR/$tfile > /dev/null
16734         # write to the file, it will try to cancel the above read lock.
16735         cat /etc/hosts >> $DIR/$tfile
16736 }
16737 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16738
16739 test_214() { # for bug 20133
16740         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16741         for (( i=0; i < 340; i++ )) ; do
16742                 touch $DIR/$tdir/d214c/a$i
16743         done
16744
16745         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16746         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16747         ls $DIR/d214c || error "ls $DIR/d214c failed"
16748         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16749         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16750 }
16751 run_test 214 "hash-indexed directory test - bug 20133"
16752
16753 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16754 create_lnet_proc_files() {
16755         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16756 }
16757
16758 # counterpart of create_lnet_proc_files
16759 remove_lnet_proc_files() {
16760         rm -f $TMP/lnet_$1.sys
16761 }
16762
16763 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16764 # 3rd arg as regexp for body
16765 check_lnet_proc_stats() {
16766         local l=$(cat "$TMP/lnet_$1" |wc -l)
16767         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16768
16769         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16770 }
16771
16772 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16773 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16774 # optional and can be regexp for 2nd line (lnet.routes case)
16775 check_lnet_proc_entry() {
16776         local blp=2          # blp stands for 'position of 1st line of body'
16777         [ -z "$5" ] || blp=3 # lnet.routes case
16778
16779         local l=$(cat "$TMP/lnet_$1" |wc -l)
16780         # subtracting one from $blp because the body can be empty
16781         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16782
16783         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16784                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16785
16786         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16787                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16788
16789         # bail out if any unexpected line happened
16790         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16791         [ "$?" != 0 ] || error "$2 misformatted"
16792 }
16793
16794 test_215() { # for bugs 18102, 21079, 21517
16795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16796
16797         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16798         local P='[1-9][0-9]*'           # positive numeric
16799         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16800         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16801         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16802         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16803
16804         local L1 # regexp for 1st line
16805         local L2 # regexp for 2nd line (optional)
16806         local BR # regexp for the rest (body)
16807
16808         # lnet.stats should look as 11 space-separated non-negative numerics
16809         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16810         create_lnet_proc_files "stats"
16811         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16812         remove_lnet_proc_files "stats"
16813
16814         # lnet.routes should look like this:
16815         # Routing disabled/enabled
16816         # net hops priority state router
16817         # where net is a string like tcp0, hops > 0, priority >= 0,
16818         # state is up/down,
16819         # router is a string like 192.168.1.1@tcp2
16820         L1="^Routing (disabled|enabled)$"
16821         L2="^net +hops +priority +state +router$"
16822         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16823         create_lnet_proc_files "routes"
16824         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16825         remove_lnet_proc_files "routes"
16826
16827         # lnet.routers should look like this:
16828         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16829         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16830         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16831         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16832         L1="^ref +rtr_ref +alive +router$"
16833         BR="^$P +$P +(up|down) +$NID$"
16834         create_lnet_proc_files "routers"
16835         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16836         remove_lnet_proc_files "routers"
16837
16838         # lnet.peers should look like this:
16839         # nid refs state last max rtr min tx min queue
16840         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16841         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16842         # numeric (0 or >0 or <0), queue >= 0.
16843         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16844         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16845         create_lnet_proc_files "peers"
16846         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16847         remove_lnet_proc_files "peers"
16848
16849         # lnet.buffers  should look like this:
16850         # pages count credits min
16851         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16852         L1="^pages +count +credits +min$"
16853         BR="^ +$N +$N +$I +$I$"
16854         create_lnet_proc_files "buffers"
16855         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16856         remove_lnet_proc_files "buffers"
16857
16858         # lnet.nis should look like this:
16859         # nid status alive refs peer rtr max tx min
16860         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16861         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16862         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16863         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16864         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16865         create_lnet_proc_files "nis"
16866         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16867         remove_lnet_proc_files "nis"
16868
16869         # can we successfully write to lnet.stats?
16870         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
16871 }
16872 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
16873
16874 test_216() { # bug 20317
16875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16876         remote_ost_nodsh && skip "remote OST with nodsh"
16877
16878         local node
16879         local facets=$(get_facets OST)
16880         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16881
16882         save_lustre_params client "osc.*.contention_seconds" > $p
16883         save_lustre_params $facets \
16884                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
16885         save_lustre_params $facets \
16886                 "ldlm.namespaces.filter-*.contended_locks" >> $p
16887         save_lustre_params $facets \
16888                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
16889         clear_stats osc.*.osc_stats
16890
16891         # agressive lockless i/o settings
16892         do_nodes $(comma_list $(osts_nodes)) \
16893                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
16894                         ldlm.namespaces.filter-*.contended_locks=0 \
16895                         ldlm.namespaces.filter-*.contention_seconds=60"
16896         lctl set_param -n osc.*.contention_seconds=60
16897
16898         $DIRECTIO write $DIR/$tfile 0 10 4096
16899         $CHECKSTAT -s 40960 $DIR/$tfile
16900
16901         # disable lockless i/o
16902         do_nodes $(comma_list $(osts_nodes)) \
16903                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
16904                         ldlm.namespaces.filter-*.contended_locks=32 \
16905                         ldlm.namespaces.filter-*.contention_seconds=0"
16906         lctl set_param -n osc.*.contention_seconds=0
16907         clear_stats osc.*.osc_stats
16908
16909         dd if=/dev/zero of=$DIR/$tfile count=0
16910         $CHECKSTAT -s 0 $DIR/$tfile
16911
16912         restore_lustre_params <$p
16913         rm -f $p
16914         rm $DIR/$tfile
16915 }
16916 run_test 216 "check lockless direct write updates file size and kms correctly"
16917
16918 test_217() { # bug 22430
16919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16920
16921         local node
16922         local nid
16923
16924         for node in $(nodes_list); do
16925                 nid=$(host_nids_address $node $NETTYPE)
16926                 if [[ $nid = *-* ]] ; then
16927                         echo "lctl ping $(h2nettype $nid)"
16928                         lctl ping $(h2nettype $nid)
16929                 else
16930                         echo "skipping $node (no hyphen detected)"
16931                 fi
16932         done
16933 }
16934 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
16935
16936 test_218() {
16937        # do directio so as not to populate the page cache
16938        log "creating a 10 Mb file"
16939        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
16940        log "starting reads"
16941        dd if=$DIR/$tfile of=/dev/null bs=4096 &
16942        log "truncating the file"
16943        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
16944        log "killing dd"
16945        kill %+ || true # reads might have finished
16946        echo "wait until dd is finished"
16947        wait
16948        log "removing the temporary file"
16949        rm -rf $DIR/$tfile || error "tmp file removal failed"
16950 }
16951 run_test 218 "parallel read and truncate should not deadlock"
16952
16953 test_219() {
16954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16955
16956         # write one partial page
16957         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
16958         # set no grant so vvp_io_commit_write will do sync write
16959         $LCTL set_param fail_loc=0x411
16960         # write a full page at the end of file
16961         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
16962
16963         $LCTL set_param fail_loc=0
16964         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
16965         $LCTL set_param fail_loc=0x411
16966         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
16967
16968         # LU-4201
16969         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
16970         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
16971 }
16972 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
16973
16974 test_220() { #LU-325
16975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16976         remote_ost_nodsh && skip "remote OST with nodsh"
16977         remote_mds_nodsh && skip "remote MDS with nodsh"
16978         remote_mgs_nodsh && skip "remote MGS with nodsh"
16979
16980         local OSTIDX=0
16981
16982         # create on MDT0000 so the last_id and next_id are correct
16983         mkdir $DIR/$tdir
16984         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
16985         OST=${OST%_UUID}
16986
16987         # on the mdt's osc
16988         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
16989         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
16990                         osp.$mdtosc_proc1.prealloc_last_id)
16991         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
16992                         osp.$mdtosc_proc1.prealloc_next_id)
16993
16994         $LFS df -i
16995
16996         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
16997         #define OBD_FAIL_OST_ENOINO              0x229
16998         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
16999         create_pool $FSNAME.$TESTNAME || return 1
17000         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17001
17002         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17003
17004         MDSOBJS=$((last_id - next_id))
17005         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17006
17007         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17008         echo "OST still has $count kbytes free"
17009
17010         echo "create $MDSOBJS files @next_id..."
17011         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17012
17013         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17014                         osp.$mdtosc_proc1.prealloc_last_id)
17015         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17016                         osp.$mdtosc_proc1.prealloc_next_id)
17017
17018         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17019         $LFS df -i
17020
17021         echo "cleanup..."
17022
17023         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17024         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17025
17026         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17027                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17028         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17029                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17030         echo "unlink $MDSOBJS files @$next_id..."
17031         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17032 }
17033 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17034
17035 test_221() {
17036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17037
17038         dd if=`which date` of=$MOUNT/date oflag=sync
17039         chmod +x $MOUNT/date
17040
17041         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17042         $LCTL set_param fail_loc=0x80001401
17043
17044         $MOUNT/date > /dev/null
17045         rm -f $MOUNT/date
17046 }
17047 run_test 221 "make sure fault and truncate race to not cause OOM"
17048
17049 test_222a () {
17050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17051
17052         rm -rf $DIR/$tdir
17053         test_mkdir $DIR/$tdir
17054         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17055         createmany -o $DIR/$tdir/$tfile 10
17056         cancel_lru_locks mdc
17057         cancel_lru_locks osc
17058         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17059         $LCTL set_param fail_loc=0x31a
17060         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17061         $LCTL set_param fail_loc=0
17062         rm -r $DIR/$tdir
17063 }
17064 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17065
17066 test_222b () {
17067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17068
17069         rm -rf $DIR/$tdir
17070         test_mkdir $DIR/$tdir
17071         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17072         createmany -o $DIR/$tdir/$tfile 10
17073         cancel_lru_locks mdc
17074         cancel_lru_locks osc
17075         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17076         $LCTL set_param fail_loc=0x31a
17077         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17078         $LCTL set_param fail_loc=0
17079 }
17080 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17081
17082 test_223 () {
17083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17084
17085         rm -rf $DIR/$tdir
17086         test_mkdir $DIR/$tdir
17087         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17088         createmany -o $DIR/$tdir/$tfile 10
17089         cancel_lru_locks mdc
17090         cancel_lru_locks osc
17091         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17092         $LCTL set_param fail_loc=0x31b
17093         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17094         $LCTL set_param fail_loc=0
17095         rm -r $DIR/$tdir
17096 }
17097 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17098
17099 test_224a() { # LU-1039, MRP-303
17100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17101
17102         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17103         $LCTL set_param fail_loc=0x508
17104         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17105         $LCTL set_param fail_loc=0
17106         df $DIR
17107 }
17108 run_test 224a "Don't panic on bulk IO failure"
17109
17110 test_224b() { # LU-1039, MRP-303
17111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17112
17113         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17114         cancel_lru_locks osc
17115         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17116         $LCTL set_param fail_loc=0x515
17117         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17118         $LCTL set_param fail_loc=0
17119         df $DIR
17120 }
17121 run_test 224b "Don't panic on bulk IO failure"
17122
17123 test_224c() { # LU-6441
17124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17125         remote_mds_nodsh && skip "remote MDS with nodsh"
17126
17127         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17128         save_writethrough $p
17129         set_cache writethrough on
17130
17131         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17132         local at_max=$($LCTL get_param -n at_max)
17133         local timeout=$($LCTL get_param -n timeout)
17134         local test_at="at_max"
17135         local param_at="$FSNAME.sys.at_max"
17136         local test_timeout="timeout"
17137         local param_timeout="$FSNAME.sys.timeout"
17138
17139         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17140
17141         set_persistent_param_and_check client "$test_at" "$param_at" 0
17142         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17143
17144         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17145         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17146         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17147         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17148         sync
17149         do_facet ost1 "$LCTL set_param fail_loc=0"
17150
17151         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17152         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17153                 $timeout
17154
17155         $LCTL set_param -n $pages_per_rpc
17156         restore_lustre_params < $p
17157         rm -f $p
17158 }
17159 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17160
17161 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17162 test_225a () {
17163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17164         if [ -z ${MDSSURVEY} ]; then
17165                 skip_env "mds-survey not found"
17166         fi
17167         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17168                 skip "Need MDS version at least 2.2.51"
17169
17170         local mds=$(facet_host $SINGLEMDS)
17171         local target=$(do_nodes $mds 'lctl dl' |
17172                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17173
17174         local cmd1="file_count=1000 thrhi=4"
17175         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17176         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17177         local cmd="$cmd1 $cmd2 $cmd3"
17178
17179         rm -f ${TMP}/mds_survey*
17180         echo + $cmd
17181         eval $cmd || error "mds-survey with zero-stripe failed"
17182         cat ${TMP}/mds_survey*
17183         rm -f ${TMP}/mds_survey*
17184 }
17185 run_test 225a "Metadata survey sanity with zero-stripe"
17186
17187 test_225b () {
17188         if [ -z ${MDSSURVEY} ]; then
17189                 skip_env "mds-survey not found"
17190         fi
17191         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17192                 skip "Need MDS version at least 2.2.51"
17193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17194         remote_mds_nodsh && skip "remote MDS with nodsh"
17195         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17196                 skip_env "Need to mount OST to test"
17197         fi
17198
17199         local mds=$(facet_host $SINGLEMDS)
17200         local target=$(do_nodes $mds 'lctl dl' |
17201                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17202
17203         local cmd1="file_count=1000 thrhi=4"
17204         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17205         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17206         local cmd="$cmd1 $cmd2 $cmd3"
17207
17208         rm -f ${TMP}/mds_survey*
17209         echo + $cmd
17210         eval $cmd || error "mds-survey with stripe_count failed"
17211         cat ${TMP}/mds_survey*
17212         rm -f ${TMP}/mds_survey*
17213 }
17214 run_test 225b "Metadata survey sanity with stripe_count = 1"
17215
17216 mcreate_path2fid () {
17217         local mode=$1
17218         local major=$2
17219         local minor=$3
17220         local name=$4
17221         local desc=$5
17222         local path=$DIR/$tdir/$name
17223         local fid
17224         local rc
17225         local fid_path
17226
17227         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17228                 error "cannot create $desc"
17229
17230         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17231         rc=$?
17232         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17233
17234         fid_path=$($LFS fid2path $MOUNT $fid)
17235         rc=$?
17236         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17237
17238         [ "$path" == "$fid_path" ] ||
17239                 error "fid2path returned $fid_path, expected $path"
17240
17241         echo "pass with $path and $fid"
17242 }
17243
17244 test_226a () {
17245         rm -rf $DIR/$tdir
17246         mkdir -p $DIR/$tdir
17247
17248         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17249         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17250         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17251         mcreate_path2fid 0040666 0 0 dir "directory"
17252         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17253         mcreate_path2fid 0100666 0 0 file "regular file"
17254         mcreate_path2fid 0120666 0 0 link "symbolic link"
17255         mcreate_path2fid 0140666 0 0 sock "socket"
17256 }
17257 run_test 226a "call path2fid and fid2path on files of all type"
17258
17259 test_226b () {
17260         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17261
17262         local MDTIDX=1
17263
17264         rm -rf $DIR/$tdir
17265         mkdir -p $DIR/$tdir
17266         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17267                 error "create remote directory failed"
17268         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17269         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17270                                 "character special file (null)"
17271         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17272                                 "character special file (no device)"
17273         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17274         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17275                                 "block special file (loop)"
17276         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17277         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17278         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17279 }
17280 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17281
17282 test_226c () {
17283         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17284         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17285                 skip "Need MDS version at least 2.13.55"
17286
17287         local submnt=/mnt/submnt
17288         local srcfile=/etc/passwd
17289         local dstfile=$submnt/passwd
17290         local path
17291         local fid
17292
17293         rm -rf $DIR/$tdir
17294         rm -rf $submnt
17295         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17296                 error "create remote directory failed"
17297         mkdir -p $submnt || error "create $submnt failed"
17298         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17299                 error "mount $submnt failed"
17300         stack_trap "umount $submnt" EXIT
17301
17302         cp $srcfile $dstfile
17303         fid=$($LFS path2fid $dstfile)
17304         path=$($LFS fid2path $submnt "$fid")
17305         [ "$path" = "$dstfile" ] ||
17306                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17307 }
17308 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17309
17310 # LU-1299 Executing or running ldd on a truncated executable does not
17311 # cause an out-of-memory condition.
17312 test_227() {
17313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17314         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17315
17316         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17317         chmod +x $MOUNT/date
17318
17319         $MOUNT/date > /dev/null
17320         ldd $MOUNT/date > /dev/null
17321         rm -f $MOUNT/date
17322 }
17323 run_test 227 "running truncated executable does not cause OOM"
17324
17325 # LU-1512 try to reuse idle OI blocks
17326 test_228a() {
17327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17328         remote_mds_nodsh && skip "remote MDS with nodsh"
17329         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17330
17331         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17332         local myDIR=$DIR/$tdir
17333
17334         mkdir -p $myDIR
17335         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17336         $LCTL set_param fail_loc=0x80001002
17337         createmany -o $myDIR/t- 10000
17338         $LCTL set_param fail_loc=0
17339         # The guard is current the largest FID holder
17340         touch $myDIR/guard
17341         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17342                     tr -d '[')
17343         local IDX=$(($SEQ % 64))
17344
17345         do_facet $SINGLEMDS sync
17346         # Make sure journal flushed.
17347         sleep 6
17348         local blk1=$(do_facet $SINGLEMDS \
17349                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17350                      grep Blockcount | awk '{print $4}')
17351
17352         # Remove old files, some OI blocks will become idle.
17353         unlinkmany $myDIR/t- 10000
17354         # Create new files, idle OI blocks should be reused.
17355         createmany -o $myDIR/t- 2000
17356         do_facet $SINGLEMDS sync
17357         # Make sure journal flushed.
17358         sleep 6
17359         local blk2=$(do_facet $SINGLEMDS \
17360                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17361                      grep Blockcount | awk '{print $4}')
17362
17363         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17364 }
17365 run_test 228a "try to reuse idle OI blocks"
17366
17367 test_228b() {
17368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17369         remote_mds_nodsh && skip "remote MDS with nodsh"
17370         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17371
17372         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17373         local myDIR=$DIR/$tdir
17374
17375         mkdir -p $myDIR
17376         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17377         $LCTL set_param fail_loc=0x80001002
17378         createmany -o $myDIR/t- 10000
17379         $LCTL set_param fail_loc=0
17380         # The guard is current the largest FID holder
17381         touch $myDIR/guard
17382         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17383                     tr -d '[')
17384         local IDX=$(($SEQ % 64))
17385
17386         do_facet $SINGLEMDS sync
17387         # Make sure journal flushed.
17388         sleep 6
17389         local blk1=$(do_facet $SINGLEMDS \
17390                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17391                      grep Blockcount | awk '{print $4}')
17392
17393         # Remove old files, some OI blocks will become idle.
17394         unlinkmany $myDIR/t- 10000
17395
17396         # stop the MDT
17397         stop $SINGLEMDS || error "Fail to stop MDT."
17398         # remount the MDT
17399         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17400
17401         df $MOUNT || error "Fail to df."
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 228b "idle OI blocks can be reused after MDT restart"
17414
17415 #LU-1881
17416 test_228c() {
17417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17418         remote_mds_nodsh && skip "remote MDS with nodsh"
17419         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17420
17421         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17422         local myDIR=$DIR/$tdir
17423
17424         mkdir -p $myDIR
17425         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17426         $LCTL set_param fail_loc=0x80001002
17427         # 20000 files can guarantee there are index nodes in the OI file
17428         createmany -o $myDIR/t- 20000
17429         $LCTL set_param fail_loc=0
17430         # The guard is current the largest FID holder
17431         touch $myDIR/guard
17432         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17433                     tr -d '[')
17434         local IDX=$(($SEQ % 64))
17435
17436         do_facet $SINGLEMDS sync
17437         # Make sure journal flushed.
17438         sleep 6
17439         local blk1=$(do_facet $SINGLEMDS \
17440                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17441                      grep Blockcount | awk '{print $4}')
17442
17443         # Remove old files, some OI blocks will become idle.
17444         unlinkmany $myDIR/t- 20000
17445         rm -f $myDIR/guard
17446         # The OI file should become empty now
17447
17448         # Create new files, idle OI blocks should be reused.
17449         createmany -o $myDIR/t- 2000
17450         do_facet $SINGLEMDS sync
17451         # Make sure journal flushed.
17452         sleep 6
17453         local blk2=$(do_facet $SINGLEMDS \
17454                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17455                      grep Blockcount | awk '{print $4}')
17456
17457         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17458 }
17459 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17460
17461 test_229() { # LU-2482, LU-3448
17462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17463         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17464         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17465                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17466
17467         rm -f $DIR/$tfile
17468
17469         # Create a file with a released layout and stripe count 2.
17470         $MULTIOP $DIR/$tfile H2c ||
17471                 error "failed to create file with released layout"
17472
17473         $LFS getstripe -v $DIR/$tfile
17474
17475         local pattern=$($LFS getstripe -L $DIR/$tfile)
17476         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17477
17478         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17479                 error "getstripe"
17480         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17481         stat $DIR/$tfile || error "failed to stat released file"
17482
17483         chown $RUNAS_ID $DIR/$tfile ||
17484                 error "chown $RUNAS_ID $DIR/$tfile failed"
17485
17486         chgrp $RUNAS_ID $DIR/$tfile ||
17487                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17488
17489         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17490         rm $DIR/$tfile || error "failed to remove released file"
17491 }
17492 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17493
17494 test_230a() {
17495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17496         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17497         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17498                 skip "Need MDS version at least 2.11.52"
17499
17500         local MDTIDX=1
17501
17502         test_mkdir $DIR/$tdir
17503         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17504         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17505         [ $mdt_idx -ne 0 ] &&
17506                 error "create local directory on wrong MDT $mdt_idx"
17507
17508         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17509                         error "create remote directory failed"
17510         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17511         [ $mdt_idx -ne $MDTIDX ] &&
17512                 error "create remote directory on wrong MDT $mdt_idx"
17513
17514         createmany -o $DIR/$tdir/test_230/t- 10 ||
17515                 error "create files on remote directory failed"
17516         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17517         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17518         rm -r $DIR/$tdir || error "unlink remote directory failed"
17519 }
17520 run_test 230a "Create remote directory and files under the remote directory"
17521
17522 test_230b() {
17523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17524         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17525         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17526                 skip "Need MDS version at least 2.11.52"
17527
17528         local MDTIDX=1
17529         local mdt_index
17530         local i
17531         local file
17532         local pid
17533         local stripe_count
17534         local migrate_dir=$DIR/$tdir/migrate_dir
17535         local other_dir=$DIR/$tdir/other_dir
17536
17537         test_mkdir $DIR/$tdir
17538         test_mkdir -i0 -c1 $migrate_dir
17539         test_mkdir -i0 -c1 $other_dir
17540         for ((i=0; i<10; i++)); do
17541                 mkdir -p $migrate_dir/dir_${i}
17542                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17543                         error "create files under remote dir failed $i"
17544         done
17545
17546         cp /etc/passwd $migrate_dir/$tfile
17547         cp /etc/passwd $other_dir/$tfile
17548         chattr +SAD $migrate_dir
17549         chattr +SAD $migrate_dir/$tfile
17550
17551         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17552         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17553         local old_dir_mode=$(stat -c%f $migrate_dir)
17554         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17555
17556         mkdir -p $migrate_dir/dir_default_stripe2
17557         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17558         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17559
17560         mkdir -p $other_dir
17561         ln $migrate_dir/$tfile $other_dir/luna
17562         ln $migrate_dir/$tfile $migrate_dir/sofia
17563         ln $other_dir/$tfile $migrate_dir/david
17564         ln -s $migrate_dir/$tfile $other_dir/zachary
17565         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17566         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17567
17568         local len
17569         local lnktgt
17570
17571         # inline symlink
17572         for len in 58 59 60; do
17573                 lnktgt=$(str_repeat 'l' $len)
17574                 touch $migrate_dir/$lnktgt
17575                 ln -s $lnktgt $migrate_dir/${len}char_ln
17576         done
17577
17578         # PATH_MAX
17579         for len in 4094 4095; do
17580                 lnktgt=$(str_repeat 'l' $len)
17581                 ln -s $lnktgt $migrate_dir/${len}char_ln
17582         done
17583
17584         # NAME_MAX
17585         for len in 254 255; do
17586                 touch $migrate_dir/$(str_repeat 'l' $len)
17587         done
17588
17589         $LFS migrate -m $MDTIDX $migrate_dir ||
17590                 error "fails on migrating remote dir to MDT1"
17591
17592         echo "migratate to MDT1, then checking.."
17593         for ((i = 0; i < 10; i++)); do
17594                 for file in $(find $migrate_dir/dir_${i}); do
17595                         mdt_index=$($LFS getstripe -m $file)
17596                         # broken symlink getstripe will fail
17597                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17598                                 error "$file is not on MDT${MDTIDX}"
17599                 done
17600         done
17601
17602         # the multiple link file should still in MDT0
17603         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17604         [ $mdt_index == 0 ] ||
17605                 error "$file is not on MDT${MDTIDX}"
17606
17607         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17608         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17609                 error " expect $old_dir_flag get $new_dir_flag"
17610
17611         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17612         [ "$old_file_flag" = "$new_file_flag" ] ||
17613                 error " expect $old_file_flag get $new_file_flag"
17614
17615         local new_dir_mode=$(stat -c%f $migrate_dir)
17616         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17617                 error "expect mode $old_dir_mode get $new_dir_mode"
17618
17619         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17620         [ "$old_file_mode" = "$new_file_mode" ] ||
17621                 error "expect mode $old_file_mode get $new_file_mode"
17622
17623         diff /etc/passwd $migrate_dir/$tfile ||
17624                 error "$tfile different after migration"
17625
17626         diff /etc/passwd $other_dir/luna ||
17627                 error "luna different after migration"
17628
17629         diff /etc/passwd $migrate_dir/sofia ||
17630                 error "sofia different after migration"
17631
17632         diff /etc/passwd $migrate_dir/david ||
17633                 error "david different after migration"
17634
17635         diff /etc/passwd $other_dir/zachary ||
17636                 error "zachary different after migration"
17637
17638         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17639                 error "${tfile}_ln different after migration"
17640
17641         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17642                 error "${tfile}_ln_other different after migration"
17643
17644         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17645         [ $stripe_count = 2 ] ||
17646                 error "dir strpe_count $d != 2 after migration."
17647
17648         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17649         [ $stripe_count = 2 ] ||
17650                 error "file strpe_count $d != 2 after migration."
17651
17652         #migrate back to MDT0
17653         MDTIDX=0
17654
17655         $LFS migrate -m $MDTIDX $migrate_dir ||
17656                 error "fails on migrating remote dir to MDT0"
17657
17658         echo "migrate back to MDT0, checking.."
17659         for file in $(find $migrate_dir); do
17660                 mdt_index=$($LFS getstripe -m $file)
17661                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17662                         error "$file is not on MDT${MDTIDX}"
17663         done
17664
17665         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17666         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17667                 error " expect $old_dir_flag get $new_dir_flag"
17668
17669         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17670         [ "$old_file_flag" = "$new_file_flag" ] ||
17671                 error " expect $old_file_flag get $new_file_flag"
17672
17673         local new_dir_mode=$(stat -c%f $migrate_dir)
17674         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17675                 error "expect mode $old_dir_mode get $new_dir_mode"
17676
17677         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17678         [ "$old_file_mode" = "$new_file_mode" ] ||
17679                 error "expect mode $old_file_mode get $new_file_mode"
17680
17681         diff /etc/passwd ${migrate_dir}/$tfile ||
17682                 error "$tfile different after migration"
17683
17684         diff /etc/passwd ${other_dir}/luna ||
17685                 error "luna different after migration"
17686
17687         diff /etc/passwd ${migrate_dir}/sofia ||
17688                 error "sofia different after migration"
17689
17690         diff /etc/passwd ${other_dir}/zachary ||
17691                 error "zachary different after migration"
17692
17693         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17694                 error "${tfile}_ln different after migration"
17695
17696         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17697                 error "${tfile}_ln_other different after migration"
17698
17699         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17700         [ $stripe_count = 2 ] ||
17701                 error "dir strpe_count $d != 2 after migration."
17702
17703         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17704         [ $stripe_count = 2 ] ||
17705                 error "file strpe_count $d != 2 after migration."
17706
17707         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17708 }
17709 run_test 230b "migrate directory"
17710
17711 test_230c() {
17712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17713         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17714         remote_mds_nodsh && skip "remote MDS with nodsh"
17715         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17716                 skip "Need MDS version at least 2.11.52"
17717
17718         local MDTIDX=1
17719         local total=3
17720         local mdt_index
17721         local file
17722         local migrate_dir=$DIR/$tdir/migrate_dir
17723
17724         #If migrating directory fails in the middle, all entries of
17725         #the directory is still accessiable.
17726         test_mkdir $DIR/$tdir
17727         test_mkdir -i0 -c1 $migrate_dir
17728         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17729         stat $migrate_dir
17730         createmany -o $migrate_dir/f $total ||
17731                 error "create files under ${migrate_dir} failed"
17732
17733         # fail after migrating top dir, and this will fail only once, so the
17734         # first sub file migration will fail (currently f3), others succeed.
17735         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17736         do_facet mds1 lctl set_param fail_loc=0x1801
17737         local t=$(ls $migrate_dir | wc -l)
17738         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17739                 error "migrate should fail"
17740         local u=$(ls $migrate_dir | wc -l)
17741         [ "$u" == "$t" ] || error "$u != $t during migration"
17742
17743         # add new dir/file should succeed
17744         mkdir $migrate_dir/dir ||
17745                 error "mkdir failed under migrating directory"
17746         touch $migrate_dir/file ||
17747                 error "create file failed under migrating directory"
17748
17749         # add file with existing name should fail
17750         for file in $migrate_dir/f*; do
17751                 stat $file > /dev/null || error "stat $file failed"
17752                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17753                         error "open(O_CREAT|O_EXCL) $file should fail"
17754                 $MULTIOP $file m && error "create $file should fail"
17755                 touch $DIR/$tdir/remote_dir/$tfile ||
17756                         error "touch $tfile failed"
17757                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17758                         error "link $file should fail"
17759                 mdt_index=$($LFS getstripe -m $file)
17760                 if [ $mdt_index == 0 ]; then
17761                         # file failed to migrate is not allowed to rename to
17762                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17763                                 error "rename to $file should fail"
17764                 else
17765                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17766                                 error "rename to $file failed"
17767                 fi
17768                 echo hello >> $file || error "write $file failed"
17769         done
17770
17771         # resume migration with different options should fail
17772         $LFS migrate -m 0 $migrate_dir &&
17773                 error "migrate -m 0 $migrate_dir should fail"
17774
17775         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17776                 error "migrate -c 2 $migrate_dir should fail"
17777
17778         # resume migration should succeed
17779         $LFS migrate -m $MDTIDX $migrate_dir ||
17780                 error "migrate $migrate_dir failed"
17781
17782         echo "Finish migration, then checking.."
17783         for file in $(find $migrate_dir); do
17784                 mdt_index=$($LFS getstripe -m $file)
17785                 [ $mdt_index == $MDTIDX ] ||
17786                         error "$file is not on MDT${MDTIDX}"
17787         done
17788
17789         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17790 }
17791 run_test 230c "check directory accessiblity if migration failed"
17792
17793 test_230d() {
17794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17795         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17796         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17797                 skip "Need MDS version at least 2.11.52"
17798         # LU-11235
17799         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17800
17801         local migrate_dir=$DIR/$tdir/migrate_dir
17802         local old_index
17803         local new_index
17804         local old_count
17805         local new_count
17806         local new_hash
17807         local mdt_index
17808         local i
17809         local j
17810
17811         old_index=$((RANDOM % MDSCOUNT))
17812         old_count=$((MDSCOUNT - old_index))
17813         new_index=$((RANDOM % MDSCOUNT))
17814         new_count=$((MDSCOUNT - new_index))
17815         new_hash=1 # for all_char
17816
17817         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17818         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17819
17820         test_mkdir $DIR/$tdir
17821         test_mkdir -i $old_index -c $old_count $migrate_dir
17822
17823         for ((i=0; i<100; i++)); do
17824                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17825                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17826                         error "create files under remote dir failed $i"
17827         done
17828
17829         echo -n "Migrate from MDT$old_index "
17830         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17831         echo -n "to MDT$new_index"
17832         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17833         echo
17834
17835         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17836         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17837                 error "migrate remote dir error"
17838
17839         echo "Finish migration, then checking.."
17840         for file in $(find $migrate_dir); do
17841                 mdt_index=$($LFS getstripe -m $file)
17842                 if [ $mdt_index -lt $new_index ] ||
17843                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17844                         error "$file is on MDT$mdt_index"
17845                 fi
17846         done
17847
17848         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17849 }
17850 run_test 230d "check migrate big directory"
17851
17852 test_230e() {
17853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17854         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17855         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17856                 skip "Need MDS version at least 2.11.52"
17857
17858         local i
17859         local j
17860         local a_fid
17861         local b_fid
17862
17863         mkdir -p $DIR/$tdir
17864         mkdir $DIR/$tdir/migrate_dir
17865         mkdir $DIR/$tdir/other_dir
17866         touch $DIR/$tdir/migrate_dir/a
17867         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17868         ls $DIR/$tdir/other_dir
17869
17870         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17871                 error "migrate dir fails"
17872
17873         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17874         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17875
17876         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17877         [ $mdt_index == 0 ] || error "a is not on MDT0"
17878
17879         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
17880                 error "migrate dir fails"
17881
17882         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
17883         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
17884
17885         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17886         [ $mdt_index == 1 ] || error "a is not on MDT1"
17887
17888         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
17889         [ $mdt_index == 1 ] || error "b is not on MDT1"
17890
17891         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17892         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
17893
17894         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
17895
17896         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17897 }
17898 run_test 230e "migrate mulitple local link files"
17899
17900 test_230f() {
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 a_fid
17907         local ln_fid
17908
17909         mkdir -p $DIR/$tdir
17910         mkdir $DIR/$tdir/migrate_dir
17911         $LFS mkdir -i1 $DIR/$tdir/other_dir
17912         touch $DIR/$tdir/migrate_dir/a
17913         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
17914         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
17915         ls $DIR/$tdir/other_dir
17916
17917         # a should be migrated to MDT1, since no other links on MDT0
17918         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17919                 error "#1 migrate dir fails"
17920         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17921         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17922         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17923         [ $mdt_index == 1 ] || error "a is not on MDT1"
17924
17925         # a should stay on MDT1, because it is a mulitple link file
17926         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17927                 error "#2 migrate dir fails"
17928         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17929         [ $mdt_index == 1 ] || error "a is not on MDT1"
17930
17931         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17932                 error "#3 migrate dir fails"
17933
17934         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17935         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
17936         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
17937
17938         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
17939         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
17940
17941         # a should be migrated to MDT0, since no other links on MDT1
17942         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17943                 error "#4 migrate dir fails"
17944         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17945         [ $mdt_index == 0 ] || error "a is not on MDT0"
17946
17947         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17948 }
17949 run_test 230f "migrate mulitple remote link files"
17950
17951 test_230g() {
17952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17953         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17954         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17955                 skip "Need MDS version at least 2.11.52"
17956
17957         mkdir -p $DIR/$tdir/migrate_dir
17958
17959         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
17960                 error "migrating dir to non-exist MDT succeeds"
17961         true
17962 }
17963 run_test 230g "migrate dir to non-exist MDT"
17964
17965 test_230h() {
17966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17967         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17968         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17969                 skip "Need MDS version at least 2.11.52"
17970
17971         local mdt_index
17972
17973         mkdir -p $DIR/$tdir/migrate_dir
17974
17975         $LFS migrate -m1 $DIR &&
17976                 error "migrating mountpoint1 should fail"
17977
17978         $LFS migrate -m1 $DIR/$tdir/.. &&
17979                 error "migrating mountpoint2 should fail"
17980
17981         # same as mv
17982         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
17983                 error "migrating $tdir/migrate_dir/.. should fail"
17984
17985         true
17986 }
17987 run_test 230h "migrate .. and root"
17988
17989 test_230i() {
17990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17991         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17992         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17993                 skip "Need MDS version at least 2.11.52"
17994
17995         mkdir -p $DIR/$tdir/migrate_dir
17996
17997         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
17998                 error "migration fails with a tailing slash"
17999
18000         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18001                 error "migration fails with two tailing slashes"
18002 }
18003 run_test 230i "lfs migrate -m tolerates trailing slashes"
18004
18005 test_230j() {
18006         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18007         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18008                 skip "Need MDS version at least 2.11.52"
18009
18010         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18011         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18012                 error "create $tfile failed"
18013         cat /etc/passwd > $DIR/$tdir/$tfile
18014
18015         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18016
18017         cmp /etc/passwd $DIR/$tdir/$tfile ||
18018                 error "DoM file mismatch after migration"
18019 }
18020 run_test 230j "DoM file data not changed after dir migration"
18021
18022 test_230k() {
18023         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18024         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18025                 skip "Need MDS version at least 2.11.56"
18026
18027         local total=20
18028         local files_on_starting_mdt=0
18029
18030         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18031         $LFS getdirstripe $DIR/$tdir
18032         for i in $(seq $total); do
18033                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18034                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18035                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18036         done
18037
18038         echo "$files_on_starting_mdt files on MDT0"
18039
18040         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18041         $LFS getdirstripe $DIR/$tdir
18042
18043         files_on_starting_mdt=0
18044         for i in $(seq $total); do
18045                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18046                         error "file $tfile.$i mismatch after migration"
18047                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18048                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18049         done
18050
18051         echo "$files_on_starting_mdt files on MDT1 after migration"
18052         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18053
18054         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18055         $LFS getdirstripe $DIR/$tdir
18056
18057         files_on_starting_mdt=0
18058         for i in $(seq $total); do
18059                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18060                         error "file $tfile.$i mismatch after 2nd migration"
18061                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18062                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18063         done
18064
18065         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18066         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18067
18068         true
18069 }
18070 run_test 230k "file data not changed after dir migration"
18071
18072 test_230l() {
18073         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18074         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18075                 skip "Need MDS version at least 2.11.56"
18076
18077         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18078         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18079                 error "create files under remote dir failed $i"
18080         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18081 }
18082 run_test 230l "readdir between MDTs won't crash"
18083
18084 test_230m() {
18085         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18086         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18087                 skip "Need MDS version at least 2.11.56"
18088
18089         local MDTIDX=1
18090         local mig_dir=$DIR/$tdir/migrate_dir
18091         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18092         local shortstr="b"
18093         local val
18094
18095         echo "Creating files and dirs with xattrs"
18096         test_mkdir $DIR/$tdir
18097         test_mkdir -i0 -c1 $mig_dir
18098         mkdir $mig_dir/dir
18099         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18100                 error "cannot set xattr attr1 on dir"
18101         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18102                 error "cannot set xattr attr2 on dir"
18103         touch $mig_dir/dir/f0
18104         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18105                 error "cannot set xattr attr1 on file"
18106         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18107                 error "cannot set xattr attr2 on file"
18108         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18109         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18110         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18111         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18112         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18113         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18114         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18115         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18116         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18117
18118         echo "Migrating to MDT1"
18119         $LFS migrate -m $MDTIDX $mig_dir ||
18120                 error "fails on migrating dir to MDT1"
18121
18122         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18123         echo "Checking xattrs"
18124         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18125         [ "$val" = $longstr ] ||
18126                 error "expecting xattr1 $longstr on dir, found $val"
18127         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18128         [ "$val" = $shortstr ] ||
18129                 error "expecting xattr2 $shortstr on dir, found $val"
18130         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18131         [ "$val" = $longstr ] ||
18132                 error "expecting xattr1 $longstr on file, found $val"
18133         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18134         [ "$val" = $shortstr ] ||
18135                 error "expecting xattr2 $shortstr on file, found $val"
18136 }
18137 run_test 230m "xattrs not changed after dir migration"
18138
18139 test_230n() {
18140         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18141         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18142                 skip "Need MDS version at least 2.13.53"
18143
18144         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18145         cat /etc/hosts > $DIR/$tdir/$tfile
18146         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18147         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18148
18149         cmp /etc/hosts $DIR/$tdir/$tfile ||
18150                 error "File data mismatch after migration"
18151 }
18152 run_test 230n "Dir migration with mirrored file"
18153
18154 test_230o() {
18155         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18156         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18157                 skip "Need MDS version at least 2.13.52"
18158
18159         local mdts=$(comma_list $(mdts_nodes))
18160         local timeout=100
18161
18162         local restripe_status
18163         local delta
18164         local i
18165         local j
18166
18167         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18168
18169         # in case "crush" hash type is not set
18170         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18171
18172         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18173                            mdt.*MDT0000.enable_dir_restripe)
18174         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18175         stack_trap "do_nodes $mdts $LCTL set_param \
18176                     mdt.*.enable_dir_restripe=$restripe_status"
18177
18178         mkdir $DIR/$tdir
18179         createmany -m $DIR/$tdir/f 100 ||
18180                 error "create files under remote dir failed $i"
18181         createmany -d $DIR/$tdir/d 100 ||
18182                 error "create dirs under remote dir failed $i"
18183
18184         for i in $(seq 2 $MDSCOUNT); do
18185                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18186                 $LFS setdirstripe -c $i $DIR/$tdir ||
18187                         error "split -c $i $tdir failed"
18188                 wait_update $HOSTNAME \
18189                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18190                         error "dir split not finished"
18191                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18192                         awk '/migrate/ {sum += $2} END { print sum }')
18193                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18194                 # delta is around total_files/stripe_count
18195                 [ $delta -lt $((200 /(i - 1))) ] ||
18196                         error "$delta files migrated"
18197         done
18198 }
18199 run_test 230o "dir split"
18200
18201 test_230p() {
18202         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18203         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18204                 skip "Need MDS version at least 2.13.52"
18205
18206         local mdts=$(comma_list $(mdts_nodes))
18207         local timeout=100
18208
18209         local restripe_status
18210         local delta
18211         local i
18212         local j
18213
18214         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18215
18216         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18217
18218         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18219                            mdt.*MDT0000.enable_dir_restripe)
18220         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18221         stack_trap "do_nodes $mdts $LCTL set_param \
18222                     mdt.*.enable_dir_restripe=$restripe_status"
18223
18224         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18225         createmany -m $DIR/$tdir/f 100 ||
18226                 error "create files under remote dir failed $i"
18227         createmany -d $DIR/$tdir/d 100 ||
18228                 error "create dirs under remote dir failed $i"
18229
18230         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18231                 local mdt_hash="crush"
18232
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                 [ $i -eq 1 ] && mdt_hash="none"
18237                 wait_update $HOSTNAME \
18238                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18239                         error "dir merge not finished"
18240                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18241                         awk '/migrate/ {sum += $2} END { print sum }')
18242                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18243                 # delta is around total_files/stripe_count
18244                 [ $delta -lt $((200 / i)) ] ||
18245                         error "$delta files migrated"
18246         done
18247 }
18248 run_test 230p "dir merge"
18249
18250 test_230q() {
18251         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18252         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18253                 skip "Need MDS version at least 2.13.52"
18254
18255         local mdts=$(comma_list $(mdts_nodes))
18256         local saved_threshold=$(do_facet mds1 \
18257                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18258         local saved_delta=$(do_facet mds1 \
18259                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18260         local threshold=100
18261         local delta=2
18262         local total=0
18263         local stripe_count=0
18264         local stripe_index
18265         local nr_files
18266
18267         stack_trap "do_nodes $mdts $LCTL set_param \
18268                     mdt.*.dir_split_count=$saved_threshold"
18269         stack_trap "do_nodes $mdts $LCTL set_param \
18270                     mdt.*.dir_split_delta=$saved_delta"
18271         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18272         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18273         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18274         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18275         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18276         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18277
18278         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18279         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18280
18281         while [ $stripe_count -lt $MDSCOUNT ]; do
18282                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18283                         error "create sub files failed"
18284                 stat $DIR/$tdir > /dev/null
18285                 total=$((total + threshold * 3 / 2))
18286                 stripe_count=$((stripe_count + delta))
18287                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18288
18289                 wait_update $HOSTNAME \
18290                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18291                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18292
18293                 wait_update $HOSTNAME \
18294                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18295                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18296
18297                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18298                            grep -w $stripe_index | wc -l)
18299                 echo "$nr_files files on MDT$stripe_index after split"
18300                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18301                         error "$nr_files files on MDT$stripe_index after split"
18302
18303                 nr_files=$(ls $DIR/$tdir | wc -w)
18304                 [ $nr_files -eq $total ] ||
18305                         error "total sub files $nr_files != $total"
18306         done
18307 }
18308 run_test 230q "dir auto split"
18309
18310 test_231a()
18311 {
18312         # For simplicity this test assumes that max_pages_per_rpc
18313         # is the same across all OSCs
18314         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18315         local bulk_size=$((max_pages * PAGE_SIZE))
18316         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18317                                        head -n 1)
18318
18319         mkdir -p $DIR/$tdir
18320         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18321                 error "failed to set stripe with -S ${brw_size}M option"
18322
18323         # clear the OSC stats
18324         $LCTL set_param osc.*.stats=0 &>/dev/null
18325         stop_writeback
18326
18327         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18328         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18329                 oflag=direct &>/dev/null || error "dd failed"
18330
18331         sync; sleep 1; sync # just to be safe
18332         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18333         if [ x$nrpcs != "x1" ]; then
18334                 $LCTL get_param osc.*.stats
18335                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18336         fi
18337
18338         start_writeback
18339         # Drop the OSC cache, otherwise we will read from it
18340         cancel_lru_locks osc
18341
18342         # clear the OSC stats
18343         $LCTL set_param osc.*.stats=0 &>/dev/null
18344
18345         # Client reads $bulk_size.
18346         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18347                 iflag=direct &>/dev/null || error "dd failed"
18348
18349         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18350         if [ x$nrpcs != "x1" ]; then
18351                 $LCTL get_param osc.*.stats
18352                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18353         fi
18354 }
18355 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18356
18357 test_231b() {
18358         mkdir -p $DIR/$tdir
18359         local i
18360         for i in {0..1023}; do
18361                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18362                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18363                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18364         done
18365         sync
18366 }
18367 run_test 231b "must not assert on fully utilized OST request buffer"
18368
18369 test_232a() {
18370         mkdir -p $DIR/$tdir
18371         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18372
18373         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18374         do_facet ost1 $LCTL set_param fail_loc=0x31c
18375
18376         # ignore dd failure
18377         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18378
18379         do_facet ost1 $LCTL set_param fail_loc=0
18380         umount_client $MOUNT || error "umount failed"
18381         mount_client $MOUNT || error "mount failed"
18382         stop ost1 || error "cannot stop ost1"
18383         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18384 }
18385 run_test 232a "failed lock should not block umount"
18386
18387 test_232b() {
18388         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18389                 skip "Need MDS version at least 2.10.58"
18390
18391         mkdir -p $DIR/$tdir
18392         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18393         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18394         sync
18395         cancel_lru_locks osc
18396
18397         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18398         do_facet ost1 $LCTL set_param fail_loc=0x31c
18399
18400         # ignore failure
18401         $LFS data_version $DIR/$tdir/$tfile || true
18402
18403         do_facet ost1 $LCTL set_param fail_loc=0
18404         umount_client $MOUNT || error "umount failed"
18405         mount_client $MOUNT || error "mount failed"
18406         stop ost1 || error "cannot stop ost1"
18407         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18408 }
18409 run_test 232b "failed data version lock should not block umount"
18410
18411 test_233a() {
18412         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18413                 skip "Need MDS version at least 2.3.64"
18414         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18415
18416         local fid=$($LFS path2fid $MOUNT)
18417
18418         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18419                 error "cannot access $MOUNT using its FID '$fid'"
18420 }
18421 run_test 233a "checking that OBF of the FS root succeeds"
18422
18423 test_233b() {
18424         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18425                 skip "Need MDS version at least 2.5.90"
18426         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18427
18428         local fid=$($LFS path2fid $MOUNT/.lustre)
18429
18430         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18431                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18432
18433         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18434         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18435                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18436 }
18437 run_test 233b "checking that OBF of the FS .lustre succeeds"
18438
18439 test_234() {
18440         local p="$TMP/sanityN-$TESTNAME.parameters"
18441         save_lustre_params client "llite.*.xattr_cache" > $p
18442         lctl set_param llite.*.xattr_cache 1 ||
18443                 skip_env "xattr cache is not supported"
18444
18445         mkdir -p $DIR/$tdir || error "mkdir failed"
18446         touch $DIR/$tdir/$tfile || error "touch failed"
18447         # OBD_FAIL_LLITE_XATTR_ENOMEM
18448         $LCTL set_param fail_loc=0x1405
18449         getfattr -n user.attr $DIR/$tdir/$tfile &&
18450                 error "getfattr should have failed with ENOMEM"
18451         $LCTL set_param fail_loc=0x0
18452         rm -rf $DIR/$tdir
18453
18454         restore_lustre_params < $p
18455         rm -f $p
18456 }
18457 run_test 234 "xattr cache should not crash on ENOMEM"
18458
18459 test_235() {
18460         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18461                 skip "Need MDS version at least 2.4.52"
18462
18463         flock_deadlock $DIR/$tfile
18464         local RC=$?
18465         case $RC in
18466                 0)
18467                 ;;
18468                 124) error "process hangs on a deadlock"
18469                 ;;
18470                 *) error "error executing flock_deadlock $DIR/$tfile"
18471                 ;;
18472         esac
18473 }
18474 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18475
18476 #LU-2935
18477 test_236() {
18478         check_swap_layouts_support
18479
18480         local ref1=/etc/passwd
18481         local ref2=/etc/group
18482         local file1=$DIR/$tdir/f1
18483         local file2=$DIR/$tdir/f2
18484
18485         test_mkdir -c1 $DIR/$tdir
18486         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18487         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18488         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18489         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18490         local fd=$(free_fd)
18491         local cmd="exec $fd<>$file2"
18492         eval $cmd
18493         rm $file2
18494         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18495                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18496         cmd="exec $fd>&-"
18497         eval $cmd
18498         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18499
18500         #cleanup
18501         rm -rf $DIR/$tdir
18502 }
18503 run_test 236 "Layout swap on open unlinked file"
18504
18505 # LU-4659 linkea consistency
18506 test_238() {
18507         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18508                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18509                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18510                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18511
18512         touch $DIR/$tfile
18513         ln $DIR/$tfile $DIR/$tfile.lnk
18514         touch $DIR/$tfile.new
18515         mv $DIR/$tfile.new $DIR/$tfile
18516         local fid1=$($LFS path2fid $DIR/$tfile)
18517         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18518         local path1=$($LFS fid2path $FSNAME "$fid1")
18519         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18520         local path2=$($LFS fid2path $FSNAME "$fid2")
18521         [ $tfile.lnk == $path2 ] ||
18522                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18523         rm -f $DIR/$tfile*
18524 }
18525 run_test 238 "Verify linkea consistency"
18526
18527 test_239A() { # was test_239
18528         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18529                 skip "Need MDS version at least 2.5.60"
18530
18531         local list=$(comma_list $(mdts_nodes))
18532
18533         mkdir -p $DIR/$tdir
18534         createmany -o $DIR/$tdir/f- 5000
18535         unlinkmany $DIR/$tdir/f- 5000
18536         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18537                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18538         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18539                         osp.*MDT*.sync_in_flight" | calc_sum)
18540         [ "$changes" -eq 0 ] || error "$changes not synced"
18541 }
18542 run_test 239A "osp_sync test"
18543
18544 test_239a() { #LU-5297
18545         remote_mds_nodsh && skip "remote MDS with nodsh"
18546
18547         touch $DIR/$tfile
18548         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18549         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18550         chgrp $RUNAS_GID $DIR/$tfile
18551         wait_delete_completed
18552 }
18553 run_test 239a "process invalid osp sync record correctly"
18554
18555 test_239b() { #LU-5297
18556         remote_mds_nodsh && skip "remote MDS with nodsh"
18557
18558         touch $DIR/$tfile1
18559         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18560         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18561         chgrp $RUNAS_GID $DIR/$tfile1
18562         wait_delete_completed
18563         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18564         touch $DIR/$tfile2
18565         chgrp $RUNAS_GID $DIR/$tfile2
18566         wait_delete_completed
18567 }
18568 run_test 239b "process osp sync record with ENOMEM error correctly"
18569
18570 test_240() {
18571         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18572         remote_mds_nodsh && skip "remote MDS with nodsh"
18573
18574         mkdir -p $DIR/$tdir
18575
18576         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18577                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18578         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18579                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18580
18581         umount_client $MOUNT || error "umount failed"
18582         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18583         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18584         mount_client $MOUNT || error "failed to mount client"
18585
18586         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18587         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18588 }
18589 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18590
18591 test_241_bio() {
18592         local count=$1
18593         local bsize=$2
18594
18595         for LOOP in $(seq $count); do
18596                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18597                 cancel_lru_locks $OSC || true
18598         done
18599 }
18600
18601 test_241_dio() {
18602         local count=$1
18603         local bsize=$2
18604
18605         for LOOP in $(seq $1); do
18606                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18607                         2>/dev/null
18608         done
18609 }
18610
18611 test_241a() { # was test_241
18612         local bsize=$PAGE_SIZE
18613
18614         (( bsize < 40960 )) && bsize=40960
18615         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18616         ls -la $DIR/$tfile
18617         cancel_lru_locks $OSC
18618         test_241_bio 1000 $bsize &
18619         PID=$!
18620         test_241_dio 1000 $bsize
18621         wait $PID
18622 }
18623 run_test 241a "bio vs dio"
18624
18625 test_241b() {
18626         local bsize=$PAGE_SIZE
18627
18628         (( bsize < 40960 )) && bsize=40960
18629         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18630         ls -la $DIR/$tfile
18631         test_241_dio 1000 $bsize &
18632         PID=$!
18633         test_241_dio 1000 $bsize
18634         wait $PID
18635 }
18636 run_test 241b "dio vs dio"
18637
18638 test_242() {
18639         remote_mds_nodsh && skip "remote MDS with nodsh"
18640
18641         mkdir -p $DIR/$tdir
18642         touch $DIR/$tdir/$tfile
18643
18644         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18645         do_facet mds1 lctl set_param fail_loc=0x105
18646         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18647
18648         do_facet mds1 lctl set_param fail_loc=0
18649         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18650 }
18651 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18652
18653 test_243()
18654 {
18655         test_mkdir $DIR/$tdir
18656         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18657 }
18658 run_test 243 "various group lock tests"
18659
18660 test_244a()
18661 {
18662         test_mkdir $DIR/$tdir
18663         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18664         sendfile_grouplock $DIR/$tdir/$tfile || \
18665                 error "sendfile+grouplock failed"
18666         rm -rf $DIR/$tdir
18667 }
18668 run_test 244a "sendfile with group lock tests"
18669
18670 test_244b()
18671 {
18672         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18673
18674         local threads=50
18675         local size=$((1024*1024))
18676
18677         test_mkdir $DIR/$tdir
18678         for i in $(seq 1 $threads); do
18679                 local file=$DIR/$tdir/file_$((i / 10))
18680                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18681                 local pids[$i]=$!
18682         done
18683         for i in $(seq 1 $threads); do
18684                 wait ${pids[$i]}
18685         done
18686 }
18687 run_test 244b "multi-threaded write with group lock"
18688
18689 test_245() {
18690         local flagname="multi_mod_rpcs"
18691         local connect_data_name="max_mod_rpcs"
18692         local out
18693
18694         # check if multiple modify RPCs flag is set
18695         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18696                 grep "connect_flags:")
18697         echo "$out"
18698
18699         echo "$out" | grep -qw $flagname
18700         if [ $? -ne 0 ]; then
18701                 echo "connect flag $flagname is not set"
18702                 return
18703         fi
18704
18705         # check if multiple modify RPCs data is set
18706         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18707         echo "$out"
18708
18709         echo "$out" | grep -qw $connect_data_name ||
18710                 error "import should have connect data $connect_data_name"
18711 }
18712 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18713
18714 cleanup_247() {
18715         local submount=$1
18716
18717         trap 0
18718         umount_client $submount
18719         rmdir $submount
18720 }
18721
18722 test_247a() {
18723         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18724                 grep -q subtree ||
18725                 skip_env "Fileset feature is not supported"
18726
18727         local submount=${MOUNT}_$tdir
18728
18729         mkdir $MOUNT/$tdir
18730         mkdir -p $submount || error "mkdir $submount failed"
18731         FILESET="$FILESET/$tdir" mount_client $submount ||
18732                 error "mount $submount failed"
18733         trap "cleanup_247 $submount" EXIT
18734         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18735         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18736                 error "read $MOUNT/$tdir/$tfile failed"
18737         cleanup_247 $submount
18738 }
18739 run_test 247a "mount subdir as fileset"
18740
18741 test_247b() {
18742         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18743                 skip_env "Fileset feature is not supported"
18744
18745         local submount=${MOUNT}_$tdir
18746
18747         rm -rf $MOUNT/$tdir
18748         mkdir -p $submount || error "mkdir $submount failed"
18749         SKIP_FILESET=1
18750         FILESET="$FILESET/$tdir" mount_client $submount &&
18751                 error "mount $submount should fail"
18752         rmdir $submount
18753 }
18754 run_test 247b "mount subdir that dose not exist"
18755
18756 test_247c() {
18757         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18758                 skip_env "Fileset feature is not supported"
18759
18760         local submount=${MOUNT}_$tdir
18761
18762         mkdir -p $MOUNT/$tdir/dir1
18763         mkdir -p $submount || error "mkdir $submount failed"
18764         trap "cleanup_247 $submount" EXIT
18765         FILESET="$FILESET/$tdir" mount_client $submount ||
18766                 error "mount $submount failed"
18767         local fid=$($LFS path2fid $MOUNT/)
18768         $LFS fid2path $submount $fid && error "fid2path should fail"
18769         cleanup_247 $submount
18770 }
18771 run_test 247c "running fid2path outside subdirectory root"
18772
18773 test_247d() {
18774         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18775                 skip "Fileset feature is not supported"
18776
18777         local submount=${MOUNT}_$tdir
18778
18779         mkdir -p $MOUNT/$tdir/dir1
18780         mkdir -p $submount || error "mkdir $submount failed"
18781         FILESET="$FILESET/$tdir" mount_client $submount ||
18782                 error "mount $submount failed"
18783         trap "cleanup_247 $submount" EXIT
18784
18785         local td=$submount/dir1
18786         local fid=$($LFS path2fid $td)
18787         [ -z "$fid" ] && error "path2fid unable to get $td FID"
18788
18789         # check that we get the same pathname back
18790         local rootpath
18791         local found
18792         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
18793                 echo "$rootpath $fid"
18794                 found=$($LFS fid2path $rootpath "$fid")
18795                 [ -n "found" ] || error "fid2path should succeed"
18796                 [ "$found" == "$td" ] || error "fid2path $found != $td"
18797         done
18798         # check wrong root path format
18799         rootpath=$submount"_wrong"
18800         found=$($LFS fid2path $rootpath "$fid")
18801         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
18802
18803         cleanup_247 $submount
18804 }
18805 run_test 247d "running fid2path inside subdirectory root"
18806
18807 # LU-8037
18808 test_247e() {
18809         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18810                 grep -q subtree ||
18811                 skip "Fileset feature is not supported"
18812
18813         local submount=${MOUNT}_$tdir
18814
18815         mkdir $MOUNT/$tdir
18816         mkdir -p $submount || error "mkdir $submount failed"
18817         FILESET="$FILESET/.." mount_client $submount &&
18818                 error "mount $submount should fail"
18819         rmdir $submount
18820 }
18821 run_test 247e "mount .. as fileset"
18822
18823 test_247f() {
18824         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18825         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18826                 skip "Need at least version 2.13.52"
18827         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18828                 grep -q subtree ||
18829                 skip "Fileset feature is not supported"
18830
18831         mkdir $DIR/$tdir || error "mkdir $tdir failed"
18832         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
18833                 error "mkdir remote failed"
18834         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
18835         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
18836                 error "mkdir striped failed"
18837         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
18838
18839         local submount=${MOUNT}_$tdir
18840
18841         mkdir -p $submount || error "mkdir $submount failed"
18842
18843         local dir
18844         local fileset=$FILESET
18845
18846         for dir in $tdir/remote $tdir/remote/subdir \
18847                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
18848                 FILESET="$fileset/$dir" mount_client $submount ||
18849                         error "mount $dir failed"
18850                 umount_client $submount
18851         done
18852 }
18853 run_test 247f "mount striped or remote directory as fileset"
18854
18855 test_248a() {
18856         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
18857         [ -z "$fast_read_sav" ] && skip "no fast read support"
18858
18859         # create a large file for fast read verification
18860         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
18861
18862         # make sure the file is created correctly
18863         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
18864                 { rm -f $DIR/$tfile; skip "file creation error"; }
18865
18866         echo "Test 1: verify that fast read is 4 times faster on cache read"
18867
18868         # small read with fast read enabled
18869         $LCTL set_param -n llite.*.fast_read=1
18870         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18871                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18872                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18873         # small read with fast read disabled
18874         $LCTL set_param -n llite.*.fast_read=0
18875         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18876                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18877                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18878
18879         # verify that fast read is 4 times faster for cache read
18880         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
18881                 error_not_in_vm "fast read was not 4 times faster: " \
18882                            "$t_fast vs $t_slow"
18883
18884         echo "Test 2: verify the performance between big and small read"
18885         $LCTL set_param -n llite.*.fast_read=1
18886
18887         # 1k non-cache read
18888         cancel_lru_locks osc
18889         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18890                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18891                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18892
18893         # 1M non-cache read
18894         cancel_lru_locks osc
18895         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18896                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18897                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18898
18899         # verify that big IO is not 4 times faster than small IO
18900         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
18901                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
18902
18903         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
18904         rm -f $DIR/$tfile
18905 }
18906 run_test 248a "fast read verification"
18907
18908 test_248b() {
18909         # Default short_io_bytes=16384, try both smaller and larger sizes.
18910         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
18911         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
18912         echo "bs=53248 count=113 normal buffered write"
18913         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
18914                 error "dd of initial data file failed"
18915         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
18916
18917         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
18918         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
18919                 error "dd with sync normal writes failed"
18920         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
18921
18922         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
18923         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
18924                 error "dd with sync small writes failed"
18925         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
18926
18927         cancel_lru_locks osc
18928
18929         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
18930         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
18931         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
18932         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
18933                 iflag=direct || error "dd with O_DIRECT small read failed"
18934         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
18935         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
18936                 error "compare $TMP/$tfile.1 failed"
18937
18938         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
18939         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
18940
18941         # just to see what the maximum tunable value is, and test parsing
18942         echo "test invalid parameter 2MB"
18943         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
18944                 error "too-large short_io_bytes allowed"
18945         echo "test maximum parameter 512KB"
18946         # if we can set a larger short_io_bytes, run test regardless of version
18947         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
18948                 # older clients may not allow setting it this large, that's OK
18949                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
18950                         skip "Need at least client version 2.13.50"
18951                 error "medium short_io_bytes failed"
18952         fi
18953         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
18954         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
18955
18956         echo "test large parameter 64KB"
18957         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
18958         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
18959
18960         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
18961         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
18962                 error "dd with sync large writes failed"
18963         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
18964
18965         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
18966         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
18967         num=$((113 * 4096 / PAGE_SIZE))
18968         echo "bs=$size count=$num oflag=direct large write $tfile.3"
18969         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
18970                 error "dd with O_DIRECT large writes failed"
18971         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
18972                 error "compare $DIR/$tfile.3 failed"
18973
18974         cancel_lru_locks osc
18975
18976         echo "bs=$size count=$num iflag=direct large read $tfile.2"
18977         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
18978                 error "dd with O_DIRECT large read failed"
18979         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
18980                 error "compare $TMP/$tfile.2 failed"
18981
18982         echo "bs=$size count=$num iflag=direct large read $tfile.3"
18983         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
18984                 error "dd with O_DIRECT large read failed"
18985         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
18986                 error "compare $TMP/$tfile.3 failed"
18987 }
18988 run_test 248b "test short_io read and write for both small and large sizes"
18989
18990 test_249() { # LU-7890
18991         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
18992                 skip "Need at least version 2.8.54"
18993
18994         rm -f $DIR/$tfile
18995         $LFS setstripe -c 1 $DIR/$tfile
18996         # Offset 2T == 4k * 512M
18997         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
18998                 error "dd to 2T offset failed"
18999 }
19000 run_test 249 "Write above 2T file size"
19001
19002 test_250() {
19003         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19004          && skip "no 16TB file size limit on ZFS"
19005
19006         $LFS setstripe -c 1 $DIR/$tfile
19007         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19008         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19009         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19010         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19011                 conv=notrunc,fsync && error "append succeeded"
19012         return 0
19013 }
19014 run_test 250 "Write above 16T limit"
19015
19016 test_251() {
19017         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19018
19019         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19020         #Skip once - writing the first stripe will succeed
19021         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19022         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19023                 error "short write happened"
19024
19025         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19026         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19027                 error "short read happened"
19028
19029         rm -f $DIR/$tfile
19030 }
19031 run_test 251 "Handling short read and write correctly"
19032
19033 test_252() {
19034         remote_mds_nodsh && skip "remote MDS with nodsh"
19035         remote_ost_nodsh && skip "remote OST with nodsh"
19036         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19037                 skip_env "ldiskfs only test"
19038         fi
19039
19040         local tgt
19041         local dev
19042         local out
19043         local uuid
19044         local num
19045         local gen
19046
19047         # check lr_reader on OST0000
19048         tgt=ost1
19049         dev=$(facet_device $tgt)
19050         out=$(do_facet $tgt $LR_READER $dev)
19051         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19052         echo "$out"
19053         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19054         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19055                 error "Invalid uuid returned by $LR_READER on target $tgt"
19056         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19057
19058         # check lr_reader -c on MDT0000
19059         tgt=mds1
19060         dev=$(facet_device $tgt)
19061         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19062                 skip "$LR_READER does not support additional options"
19063         fi
19064         out=$(do_facet $tgt $LR_READER -c $dev)
19065         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19066         echo "$out"
19067         num=$(echo "$out" | grep -c "mdtlov")
19068         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19069                 error "Invalid number of mdtlov clients returned by $LR_READER"
19070         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19071
19072         # check lr_reader -cr on MDT0000
19073         out=$(do_facet $tgt $LR_READER -cr $dev)
19074         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19075         echo "$out"
19076         echo "$out" | grep -q "^reply_data:$" ||
19077                 error "$LR_READER should have returned 'reply_data' section"
19078         num=$(echo "$out" | grep -c "client_generation")
19079         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19080 }
19081 run_test 252 "check lr_reader tool"
19082
19083 test_253() {
19084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19085         remote_mds_nodsh && skip "remote MDS with nodsh"
19086         remote_mgs_nodsh && skip "remote MGS with nodsh"
19087
19088         local ostidx=0
19089         local rc=0
19090         local ost_name=$(ostname_from_index $ostidx)
19091
19092         # on the mdt's osc
19093         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19094         do_facet $SINGLEMDS $LCTL get_param -n \
19095                 osp.$mdtosc_proc1.reserved_mb_high ||
19096                 skip  "remote MDS does not support reserved_mb_high"
19097
19098         rm -rf $DIR/$tdir
19099         wait_mds_ost_sync
19100         wait_delete_completed
19101         mkdir $DIR/$tdir
19102
19103         pool_add $TESTNAME || error "Pool creation failed"
19104         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19105
19106         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19107                 error "Setstripe failed"
19108
19109         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19110
19111         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19112                     grep "watermarks")
19113         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19114
19115         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19116                         osp.$mdtosc_proc1.prealloc_status)
19117         echo "prealloc_status $oa_status"
19118
19119         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19120                 error "File creation should fail"
19121
19122         #object allocation was stopped, but we still able to append files
19123         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19124                 oflag=append || error "Append failed"
19125
19126         rm -f $DIR/$tdir/$tfile.0
19127
19128         # For this test, we want to delete the files we created to go out of
19129         # space but leave the watermark, so we remain nearly out of space
19130         ost_watermarks_enospc_delete_files $tfile $ostidx
19131
19132         wait_delete_completed
19133
19134         sleep_maxage
19135
19136         for i in $(seq 10 12); do
19137                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19138                         2>/dev/null || error "File creation failed after rm"
19139         done
19140
19141         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19142                         osp.$mdtosc_proc1.prealloc_status)
19143         echo "prealloc_status $oa_status"
19144
19145         if (( oa_status != 0 )); then
19146                 error "Object allocation still disable after rm"
19147         fi
19148 }
19149 run_test 253 "Check object allocation limit"
19150
19151 test_254() {
19152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19153         remote_mds_nodsh && skip "remote MDS with nodsh"
19154         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19155                 skip "MDS does not support changelog_size"
19156
19157         local cl_user
19158         local MDT0=$(facet_svc $SINGLEMDS)
19159
19160         changelog_register || error "changelog_register failed"
19161
19162         changelog_clear 0 || error "changelog_clear failed"
19163
19164         local size1=$(do_facet $SINGLEMDS \
19165                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19166         echo "Changelog size $size1"
19167
19168         rm -rf $DIR/$tdir
19169         $LFS mkdir -i 0 $DIR/$tdir
19170         # change something
19171         mkdir -p $DIR/$tdir/pics/2008/zachy
19172         touch $DIR/$tdir/pics/2008/zachy/timestamp
19173         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19174         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19175         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19176         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19177         rm $DIR/$tdir/pics/desktop.jpg
19178
19179         local size2=$(do_facet $SINGLEMDS \
19180                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19181         echo "Changelog size after work $size2"
19182
19183         (( $size2 > $size1 )) ||
19184                 error "new Changelog size=$size2 less than old size=$size1"
19185 }
19186 run_test 254 "Check changelog size"
19187
19188 ladvise_no_type()
19189 {
19190         local type=$1
19191         local file=$2
19192
19193         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19194                 awk -F: '{print $2}' | grep $type > /dev/null
19195         if [ $? -ne 0 ]; then
19196                 return 0
19197         fi
19198         return 1
19199 }
19200
19201 ladvise_no_ioctl()
19202 {
19203         local file=$1
19204
19205         lfs ladvise -a willread $file > /dev/null 2>&1
19206         if [ $? -eq 0 ]; then
19207                 return 1
19208         fi
19209
19210         lfs ladvise -a willread $file 2>&1 |
19211                 grep "Inappropriate ioctl for device" > /dev/null
19212         if [ $? -eq 0 ]; then
19213                 return 0
19214         fi
19215         return 1
19216 }
19217
19218 percent() {
19219         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19220 }
19221
19222 # run a random read IO workload
19223 # usage: random_read_iops <filename> <filesize> <iosize>
19224 random_read_iops() {
19225         local file=$1
19226         local fsize=$2
19227         local iosize=${3:-4096}
19228
19229         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19230                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19231 }
19232
19233 drop_file_oss_cache() {
19234         local file="$1"
19235         local nodes="$2"
19236
19237         $LFS ladvise -a dontneed $file 2>/dev/null ||
19238                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19239 }
19240
19241 ladvise_willread_performance()
19242 {
19243         local repeat=10
19244         local average_origin=0
19245         local average_cache=0
19246         local average_ladvise=0
19247
19248         for ((i = 1; i <= $repeat; i++)); do
19249                 echo "Iter $i/$repeat: reading without willread hint"
19250                 cancel_lru_locks osc
19251                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19252                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19253                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19254                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19255
19256                 cancel_lru_locks osc
19257                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19258                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19259                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19260
19261                 cancel_lru_locks osc
19262                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19263                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19264                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19265                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19266                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19267         done
19268         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19269         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19270         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19271
19272         speedup_cache=$(percent $average_cache $average_origin)
19273         speedup_ladvise=$(percent $average_ladvise $average_origin)
19274
19275         echo "Average uncached read: $average_origin"
19276         echo "Average speedup with OSS cached read: " \
19277                 "$average_cache = +$speedup_cache%"
19278         echo "Average speedup with ladvise willread: " \
19279                 "$average_ladvise = +$speedup_ladvise%"
19280
19281         local lowest_speedup=20
19282         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19283                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19284                         "got $average_cache%. Skipping ladvise willread check."
19285                 return 0
19286         fi
19287
19288         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19289         # it is still good to run until then to exercise 'ladvise willread'
19290         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19291                 [ "$ost1_FSTYPE" = "zfs" ] &&
19292                 echo "osd-zfs does not support dontneed or drop_caches" &&
19293                 return 0
19294
19295         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19296         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
19297                 error_not_in_vm "Speedup with willread is less than " \
19298                         "$lowest_speedup%, got $average_ladvise%"
19299 }
19300
19301 test_255a() {
19302         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19303                 skip "lustre < 2.8.54 does not support ladvise "
19304         remote_ost_nodsh && skip "remote OST with nodsh"
19305
19306         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19307
19308         ladvise_no_type willread $DIR/$tfile &&
19309                 skip "willread ladvise is not supported"
19310
19311         ladvise_no_ioctl $DIR/$tfile &&
19312                 skip "ladvise ioctl is not supported"
19313
19314         local size_mb=100
19315         local size=$((size_mb * 1048576))
19316         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19317                 error "dd to $DIR/$tfile failed"
19318
19319         lfs ladvise -a willread $DIR/$tfile ||
19320                 error "Ladvise failed with no range argument"
19321
19322         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19323                 error "Ladvise failed with no -l or -e argument"
19324
19325         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19326                 error "Ladvise failed with only -e argument"
19327
19328         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19329                 error "Ladvise failed with only -l argument"
19330
19331         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19332                 error "End offset should not be smaller than start offset"
19333
19334         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19335                 error "End offset should not be equal to start offset"
19336
19337         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19338                 error "Ladvise failed with overflowing -s argument"
19339
19340         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19341                 error "Ladvise failed with overflowing -e argument"
19342
19343         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19344                 error "Ladvise failed with overflowing -l argument"
19345
19346         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19347                 error "Ladvise succeeded with conflicting -l and -e arguments"
19348
19349         echo "Synchronous ladvise should wait"
19350         local delay=4
19351 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19352         do_nodes $(comma_list $(osts_nodes)) \
19353                 $LCTL set_param fail_val=$delay fail_loc=0x237
19354
19355         local start_ts=$SECONDS
19356         lfs ladvise -a willread $DIR/$tfile ||
19357                 error "Ladvise failed with no range argument"
19358         local end_ts=$SECONDS
19359         local inteval_ts=$((end_ts - start_ts))
19360
19361         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19362                 error "Synchronous advice didn't wait reply"
19363         fi
19364
19365         echo "Asynchronous ladvise shouldn't wait"
19366         local start_ts=$SECONDS
19367         lfs ladvise -a willread -b $DIR/$tfile ||
19368                 error "Ladvise failed with no range argument"
19369         local end_ts=$SECONDS
19370         local inteval_ts=$((end_ts - start_ts))
19371
19372         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19373                 error "Asynchronous advice blocked"
19374         fi
19375
19376         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19377         ladvise_willread_performance
19378 }
19379 run_test 255a "check 'lfs ladvise -a willread'"
19380
19381 facet_meminfo() {
19382         local facet=$1
19383         local info=$2
19384
19385         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19386 }
19387
19388 test_255b() {
19389         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19390                 skip "lustre < 2.8.54 does not support ladvise "
19391         remote_ost_nodsh && skip "remote OST with nodsh"
19392
19393         lfs setstripe -c 1 -i 0 $DIR/$tfile
19394
19395         ladvise_no_type dontneed $DIR/$tfile &&
19396                 skip "dontneed ladvise is not supported"
19397
19398         ladvise_no_ioctl $DIR/$tfile &&
19399                 skip "ladvise ioctl is not supported"
19400
19401         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19402                 [ "$ost1_FSTYPE" = "zfs" ] &&
19403                 skip "zfs-osd does not support 'ladvise dontneed'"
19404
19405         local size_mb=100
19406         local size=$((size_mb * 1048576))
19407         # In order to prevent disturbance of other processes, only check 3/4
19408         # of the memory usage
19409         local kibibytes=$((size_mb * 1024 * 3 / 4))
19410
19411         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19412                 error "dd to $DIR/$tfile failed"
19413
19414         #force write to complete before dropping OST cache & checking memory
19415         sync
19416
19417         local total=$(facet_meminfo ost1 MemTotal)
19418         echo "Total memory: $total KiB"
19419
19420         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19421         local before_read=$(facet_meminfo ost1 Cached)
19422         echo "Cache used before read: $before_read KiB"
19423
19424         lfs ladvise -a willread $DIR/$tfile ||
19425                 error "Ladvise willread failed"
19426         local after_read=$(facet_meminfo ost1 Cached)
19427         echo "Cache used after read: $after_read KiB"
19428
19429         lfs ladvise -a dontneed $DIR/$tfile ||
19430                 error "Ladvise dontneed again failed"
19431         local no_read=$(facet_meminfo ost1 Cached)
19432         echo "Cache used after dontneed ladvise: $no_read KiB"
19433
19434         if [ $total -lt $((before_read + kibibytes)) ]; then
19435                 echo "Memory is too small, abort checking"
19436                 return 0
19437         fi
19438
19439         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19440                 error "Ladvise willread should use more memory" \
19441                         "than $kibibytes KiB"
19442         fi
19443
19444         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19445                 error "Ladvise dontneed should release more memory" \
19446                         "than $kibibytes KiB"
19447         fi
19448 }
19449 run_test 255b "check 'lfs ladvise -a dontneed'"
19450
19451 test_255c() {
19452         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19453                 skip "lustre < 2.10.50 does not support lockahead"
19454
19455         local count
19456         local new_count
19457         local difference
19458         local i
19459         local rc
19460
19461         test_mkdir -p $DIR/$tdir
19462         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19463
19464         #test 10 returns only success/failure
19465         i=10
19466         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19467         rc=$?
19468         if [ $rc -eq 255 ]; then
19469                 error "Ladvise test${i} failed, ${rc}"
19470         fi
19471
19472         #test 11 counts lock enqueue requests, all others count new locks
19473         i=11
19474         count=$(do_facet ost1 \
19475                 $LCTL get_param -n ost.OSS.ost.stats)
19476         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19477
19478         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19479         rc=$?
19480         if [ $rc -eq 255 ]; then
19481                 error "Ladvise test${i} failed, ${rc}"
19482         fi
19483
19484         new_count=$(do_facet ost1 \
19485                 $LCTL get_param -n ost.OSS.ost.stats)
19486         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19487                    awk '{ print $2 }')
19488
19489         difference="$((new_count - count))"
19490         if [ $difference -ne $rc ]; then
19491                 error "Ladvise test${i}, bad enqueue count, returned " \
19492                       "${rc}, actual ${difference}"
19493         fi
19494
19495         for i in $(seq 12 21); do
19496                 # If we do not do this, we run the risk of having too many
19497                 # locks and starting lock cancellation while we are checking
19498                 # lock counts.
19499                 cancel_lru_locks osc
19500
19501                 count=$($LCTL get_param -n \
19502                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19503
19504                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19505                 rc=$?
19506                 if [ $rc -eq 255 ]; then
19507                         error "Ladvise test ${i} failed, ${rc}"
19508                 fi
19509
19510                 new_count=$($LCTL get_param -n \
19511                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19512                 difference="$((new_count - count))"
19513
19514                 # Test 15 output is divided by 100 to map down to valid return
19515                 if [ $i -eq 15 ]; then
19516                         rc="$((rc * 100))"
19517                 fi
19518
19519                 if [ $difference -ne $rc ]; then
19520                         error "Ladvise test ${i}, bad lock count, returned " \
19521                               "${rc}, actual ${difference}"
19522                 fi
19523         done
19524
19525         #test 22 returns only success/failure
19526         i=22
19527         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19528         rc=$?
19529         if [ $rc -eq 255 ]; then
19530                 error "Ladvise test${i} failed, ${rc}"
19531         fi
19532 }
19533 run_test 255c "suite of ladvise lockahead tests"
19534
19535 test_256() {
19536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19537         remote_mds_nodsh && skip "remote MDS with nodsh"
19538         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19539         changelog_users $SINGLEMDS | grep "^cl" &&
19540                 skip "active changelog user"
19541
19542         local cl_user
19543         local cat_sl
19544         local mdt_dev
19545
19546         mdt_dev=$(mdsdevname 1)
19547         echo $mdt_dev
19548
19549         changelog_register || error "changelog_register failed"
19550
19551         rm -rf $DIR/$tdir
19552         mkdir -p $DIR/$tdir
19553
19554         changelog_clear 0 || error "changelog_clear failed"
19555
19556         # change something
19557         touch $DIR/$tdir/{1..10}
19558
19559         # stop the MDT
19560         stop $SINGLEMDS || error "Fail to stop MDT"
19561
19562         # remount the MDT
19563
19564         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19565
19566         #after mount new plainllog is used
19567         touch $DIR/$tdir/{11..19}
19568         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19569         stack_trap "rm -f $tmpfile"
19570         cat_sl=$(do_facet $SINGLEMDS "sync; \
19571                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19572                  llog_reader $tmpfile | grep -c type=1064553b")
19573         do_facet $SINGLEMDS llog_reader $tmpfile
19574
19575         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19576
19577         changelog_clear 0 || error "changelog_clear failed"
19578
19579         cat_sl=$(do_facet $SINGLEMDS "sync; \
19580                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19581                  llog_reader $tmpfile | grep -c type=1064553b")
19582
19583         if (( cat_sl == 2 )); then
19584                 error "Empty plain llog was not deleted from changelog catalog"
19585         elif (( cat_sl != 1 )); then
19586                 error "Active plain llog shouldn't be deleted from catalog"
19587         fi
19588 }
19589 run_test 256 "Check llog delete for empty and not full state"
19590
19591 test_257() {
19592         remote_mds_nodsh && skip "remote MDS with nodsh"
19593         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19594                 skip "Need MDS version at least 2.8.55"
19595
19596         test_mkdir $DIR/$tdir
19597
19598         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19599                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19600         stat $DIR/$tdir
19601
19602 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19603         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19604         local facet=mds$((mdtidx + 1))
19605         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19606         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19607
19608         stop $facet || error "stop MDS failed"
19609         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19610                 error "start MDS fail"
19611         wait_recovery_complete $facet
19612 }
19613 run_test 257 "xattr locks are not lost"
19614
19615 # Verify we take the i_mutex when security requires it
19616 test_258a() {
19617 #define OBD_FAIL_IMUTEX_SEC 0x141c
19618         $LCTL set_param fail_loc=0x141c
19619         touch $DIR/$tfile
19620         chmod u+s $DIR/$tfile
19621         chmod a+rwx $DIR/$tfile
19622         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19623         RC=$?
19624         if [ $RC -ne 0 ]; then
19625                 error "error, failed to take i_mutex, rc=$?"
19626         fi
19627         rm -f $DIR/$tfile
19628 }
19629 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19630
19631 # Verify we do NOT take the i_mutex in the normal case
19632 test_258b() {
19633 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19634         $LCTL set_param fail_loc=0x141d
19635         touch $DIR/$tfile
19636         chmod a+rwx $DIR
19637         chmod a+rw $DIR/$tfile
19638         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19639         RC=$?
19640         if [ $RC -ne 0 ]; then
19641                 error "error, took i_mutex unnecessarily, rc=$?"
19642         fi
19643         rm -f $DIR/$tfile
19644
19645 }
19646 run_test 258b "verify i_mutex security behavior"
19647
19648 test_259() {
19649         local file=$DIR/$tfile
19650         local before
19651         local after
19652
19653         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19654
19655         stack_trap "rm -f $file" EXIT
19656
19657         wait_delete_completed
19658         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19659         echo "before: $before"
19660
19661         $LFS setstripe -i 0 -c 1 $file
19662         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19663         sync_all_data
19664         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19665         echo "after write: $after"
19666
19667 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19668         do_facet ost1 $LCTL set_param fail_loc=0x2301
19669         $TRUNCATE $file 0
19670         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19671         echo "after truncate: $after"
19672
19673         stop ost1
19674         do_facet ost1 $LCTL set_param fail_loc=0
19675         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19676         sleep 2
19677         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19678         echo "after restart: $after"
19679         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19680                 error "missing truncate?"
19681
19682         return 0
19683 }
19684 run_test 259 "crash at delayed truncate"
19685
19686 test_260() {
19687 #define OBD_FAIL_MDC_CLOSE               0x806
19688         $LCTL set_param fail_loc=0x80000806
19689         touch $DIR/$tfile
19690
19691 }
19692 run_test 260 "Check mdc_close fail"
19693
19694 ### Data-on-MDT sanity tests ###
19695 test_270a() {
19696         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19697                 skip "Need MDS version at least 2.10.55 for DoM"
19698
19699         # create DoM file
19700         local dom=$DIR/$tdir/dom_file
19701         local tmp=$DIR/$tdir/tmp_file
19702
19703         mkdir -p $DIR/$tdir
19704
19705         # basic checks for DoM component creation
19706         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19707                 error "Can set MDT layout to non-first entry"
19708
19709         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19710                 error "Can define multiple entries as MDT layout"
19711
19712         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19713
19714         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19715         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19716         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19717
19718         local mdtidx=$($LFS getstripe -m $dom)
19719         local mdtname=MDT$(printf %04x $mdtidx)
19720         local facet=mds$((mdtidx + 1))
19721         local space_check=1
19722
19723         # Skip free space checks with ZFS
19724         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19725
19726         # write
19727         sync
19728         local size_tmp=$((65536 * 3))
19729         local mdtfree1=$(do_facet $facet \
19730                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19731
19732         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19733         # check also direct IO along write
19734         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19735         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19736         sync
19737         cmp $tmp $dom || error "file data is different"
19738         [ $(stat -c%s $dom) == $size_tmp ] ||
19739                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19740         if [ $space_check == 1 ]; then
19741                 local mdtfree2=$(do_facet $facet \
19742                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19743
19744                 # increase in usage from by $size_tmp
19745                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19746                         error "MDT free space wrong after write: " \
19747                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19748         fi
19749
19750         # truncate
19751         local size_dom=10000
19752
19753         $TRUNCATE $dom $size_dom
19754         [ $(stat -c%s $dom) == $size_dom ] ||
19755                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19756         if [ $space_check == 1 ]; then
19757                 mdtfree1=$(do_facet $facet \
19758                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19759                 # decrease in usage from $size_tmp to new $size_dom
19760                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19761                   $(((size_tmp - size_dom) / 1024)) ] ||
19762                         error "MDT free space is wrong after truncate: " \
19763                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19764         fi
19765
19766         # append
19767         cat $tmp >> $dom
19768         sync
19769         size_dom=$((size_dom + size_tmp))
19770         [ $(stat -c%s $dom) == $size_dom ] ||
19771                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19772         if [ $space_check == 1 ]; then
19773                 mdtfree2=$(do_facet $facet \
19774                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19775                 # increase in usage by $size_tmp from previous
19776                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19777                         error "MDT free space is wrong after append: " \
19778                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19779         fi
19780
19781         # delete
19782         rm $dom
19783         if [ $space_check == 1 ]; then
19784                 mdtfree1=$(do_facet $facet \
19785                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19786                 # decrease in usage by $size_dom from previous
19787                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
19788                         error "MDT free space is wrong after removal: " \
19789                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
19790         fi
19791
19792         # combined striping
19793         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
19794                 error "Can't create DoM + OST striping"
19795
19796         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
19797         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19798         # check also direct IO along write
19799         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19800         sync
19801         cmp $tmp $dom || error "file data is different"
19802         [ $(stat -c%s $dom) == $size_tmp ] ||
19803                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19804         rm $dom $tmp
19805
19806         return 0
19807 }
19808 run_test 270a "DoM: basic functionality tests"
19809
19810 test_270b() {
19811         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19812                 skip "Need MDS version at least 2.10.55"
19813
19814         local dom=$DIR/$tdir/dom_file
19815         local max_size=1048576
19816
19817         mkdir -p $DIR/$tdir
19818         $LFS setstripe -E $max_size -L mdt $dom
19819
19820         # truncate over the limit
19821         $TRUNCATE $dom $(($max_size + 1)) &&
19822                 error "successful truncate over the maximum size"
19823         # write over the limit
19824         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
19825                 error "successful write over the maximum size"
19826         # append over the limit
19827         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
19828         echo "12345" >> $dom && error "successful append over the maximum size"
19829         rm $dom
19830
19831         return 0
19832 }
19833 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
19834
19835 test_270c() {
19836         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19837                 skip "Need MDS version at least 2.10.55"
19838
19839         mkdir -p $DIR/$tdir
19840         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19841
19842         # check files inherit DoM EA
19843         touch $DIR/$tdir/first
19844         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
19845                 error "bad pattern"
19846         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
19847                 error "bad stripe count"
19848         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
19849                 error "bad stripe size"
19850
19851         # check directory inherits DoM EA and uses it as default
19852         mkdir $DIR/$tdir/subdir
19853         touch $DIR/$tdir/subdir/second
19854         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
19855                 error "bad pattern in sub-directory"
19856         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
19857                 error "bad stripe count in sub-directory"
19858         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
19859                 error "bad stripe size in sub-directory"
19860         return 0
19861 }
19862 run_test 270c "DoM: DoM EA inheritance tests"
19863
19864 test_270d() {
19865         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19866                 skip "Need MDS version at least 2.10.55"
19867
19868         mkdir -p $DIR/$tdir
19869         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19870
19871         # inherit default DoM striping
19872         mkdir $DIR/$tdir/subdir
19873         touch $DIR/$tdir/subdir/f1
19874
19875         # change default directory striping
19876         $LFS setstripe -c 1 $DIR/$tdir/subdir
19877         touch $DIR/$tdir/subdir/f2
19878         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
19879                 error "wrong default striping in file 2"
19880         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
19881                 error "bad pattern in file 2"
19882         return 0
19883 }
19884 run_test 270d "DoM: change striping from DoM to RAID0"
19885
19886 test_270e() {
19887         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19888                 skip "Need MDS version at least 2.10.55"
19889
19890         mkdir -p $DIR/$tdir/dom
19891         mkdir -p $DIR/$tdir/norm
19892         DOMFILES=20
19893         NORMFILES=10
19894         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
19895         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
19896
19897         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
19898         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
19899
19900         # find DoM files by layout
19901         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
19902         [ $NUM -eq  $DOMFILES ] ||
19903                 error "lfs find -L: found $NUM, expected $DOMFILES"
19904         echo "Test 1: lfs find 20 DOM files by layout: OK"
19905
19906         # there should be 1 dir with default DOM striping
19907         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
19908         [ $NUM -eq  1 ] ||
19909                 error "lfs find -L: found $NUM, expected 1 dir"
19910         echo "Test 2: lfs find 1 DOM dir by layout: OK"
19911
19912         # find DoM files by stripe size
19913         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
19914         [ $NUM -eq  $DOMFILES ] ||
19915                 error "lfs find -S: found $NUM, expected $DOMFILES"
19916         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
19917
19918         # find files by stripe offset except DoM files
19919         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
19920         [ $NUM -eq  $NORMFILES ] ||
19921                 error "lfs find -i: found $NUM, expected $NORMFILES"
19922         echo "Test 5: lfs find no DOM files by stripe index: OK"
19923         return 0
19924 }
19925 run_test 270e "DoM: lfs find with DoM files test"
19926
19927 test_270f() {
19928         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19929                 skip "Need MDS version at least 2.10.55"
19930
19931         local mdtname=${FSNAME}-MDT0000-mdtlov
19932         local dom=$DIR/$tdir/dom_file
19933         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
19934                                                 lod.$mdtname.dom_stripesize)
19935         local dom_limit=131072
19936
19937         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
19938         local dom_current=$(do_facet mds1 $LCTL get_param -n \
19939                                                 lod.$mdtname.dom_stripesize)
19940         [ ${dom_limit} -eq ${dom_current} ] ||
19941                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
19942
19943         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19944         $LFS setstripe -d $DIR/$tdir
19945         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
19946                 error "Can't set directory default striping"
19947
19948         # exceed maximum stripe size
19949         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
19950                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
19951         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
19952                 error "Able to create DoM component size more than LOD limit"
19953
19954         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
19955         dom_current=$(do_facet mds1 $LCTL get_param -n \
19956                                                 lod.$mdtname.dom_stripesize)
19957         [ 0 -eq ${dom_current} ] ||
19958                 error "Can't set zero DoM stripe limit"
19959         rm $dom
19960
19961         # attempt to create DoM file on server with disabled DoM should
19962         # remove DoM entry from layout and be succeed
19963         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
19964                 error "Can't create DoM file (DoM is disabled)"
19965         [ $($LFS getstripe -L $dom) == "mdt" ] &&
19966                 error "File has DoM component while DoM is disabled"
19967         rm $dom
19968
19969         # attempt to create DoM file with only DoM stripe should return error
19970         $LFS setstripe -E $dom_limit -L mdt $dom &&
19971                 error "Able to create DoM-only file while DoM is disabled"
19972
19973         # too low values to be aligned with smallest stripe size 64K
19974         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
19975         dom_current=$(do_facet mds1 $LCTL get_param -n \
19976                                                 lod.$mdtname.dom_stripesize)
19977         [ 30000 -eq ${dom_current} ] &&
19978                 error "Can set too small DoM stripe limit"
19979
19980         # 64K is a minimal stripe size in Lustre, expect limit of that size
19981         [ 65536 -eq ${dom_current} ] ||
19982                 error "Limit is not set to 64K but ${dom_current}"
19983
19984         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
19985         dom_current=$(do_facet mds1 $LCTL get_param -n \
19986                                                 lod.$mdtname.dom_stripesize)
19987         echo $dom_current
19988         [ 2147483648 -eq ${dom_current} ] &&
19989                 error "Can set too large DoM stripe limit"
19990
19991         do_facet mds1 $LCTL set_param -n \
19992                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
19993         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
19994                 error "Can't create DoM component size after limit change"
19995         do_facet mds1 $LCTL set_param -n \
19996                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
19997         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
19998                 error "Can't create DoM file after limit decrease"
19999         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20000                 error "Can create big DoM component after limit decrease"
20001         touch ${dom}_def ||
20002                 error "Can't create file with old default layout"
20003
20004         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20005         return 0
20006 }
20007 run_test 270f "DoM: maximum DoM stripe size checks"
20008
20009 test_270g() {
20010         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20011                 skip "Need MDS version at least 2.13.52"
20012         local dom=$DIR/$tdir/$tfile
20013
20014         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20015         local lodname=${FSNAME}-MDT0000-mdtlov
20016
20017         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20018         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20019         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20020         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20021
20022         local dom_limit=1024
20023         local dom_threshold="50%"
20024
20025         $LFS setstripe -d $DIR/$tdir
20026         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20027                 error "Can't set directory default striping"
20028
20029         do_facet mds1 $LCTL set_param -n \
20030                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20031         # set 0 threshold and create DOM file to change tunable stripesize
20032         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20033         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20034                 error "Failed to create $dom file"
20035         # now tunable dom_cur_stripesize should reach maximum
20036         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20037                                         lod.${lodname}.dom_stripesize_cur_kb)
20038         [[ $dom_current == $dom_limit ]] ||
20039                 error "Current DOM stripesize is not maximum"
20040         rm $dom
20041
20042         # set threshold for further tests
20043         do_facet mds1 $LCTL set_param -n \
20044                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20045         echo "DOM threshold is $dom_threshold free space"
20046         local dom_def
20047         local dom_set
20048         # Spoof bfree to exceed threshold
20049         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20050         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20051         for spfree in 40 20 0 15 30 55; do
20052                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20053                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20054                         error "Failed to create $dom file"
20055                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20056                                         lod.${lodname}.dom_stripesize_cur_kb)
20057                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20058                 [[ $dom_def != $dom_current ]] ||
20059                         error "Default stripe size was not changed"
20060                 if [[ $spfree > 0 ]] ; then
20061                         dom_set=$($LFS getstripe -S $dom)
20062                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20063                                 error "DOM component size is still old"
20064                 else
20065                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20066                                 error "DoM component is set with no free space"
20067                 fi
20068                 rm $dom
20069                 dom_current=$dom_def
20070         done
20071 }
20072 run_test 270g "DoM: default DoM stripe size depends on free space"
20073
20074 test_270h() {
20075         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20076                 skip "Need MDS version at least 2.13.53"
20077
20078         local mdtname=${FSNAME}-MDT0000-mdtlov
20079         local dom=$DIR/$tdir/$tfile
20080         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20081
20082         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20083         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20084
20085         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20086         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20087                 error "can't create OST file"
20088         # mirrored file with DOM entry in the second mirror
20089         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20090                 error "can't create mirror with DoM component"
20091
20092         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20093
20094         # DOM component in the middle and has other enries in the same mirror,
20095         # should succeed but lost DoM component
20096         $LFS setstripe --copy=${dom}_1 $dom ||
20097                 error "Can't create file from OST|DOM mirror layout"
20098         # check new file has no DoM layout after all
20099         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20100                 error "File has DoM component while DoM is disabled"
20101 }
20102 run_test 270h "DoM: DoM stripe removal when disabled on server"
20103
20104 test_271a() {
20105         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20106                 skip "Need MDS version at least 2.10.55"
20107
20108         local dom=$DIR/$tdir/dom
20109
20110         mkdir -p $DIR/$tdir
20111
20112         $LFS setstripe -E 1024K -L mdt $dom
20113
20114         lctl set_param -n mdc.*.stats=clear
20115         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20116         cat $dom > /dev/null
20117         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20118         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20119         ls $dom
20120         rm -f $dom
20121 }
20122 run_test 271a "DoM: data is cached for read after write"
20123
20124 test_271b() {
20125         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20126                 skip "Need MDS version at least 2.10.55"
20127
20128         local dom=$DIR/$tdir/dom
20129
20130         mkdir -p $DIR/$tdir
20131
20132         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20133
20134         lctl set_param -n mdc.*.stats=clear
20135         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20136         cancel_lru_locks mdc
20137         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20138         # second stat to check size is cached on client
20139         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20140         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20141         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20142         rm -f $dom
20143 }
20144 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20145
20146 test_271ba() {
20147         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20148                 skip "Need MDS version at least 2.10.55"
20149
20150         local dom=$DIR/$tdir/dom
20151
20152         mkdir -p $DIR/$tdir
20153
20154         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20155
20156         lctl set_param -n mdc.*.stats=clear
20157         lctl set_param -n osc.*.stats=clear
20158         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20159         cancel_lru_locks mdc
20160         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20161         # second stat to check size is cached on client
20162         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20163         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20164         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20165         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20166         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20167         rm -f $dom
20168 }
20169 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20170
20171
20172 get_mdc_stats() {
20173         local mdtidx=$1
20174         local param=$2
20175         local mdt=MDT$(printf %04x $mdtidx)
20176
20177         if [ -z $param ]; then
20178                 lctl get_param -n mdc.*$mdt*.stats
20179         else
20180                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20181         fi
20182 }
20183
20184 test_271c() {
20185         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20186                 skip "Need MDS version at least 2.10.55"
20187
20188         local dom=$DIR/$tdir/dom
20189
20190         mkdir -p $DIR/$tdir
20191
20192         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20193
20194         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20195         local facet=mds$((mdtidx + 1))
20196
20197         cancel_lru_locks mdc
20198         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20199         createmany -o $dom 1000
20200         lctl set_param -n mdc.*.stats=clear
20201         smalliomany -w $dom 1000 200
20202         get_mdc_stats $mdtidx
20203         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20204         # Each file has 1 open, 1 IO enqueues, total 2000
20205         # but now we have also +1 getxattr for security.capability, total 3000
20206         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20207         unlinkmany $dom 1000
20208
20209         cancel_lru_locks mdc
20210         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20211         createmany -o $dom 1000
20212         lctl set_param -n mdc.*.stats=clear
20213         smalliomany -w $dom 1000 200
20214         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20215         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20216         # for OPEN and IO lock.
20217         [ $((enq - enq_2)) -ge 1000 ] ||
20218                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20219         unlinkmany $dom 1000
20220         return 0
20221 }
20222 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20223
20224 cleanup_271def_tests() {
20225         trap 0
20226         rm -f $1
20227 }
20228
20229 test_271d() {
20230         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20231                 skip "Need MDS version at least 2.10.57"
20232
20233         local dom=$DIR/$tdir/dom
20234         local tmp=$TMP/$tfile
20235         trap "cleanup_271def_tests $tmp" EXIT
20236
20237         mkdir -p $DIR/$tdir
20238
20239         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20240
20241         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20242
20243         cancel_lru_locks mdc
20244         dd if=/dev/urandom of=$tmp bs=1000 count=1
20245         dd if=$tmp of=$dom bs=1000 count=1
20246         cancel_lru_locks mdc
20247
20248         cat /etc/hosts >> $tmp
20249         lctl set_param -n mdc.*.stats=clear
20250
20251         # append data to the same file it should update local page
20252         echo "Append to the same page"
20253         cat /etc/hosts >> $dom
20254         local num=$(get_mdc_stats $mdtidx ost_read)
20255         local ra=$(get_mdc_stats $mdtidx req_active)
20256         local rw=$(get_mdc_stats $mdtidx req_waittime)
20257
20258         [ -z $num ] || error "$num READ RPC occured"
20259         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20260         echo "... DONE"
20261
20262         # compare content
20263         cmp $tmp $dom || error "file miscompare"
20264
20265         cancel_lru_locks mdc
20266         lctl set_param -n mdc.*.stats=clear
20267
20268         echo "Open and read file"
20269         cat $dom > /dev/null
20270         local num=$(get_mdc_stats $mdtidx ost_read)
20271         local ra=$(get_mdc_stats $mdtidx req_active)
20272         local rw=$(get_mdc_stats $mdtidx req_waittime)
20273
20274         [ -z $num ] || error "$num READ RPC occured"
20275         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20276         echo "... DONE"
20277
20278         # compare content
20279         cmp $tmp $dom || error "file miscompare"
20280
20281         return 0
20282 }
20283 run_test 271d "DoM: read on open (1K file in reply buffer)"
20284
20285 test_271f() {
20286         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20287                 skip "Need MDS version at least 2.10.57"
20288
20289         local dom=$DIR/$tdir/dom
20290         local tmp=$TMP/$tfile
20291         trap "cleanup_271def_tests $tmp" EXIT
20292
20293         mkdir -p $DIR/$tdir
20294
20295         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20296
20297         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20298
20299         cancel_lru_locks mdc
20300         dd if=/dev/urandom of=$tmp bs=265000 count=1
20301         dd if=$tmp of=$dom bs=265000 count=1
20302         cancel_lru_locks mdc
20303         cat /etc/hosts >> $tmp
20304         lctl set_param -n mdc.*.stats=clear
20305
20306         echo "Append to the same page"
20307         cat /etc/hosts >> $dom
20308         local num=$(get_mdc_stats $mdtidx ost_read)
20309         local ra=$(get_mdc_stats $mdtidx req_active)
20310         local rw=$(get_mdc_stats $mdtidx req_waittime)
20311
20312         [ -z $num ] || error "$num READ RPC occured"
20313         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20314         echo "... DONE"
20315
20316         # compare content
20317         cmp $tmp $dom || error "file miscompare"
20318
20319         cancel_lru_locks mdc
20320         lctl set_param -n mdc.*.stats=clear
20321
20322         echo "Open and read file"
20323         cat $dom > /dev/null
20324         local num=$(get_mdc_stats $mdtidx ost_read)
20325         local ra=$(get_mdc_stats $mdtidx req_active)
20326         local rw=$(get_mdc_stats $mdtidx req_waittime)
20327
20328         [ -z $num ] && num=0
20329         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20330         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20331         echo "... DONE"
20332
20333         # compare content
20334         cmp $tmp $dom || error "file miscompare"
20335
20336         return 0
20337 }
20338 run_test 271f "DoM: read on open (200K file and read tail)"
20339
20340 test_271g() {
20341         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20342                 skip "Skipping due to old client or server version"
20343
20344         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20345         # to get layout
20346         $CHECKSTAT -t file $DIR1/$tfile
20347
20348         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20349         MULTIOP_PID=$!
20350         sleep 1
20351         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20352         $LCTL set_param fail_loc=0x80000314
20353         rm $DIR1/$tfile || error "Unlink fails"
20354         RC=$?
20355         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20356         [ $RC -eq 0 ] || error "Failed write to stale object"
20357 }
20358 run_test 271g "Discard DoM data vs client flush race"
20359
20360 test_272a() {
20361         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20362                 skip "Need MDS version at least 2.11.50"
20363
20364         local dom=$DIR/$tdir/dom
20365         mkdir -p $DIR/$tdir
20366
20367         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20368         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20369                 error "failed to write data into $dom"
20370         local old_md5=$(md5sum $dom)
20371
20372         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20373                 error "failed to migrate to the same DoM component"
20374
20375         local new_md5=$(md5sum $dom)
20376
20377         [ "$old_md5" == "$new_md5" ] ||
20378                 error "md5sum differ: $old_md5, $new_md5"
20379
20380         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20381                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20382 }
20383 run_test 272a "DoM migration: new layout with the same DOM component"
20384
20385 test_272b() {
20386         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20387                 skip "Need MDS version at least 2.11.50"
20388
20389         local dom=$DIR/$tdir/dom
20390         mkdir -p $DIR/$tdir
20391         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20392
20393         local mdtidx=$($LFS getstripe -m $dom)
20394         local mdtname=MDT$(printf %04x $mdtidx)
20395         local facet=mds$((mdtidx + 1))
20396
20397         local mdtfree1=$(do_facet $facet \
20398                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20399         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20400                 error "failed to write data into $dom"
20401         local old_md5=$(md5sum $dom)
20402         cancel_lru_locks mdc
20403         local mdtfree1=$(do_facet $facet \
20404                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20405
20406         $LFS migrate -c2 $dom ||
20407                 error "failed to migrate to the new composite layout"
20408         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20409                 error "MDT stripe was not removed"
20410
20411         cancel_lru_locks mdc
20412         local new_md5=$(md5sum $dom)
20413         [ "$old_md5" == "$new_md5" ] ||
20414                 error "$old_md5 != $new_md5"
20415
20416         # Skip free space checks with ZFS
20417         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20418                 local mdtfree2=$(do_facet $facet \
20419                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20420                 [ $mdtfree2 -gt $mdtfree1 ] ||
20421                         error "MDT space is not freed after migration"
20422         fi
20423         return 0
20424 }
20425 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20426
20427 test_272c() {
20428         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20429                 skip "Need MDS version at least 2.11.50"
20430
20431         local dom=$DIR/$tdir/$tfile
20432         mkdir -p $DIR/$tdir
20433         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20434
20435         local mdtidx=$($LFS getstripe -m $dom)
20436         local mdtname=MDT$(printf %04x $mdtidx)
20437         local facet=mds$((mdtidx + 1))
20438
20439         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20440                 error "failed to write data into $dom"
20441         local old_md5=$(md5sum $dom)
20442         cancel_lru_locks mdc
20443         local mdtfree1=$(do_facet $facet \
20444                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20445
20446         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20447                 error "failed to migrate to the new composite layout"
20448         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20449                 error "MDT stripe was not removed"
20450
20451         cancel_lru_locks mdc
20452         local new_md5=$(md5sum $dom)
20453         [ "$old_md5" == "$new_md5" ] ||
20454                 error "$old_md5 != $new_md5"
20455
20456         # Skip free space checks with ZFS
20457         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20458                 local mdtfree2=$(do_facet $facet \
20459                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20460                 [ $mdtfree2 -gt $mdtfree1 ] ||
20461                         error "MDS space is not freed after migration"
20462         fi
20463         return 0
20464 }
20465 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20466
20467 test_272d() {
20468         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20469                 skip "Need MDS version at least 2.12.55"
20470
20471         local dom=$DIR/$tdir/$tfile
20472         mkdir -p $DIR/$tdir
20473         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20474
20475         local mdtidx=$($LFS getstripe -m $dom)
20476         local mdtname=MDT$(printf %04x $mdtidx)
20477         local facet=mds$((mdtidx + 1))
20478
20479         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20480                 error "failed to write data into $dom"
20481         local old_md5=$(md5sum $dom)
20482         cancel_lru_locks mdc
20483         local mdtfree1=$(do_facet $facet \
20484                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20485
20486         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20487                 error "failed mirroring to the new composite layout"
20488         $LFS mirror resync $dom ||
20489                 error "failed mirror resync"
20490         $LFS mirror split --mirror-id 1 -d $dom ||
20491                 error "failed mirror split"
20492
20493         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20494                 error "MDT stripe was not removed"
20495
20496         cancel_lru_locks mdc
20497         local new_md5=$(md5sum $dom)
20498         [ "$old_md5" == "$new_md5" ] ||
20499                 error "$old_md5 != $new_md5"
20500
20501         # Skip free space checks with ZFS
20502         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20503                 local mdtfree2=$(do_facet $facet \
20504                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20505                 [ $mdtfree2 -gt $mdtfree1 ] ||
20506                         error "MDS space is not freed after DOM mirror deletion"
20507         fi
20508         return 0
20509 }
20510 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20511
20512 test_272e() {
20513         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20514                 skip "Need MDS version at least 2.12.55"
20515
20516         local dom=$DIR/$tdir/$tfile
20517         mkdir -p $DIR/$tdir
20518         $LFS setstripe -c 2 $dom
20519
20520         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20521                 error "failed to write data into $dom"
20522         local old_md5=$(md5sum $dom)
20523         cancel_lru_locks mdc
20524
20525         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20526                 error "failed mirroring to the DOM layout"
20527         $LFS mirror resync $dom ||
20528                 error "failed mirror resync"
20529         $LFS mirror split --mirror-id 1 -d $dom ||
20530                 error "failed mirror split"
20531
20532         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20533                 error "MDT stripe was not removed"
20534
20535         cancel_lru_locks mdc
20536         local new_md5=$(md5sum $dom)
20537         [ "$old_md5" == "$new_md5" ] ||
20538                 error "$old_md5 != $new_md5"
20539
20540         return 0
20541 }
20542 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20543
20544 test_272f() {
20545         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20546                 skip "Need MDS version at least 2.12.55"
20547
20548         local dom=$DIR/$tdir/$tfile
20549         mkdir -p $DIR/$tdir
20550         $LFS setstripe -c 2 $dom
20551
20552         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20553                 error "failed to write data into $dom"
20554         local old_md5=$(md5sum $dom)
20555         cancel_lru_locks mdc
20556
20557         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20558                 error "failed migrating to the DOM file"
20559
20560         cancel_lru_locks mdc
20561         local new_md5=$(md5sum $dom)
20562         [ "$old_md5" != "$new_md5" ] &&
20563                 error "$old_md5 != $new_md5"
20564
20565         return 0
20566 }
20567 run_test 272f "DoM migration: OST-striped file to DOM file"
20568
20569 test_273a() {
20570         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20571                 skip "Need MDS version at least 2.11.50"
20572
20573         # Layout swap cannot be done if either file has DOM component,
20574         # this will never be supported, migration should be used instead
20575
20576         local dom=$DIR/$tdir/$tfile
20577         mkdir -p $DIR/$tdir
20578
20579         $LFS setstripe -c2 ${dom}_plain
20580         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20581         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20582                 error "can swap layout with DoM component"
20583         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20584                 error "can swap layout with DoM component"
20585
20586         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20587         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20588                 error "can swap layout with DoM component"
20589         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20590                 error "can swap layout with DoM component"
20591         return 0
20592 }
20593 run_test 273a "DoM: layout swapping should fail with DOM"
20594
20595 test_275() {
20596         remote_ost_nodsh && skip "remote OST with nodsh"
20597         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20598                 skip "Need OST version >= 2.10.57"
20599
20600         local file=$DIR/$tfile
20601         local oss
20602
20603         oss=$(comma_list $(osts_nodes))
20604
20605         dd if=/dev/urandom of=$file bs=1M count=2 ||
20606                 error "failed to create a file"
20607         cancel_lru_locks osc
20608
20609         #lock 1
20610         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20611                 error "failed to read a file"
20612
20613 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20614         $LCTL set_param fail_loc=0x8000031f
20615
20616         cancel_lru_locks osc &
20617         sleep 1
20618
20619 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20620         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20621         #IO takes another lock, but matches the PENDING one
20622         #and places it to the IO RPC
20623         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20624                 error "failed to read a file with PENDING lock"
20625 }
20626 run_test 275 "Read on a canceled duplicate lock"
20627
20628 test_276() {
20629         remote_ost_nodsh && skip "remote OST with nodsh"
20630         local pid
20631
20632         do_facet ost1 "(while true; do \
20633                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20634                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20635         pid=$!
20636
20637         for LOOP in $(seq 20); do
20638                 stop ost1
20639                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20640         done
20641         kill -9 $pid
20642         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20643                 rm $TMP/sanity_276_pid"
20644 }
20645 run_test 276 "Race between mount and obd_statfs"
20646
20647 test_277() {
20648         $LCTL set_param ldlm.namespaces.*.lru_size=0
20649         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20650         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20651                         grep ^used_mb | awk '{print $2}')
20652         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20653         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20654                 oflag=direct conv=notrunc
20655         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20656                         grep ^used_mb | awk '{print $2}')
20657         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20658 }
20659 run_test 277 "Direct IO shall drop page cache"
20660
20661 test_278() {
20662         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20663         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20664         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20665                 skip "needs the same host for mdt1 mdt2" && return
20666
20667         local pid1
20668         local pid2
20669
20670 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20671         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20672         stop mds2 &
20673         pid2=$!
20674
20675         stop mds1
20676
20677         echo "Starting MDTs"
20678         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20679         wait $pid2
20680 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20681 #will return NULL
20682         do_facet mds2 $LCTL set_param fail_loc=0
20683
20684         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20685         wait_recovery_complete mds2
20686 }
20687 run_test 278 "Race starting MDS between MDTs stop/start"
20688
20689 test_280() {
20690         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20691                 skip "Need MGS version at least 2.13.52"
20692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20693         combined_mgs_mds || skip "needs combined MGS/MDT"
20694
20695         umount_client $MOUNT
20696 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20697         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20698
20699         mount_client $MOUNT &
20700         sleep 1
20701         stop mgs || error "stop mgs failed"
20702         #for a race mgs would crash
20703         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20704         mount_client $MOUNT || error "mount client failed"
20705 }
20706 run_test 280 "Race between MGS umount and client llog processing"
20707
20708 cleanup_test_300() {
20709         trap 0
20710         umask $SAVE_UMASK
20711 }
20712 test_striped_dir() {
20713         local mdt_index=$1
20714         local stripe_count
20715         local stripe_index
20716
20717         mkdir -p $DIR/$tdir
20718
20719         SAVE_UMASK=$(umask)
20720         trap cleanup_test_300 RETURN EXIT
20721
20722         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20723                                                 $DIR/$tdir/striped_dir ||
20724                 error "set striped dir error"
20725
20726         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20727         [ "$mode" = "755" ] || error "expect 755 got $mode"
20728
20729         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20730                 error "getdirstripe failed"
20731         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20732         if [ "$stripe_count" != "2" ]; then
20733                 error "1:stripe_count is $stripe_count, expect 2"
20734         fi
20735         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20736         if [ "$stripe_count" != "2" ]; then
20737                 error "2:stripe_count is $stripe_count, expect 2"
20738         fi
20739
20740         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20741         if [ "$stripe_index" != "$mdt_index" ]; then
20742                 error "stripe_index is $stripe_index, expect $mdt_index"
20743         fi
20744
20745         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20746                 error "nlink error after create striped dir"
20747
20748         mkdir $DIR/$tdir/striped_dir/a
20749         mkdir $DIR/$tdir/striped_dir/b
20750
20751         stat $DIR/$tdir/striped_dir/a ||
20752                 error "create dir under striped dir failed"
20753         stat $DIR/$tdir/striped_dir/b ||
20754                 error "create dir under striped dir failed"
20755
20756         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20757                 error "nlink error after mkdir"
20758
20759         rmdir $DIR/$tdir/striped_dir/a
20760         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20761                 error "nlink error after rmdir"
20762
20763         rmdir $DIR/$tdir/striped_dir/b
20764         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20765                 error "nlink error after rmdir"
20766
20767         chattr +i $DIR/$tdir/striped_dir
20768         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20769                 error "immutable flags not working under striped dir!"
20770         chattr -i $DIR/$tdir/striped_dir
20771
20772         rmdir $DIR/$tdir/striped_dir ||
20773                 error "rmdir striped dir error"
20774
20775         cleanup_test_300
20776
20777         true
20778 }
20779
20780 test_300a() {
20781         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20782                 skip "skipped for lustre < 2.7.0"
20783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20784         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20785
20786         test_striped_dir 0 || error "failed on striped dir on MDT0"
20787         test_striped_dir 1 || error "failed on striped dir on MDT0"
20788 }
20789 run_test 300a "basic striped dir sanity test"
20790
20791 test_300b() {
20792         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20793                 skip "skipped for lustre < 2.7.0"
20794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20795         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20796
20797         local i
20798         local mtime1
20799         local mtime2
20800         local mtime3
20801
20802         test_mkdir $DIR/$tdir || error "mkdir fail"
20803         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20804                 error "set striped dir error"
20805         for i in {0..9}; do
20806                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
20807                 sleep 1
20808                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
20809                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
20810                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
20811                 sleep 1
20812                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
20813                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
20814                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
20815         done
20816         true
20817 }
20818 run_test 300b "check ctime/mtime for striped dir"
20819
20820 test_300c() {
20821         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20822                 skip "skipped for lustre < 2.7.0"
20823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20824         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20825
20826         local file_count
20827
20828         mkdir -p $DIR/$tdir
20829         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
20830                 error "set striped dir error"
20831
20832         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
20833                 error "chown striped dir failed"
20834
20835         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
20836                 error "create 5k files failed"
20837
20838         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
20839
20840         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
20841
20842         rm -rf $DIR/$tdir
20843 }
20844 run_test 300c "chown && check ls under striped directory"
20845
20846 test_300d() {
20847         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20848                 skip "skipped for lustre < 2.7.0"
20849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20850         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20851
20852         local stripe_count
20853         local file
20854
20855         mkdir -p $DIR/$tdir
20856         $LFS setstripe -c 2 $DIR/$tdir
20857
20858         #local striped directory
20859         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20860                 error "set striped dir error"
20861         #look at the directories for debug purposes
20862         ls -l $DIR/$tdir
20863         $LFS getdirstripe $DIR/$tdir
20864         ls -l $DIR/$tdir/striped_dir
20865         $LFS getdirstripe $DIR/$tdir/striped_dir
20866         createmany -o $DIR/$tdir/striped_dir/f 10 ||
20867                 error "create 10 files failed"
20868
20869         #remote striped directory
20870         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
20871                 error "set striped dir error"
20872         #look at the directories for debug purposes
20873         ls -l $DIR/$tdir
20874         $LFS getdirstripe $DIR/$tdir
20875         ls -l $DIR/$tdir/remote_striped_dir
20876         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
20877         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
20878                 error "create 10 files failed"
20879
20880         for file in $(find $DIR/$tdir); do
20881                 stripe_count=$($LFS getstripe -c $file)
20882                 [ $stripe_count -eq 2 ] ||
20883                         error "wrong stripe $stripe_count for $file"
20884         done
20885
20886         rm -rf $DIR/$tdir
20887 }
20888 run_test 300d "check default stripe under striped directory"
20889
20890 test_300e() {
20891         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20892                 skip "Need MDS version at least 2.7.55"
20893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20894         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20895
20896         local stripe_count
20897         local file
20898
20899         mkdir -p $DIR/$tdir
20900
20901         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20902                 error "set striped dir error"
20903
20904         touch $DIR/$tdir/striped_dir/a
20905         touch $DIR/$tdir/striped_dir/b
20906         touch $DIR/$tdir/striped_dir/c
20907
20908         mkdir $DIR/$tdir/striped_dir/dir_a
20909         mkdir $DIR/$tdir/striped_dir/dir_b
20910         mkdir $DIR/$tdir/striped_dir/dir_c
20911
20912         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
20913                 error "set striped adir under striped dir error"
20914
20915         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
20916                 error "set striped bdir under striped dir error"
20917
20918         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
20919                 error "set striped cdir under striped dir error"
20920
20921         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
20922                 error "rename dir under striped dir fails"
20923
20924         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
20925                 error "rename dir under different stripes fails"
20926
20927         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
20928                 error "rename file under striped dir should succeed"
20929
20930         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
20931                 error "rename dir under striped dir should succeed"
20932
20933         rm -rf $DIR/$tdir
20934 }
20935 run_test 300e "check rename under striped directory"
20936
20937 test_300f() {
20938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20939         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20940         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20941                 skip "Need MDS version at least 2.7.55"
20942
20943         local stripe_count
20944         local file
20945
20946         rm -rf $DIR/$tdir
20947         mkdir -p $DIR/$tdir
20948
20949         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20950                 error "set striped dir error"
20951
20952         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
20953                 error "set striped dir error"
20954
20955         touch $DIR/$tdir/striped_dir/a
20956         mkdir $DIR/$tdir/striped_dir/dir_a
20957         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
20958                 error "create striped dir under striped dir fails"
20959
20960         touch $DIR/$tdir/striped_dir1/b
20961         mkdir $DIR/$tdir/striped_dir1/dir_b
20962         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
20963                 error "create striped dir under striped dir fails"
20964
20965         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
20966                 error "rename dir under different striped dir should fail"
20967
20968         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
20969                 error "rename striped dir under diff striped dir should fail"
20970
20971         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
20972                 error "rename file under diff striped dirs fails"
20973
20974         rm -rf $DIR/$tdir
20975 }
20976 run_test 300f "check rename cross striped directory"
20977
20978 test_300_check_default_striped_dir()
20979 {
20980         local dirname=$1
20981         local default_count=$2
20982         local default_index=$3
20983         local stripe_count
20984         local stripe_index
20985         local dir_stripe_index
20986         local dir
20987
20988         echo "checking $dirname $default_count $default_index"
20989         $LFS setdirstripe -D -c $default_count -i $default_index \
20990                                 -t all_char $DIR/$tdir/$dirname ||
20991                 error "set default stripe on striped dir error"
20992         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
20993         [ $stripe_count -eq $default_count ] ||
20994                 error "expect $default_count get $stripe_count for $dirname"
20995
20996         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
20997         [ $stripe_index -eq $default_index ] ||
20998                 error "expect $default_index get $stripe_index for $dirname"
20999
21000         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21001                                                 error "create dirs failed"
21002
21003         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21004         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21005         for dir in $(find $DIR/$tdir/$dirname/*); do
21006                 stripe_count=$($LFS getdirstripe -c $dir)
21007                 [ $stripe_count -eq $default_count ] ||
21008                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21009                 error "stripe count $default_count != $stripe_count for $dir"
21010
21011                 stripe_index=$($LFS getdirstripe -i $dir)
21012                 [ $default_index -eq -1 ] ||
21013                         [ $stripe_index -eq $default_index ] ||
21014                         error "$stripe_index != $default_index for $dir"
21015
21016                 #check default stripe
21017                 stripe_count=$($LFS getdirstripe -D -c $dir)
21018                 [ $stripe_count -eq $default_count ] ||
21019                 error "default count $default_count != $stripe_count for $dir"
21020
21021                 stripe_index=$($LFS getdirstripe -D -i $dir)
21022                 [ $stripe_index -eq $default_index ] ||
21023                 error "default index $default_index != $stripe_index for $dir"
21024         done
21025         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21026 }
21027
21028 test_300g() {
21029         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21030         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21031                 skip "Need MDS version at least 2.7.55"
21032
21033         local dir
21034         local stripe_count
21035         local stripe_index
21036
21037         mkdir $DIR/$tdir
21038         mkdir $DIR/$tdir/normal_dir
21039
21040         #Checking when client cache stripe index
21041         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21042         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21043                 error "create striped_dir failed"
21044
21045         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21046                 error "create dir0 fails"
21047         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21048         [ $stripe_index -eq 0 ] ||
21049                 error "dir0 expect index 0 got $stripe_index"
21050
21051         mkdir $DIR/$tdir/striped_dir/dir1 ||
21052                 error "create dir1 fails"
21053         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21054         [ $stripe_index -eq 1 ] ||
21055                 error "dir1 expect index 1 got $stripe_index"
21056
21057         #check default stripe count/stripe index
21058         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21059         test_300_check_default_striped_dir normal_dir 1 0
21060         test_300_check_default_striped_dir normal_dir 2 1
21061         test_300_check_default_striped_dir normal_dir 2 -1
21062
21063         #delete default stripe information
21064         echo "delete default stripeEA"
21065         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21066                 error "set default stripe on striped dir error"
21067
21068         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21069         for dir in $(find $DIR/$tdir/normal_dir/*); do
21070                 stripe_count=$($LFS getdirstripe -c $dir)
21071                 [ $stripe_count -eq 0 ] ||
21072                         error "expect 1 get $stripe_count for $dir"
21073                 stripe_index=$($LFS getdirstripe -i $dir)
21074                 [ $stripe_index -eq 0 ] ||
21075                         error "expect 0 get $stripe_index for $dir"
21076         done
21077 }
21078 run_test 300g "check default striped directory for normal directory"
21079
21080 test_300h() {
21081         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21082         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21083                 skip "Need MDS version at least 2.7.55"
21084
21085         local dir
21086         local stripe_count
21087
21088         mkdir $DIR/$tdir
21089         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21090                 error "set striped dir error"
21091
21092         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21093         test_300_check_default_striped_dir striped_dir 1 0
21094         test_300_check_default_striped_dir striped_dir 2 1
21095         test_300_check_default_striped_dir striped_dir 2 -1
21096
21097         #delete default stripe information
21098         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21099                 error "set default stripe on striped dir error"
21100
21101         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21102         for dir in $(find $DIR/$tdir/striped_dir/*); do
21103                 stripe_count=$($LFS getdirstripe -c $dir)
21104                 [ $stripe_count -eq 0 ] ||
21105                         error "expect 1 get $stripe_count for $dir"
21106         done
21107 }
21108 run_test 300h "check default striped directory for striped directory"
21109
21110 test_300i() {
21111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
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 stripe_count
21117         local file
21118
21119         mkdir $DIR/$tdir
21120
21121         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21122                 error "set striped dir error"
21123
21124         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21125                 error "create files under striped dir failed"
21126
21127         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21128                 error "set striped hashdir error"
21129
21130         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21131                 error "create dir0 under hash dir failed"
21132         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21133                 error "create dir1 under hash dir failed"
21134
21135         # unfortunately, we need to umount to clear dir layout cache for now
21136         # once we fully implement dir layout, we can drop this
21137         umount_client $MOUNT || error "umount failed"
21138         mount_client $MOUNT || error "mount failed"
21139
21140         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21141         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21142         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21143
21144         #set the stripe to be unknown hash type
21145         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21146         $LCTL set_param fail_loc=0x1901
21147         for ((i = 0; i < 10; i++)); do
21148                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21149                         error "stat f-$i failed"
21150                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21151         done
21152
21153         touch $DIR/$tdir/striped_dir/f0 &&
21154                 error "create under striped dir with unknown hash should fail"
21155
21156         $LCTL set_param fail_loc=0
21157
21158         umount_client $MOUNT || error "umount failed"
21159         mount_client $MOUNT || error "mount failed"
21160
21161         return 0
21162 }
21163 run_test 300i "client handle unknown hash type striped directory"
21164
21165 test_300j() {
21166         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21168         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21169                 skip "Need MDS version at least 2.7.55"
21170
21171         local stripe_count
21172         local file
21173
21174         mkdir $DIR/$tdir
21175
21176         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21177         $LCTL set_param fail_loc=0x1702
21178         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21179                 error "set striped dir error"
21180
21181         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21182                 error "create files under striped dir failed"
21183
21184         $LCTL set_param fail_loc=0
21185
21186         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21187
21188         return 0
21189 }
21190 run_test 300j "test large update record"
21191
21192 test_300k() {
21193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21194         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21195         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21196                 skip "Need MDS version at least 2.7.55"
21197
21198         # this test needs a huge transaction
21199         local kb
21200         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21201              osd*.$FSNAME-MDT0000.kbytestotal")
21202         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21203
21204         local stripe_count
21205         local file
21206
21207         mkdir $DIR/$tdir
21208
21209         #define OBD_FAIL_LARGE_STRIPE   0x1703
21210         $LCTL set_param fail_loc=0x1703
21211         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21212                 error "set striped dir error"
21213         $LCTL set_param fail_loc=0
21214
21215         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21216                 error "getstripeddir fails"
21217         rm -rf $DIR/$tdir/striped_dir ||
21218                 error "unlink striped dir fails"
21219
21220         return 0
21221 }
21222 run_test 300k "test large striped directory"
21223
21224 test_300l() {
21225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21226         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21227         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21228                 skip "Need MDS version at least 2.7.55"
21229
21230         local stripe_index
21231
21232         test_mkdir -p $DIR/$tdir/striped_dir
21233         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21234                         error "chown $RUNAS_ID failed"
21235         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21236                 error "set default striped dir failed"
21237
21238         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21239         $LCTL set_param fail_loc=0x80000158
21240         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21241
21242         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21243         [ $stripe_index -eq 1 ] ||
21244                 error "expect 1 get $stripe_index for $dir"
21245 }
21246 run_test 300l "non-root user to create dir under striped dir with stale layout"
21247
21248 test_300m() {
21249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21250         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21251         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21252                 skip "Need MDS version at least 2.7.55"
21253
21254         mkdir -p $DIR/$tdir/striped_dir
21255         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21256                 error "set default stripes dir error"
21257
21258         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21259
21260         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21261         [ $stripe_count -eq 0 ] ||
21262                         error "expect 0 get $stripe_count for a"
21263
21264         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21265                 error "set default stripes dir error"
21266
21267         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21268
21269         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21270         [ $stripe_count -eq 0 ] ||
21271                         error "expect 0 get $stripe_count for b"
21272
21273         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21274                 error "set default stripes dir error"
21275
21276         mkdir $DIR/$tdir/striped_dir/c &&
21277                 error "default stripe_index is invalid, mkdir c should fails"
21278
21279         rm -rf $DIR/$tdir || error "rmdir fails"
21280 }
21281 run_test 300m "setstriped directory on single MDT FS"
21282
21283 cleanup_300n() {
21284         local list=$(comma_list $(mdts_nodes))
21285
21286         trap 0
21287         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21288 }
21289
21290 test_300n() {
21291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21292         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21293         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21294                 skip "Need MDS version at least 2.7.55"
21295         remote_mds_nodsh && skip "remote MDS with nodsh"
21296
21297         local stripe_index
21298         local list=$(comma_list $(mdts_nodes))
21299
21300         trap cleanup_300n RETURN EXIT
21301         mkdir -p $DIR/$tdir
21302         chmod 777 $DIR/$tdir
21303         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21304                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21305                 error "create striped dir succeeds with gid=0"
21306
21307         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21308         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21309                 error "create striped dir fails with gid=-1"
21310
21311         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21312         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21313                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21314                 error "set default striped dir succeeds with gid=0"
21315
21316
21317         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21318         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21319                 error "set default striped dir fails with gid=-1"
21320
21321
21322         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21323         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21324                                         error "create test_dir fails"
21325         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21326                                         error "create test_dir1 fails"
21327         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21328                                         error "create test_dir2 fails"
21329         cleanup_300n
21330 }
21331 run_test 300n "non-root user to create dir under striped dir with default EA"
21332
21333 test_300o() {
21334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21335         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21336         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21337                 skip "Need MDS version at least 2.7.55"
21338
21339         local numfree1
21340         local numfree2
21341
21342         mkdir -p $DIR/$tdir
21343
21344         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21345         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21346         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21347                 skip "not enough free inodes $numfree1 $numfree2"
21348         fi
21349
21350         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21351         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21352         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21353                 skip "not enough free space $numfree1 $numfree2"
21354         fi
21355
21356         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21357                 error "setdirstripe fails"
21358
21359         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21360                 error "create dirs fails"
21361
21362         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21363         ls $DIR/$tdir/striped_dir > /dev/null ||
21364                 error "ls striped dir fails"
21365         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21366                 error "unlink big striped dir fails"
21367 }
21368 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21369
21370 test_300p() {
21371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21372         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21373         remote_mds_nodsh && skip "remote MDS with nodsh"
21374
21375         mkdir -p $DIR/$tdir
21376
21377         #define OBD_FAIL_OUT_ENOSPC     0x1704
21378         do_facet mds2 lctl set_param fail_loc=0x80001704
21379         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21380                  && error "create striped directory should fail"
21381
21382         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21383
21384         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21385         true
21386 }
21387 run_test 300p "create striped directory without space"
21388
21389 test_300q() {
21390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21391         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21392
21393         local fd=$(free_fd)
21394         local cmd="exec $fd<$tdir"
21395         cd $DIR
21396         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21397         eval $cmd
21398         cmd="exec $fd<&-"
21399         trap "eval $cmd" EXIT
21400         cd $tdir || error "cd $tdir fails"
21401         rmdir  ../$tdir || error "rmdir $tdir fails"
21402         mkdir local_dir && error "create dir succeeds"
21403         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21404         eval $cmd
21405         return 0
21406 }
21407 run_test 300q "create remote directory under orphan directory"
21408
21409 test_300r() {
21410         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21411                 skip "Need MDS version at least 2.7.55" && return
21412         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21413
21414         mkdir $DIR/$tdir
21415
21416         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21417                 error "set striped dir error"
21418
21419         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21420                 error "getstripeddir fails"
21421
21422         local stripe_count
21423         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21424                       awk '/lmv_stripe_count:/ { print $2 }')
21425
21426         [ $MDSCOUNT -ne $stripe_count ] &&
21427                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21428
21429         rm -rf $DIR/$tdir/striped_dir ||
21430                 error "unlink striped dir fails"
21431 }
21432 run_test 300r "test -1 striped directory"
21433
21434 prepare_remote_file() {
21435         mkdir $DIR/$tdir/src_dir ||
21436                 error "create remote source failed"
21437
21438         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21439                  error "cp to remote source failed"
21440         touch $DIR/$tdir/src_dir/a
21441
21442         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21443                 error "create remote target dir failed"
21444
21445         touch $DIR/$tdir/tgt_dir/b
21446
21447         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21448                 error "rename dir cross MDT failed!"
21449
21450         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21451                 error "src_child still exists after rename"
21452
21453         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21454                 error "missing file(a) after rename"
21455
21456         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21457                 error "diff after rename"
21458 }
21459
21460 test_310a() {
21461         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21463
21464         local remote_file=$DIR/$tdir/tgt_dir/b
21465
21466         mkdir -p $DIR/$tdir
21467
21468         prepare_remote_file || error "prepare remote file failed"
21469
21470         #open-unlink file
21471         $OPENUNLINK $remote_file $remote_file ||
21472                 error "openunlink $remote_file failed"
21473         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21474 }
21475 run_test 310a "open unlink remote file"
21476
21477 test_310b() {
21478         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21480
21481         local remote_file=$DIR/$tdir/tgt_dir/b
21482
21483         mkdir -p $DIR/$tdir
21484
21485         prepare_remote_file || error "prepare remote file failed"
21486
21487         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21488         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21489         $CHECKSTAT -t file $remote_file || error "check file failed"
21490 }
21491 run_test 310b "unlink remote file with multiple links while open"
21492
21493 test_310c() {
21494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21495         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21496
21497         local remote_file=$DIR/$tdir/tgt_dir/b
21498
21499         mkdir -p $DIR/$tdir
21500
21501         prepare_remote_file || error "prepare remote file failed"
21502
21503         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21504         multiop_bg_pause $remote_file O_uc ||
21505                         error "mulitop failed for remote file"
21506         MULTIPID=$!
21507         $MULTIOP $DIR/$tfile Ouc
21508         kill -USR1 $MULTIPID
21509         wait $MULTIPID
21510 }
21511 run_test 310c "open-unlink remote file with multiple links"
21512
21513 #LU-4825
21514 test_311() {
21515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21516         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21517         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21518                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21519         remote_mds_nodsh && skip "remote MDS with nodsh"
21520
21521         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21522         local mdts=$(comma_list $(mdts_nodes))
21523
21524         mkdir -p $DIR/$tdir
21525         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21526         createmany -o $DIR/$tdir/$tfile. 1000
21527
21528         # statfs data is not real time, let's just calculate it
21529         old_iused=$((old_iused + 1000))
21530
21531         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21532                         osp.*OST0000*MDT0000.create_count")
21533         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21534                                 osp.*OST0000*MDT0000.max_create_count")
21535         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21536
21537         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21538         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21539         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21540
21541         unlinkmany $DIR/$tdir/$tfile. 1000
21542
21543         do_nodes $mdts "$LCTL set_param -n \
21544                         osp.*OST0000*.max_create_count=$max_count"
21545         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21546                 do_nodes $mdts "$LCTL set_param -n \
21547                                 osp.*OST0000*.create_count=$count"
21548         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21549                         grep "=0" && error "create_count is zero"
21550
21551         local new_iused
21552         for i in $(seq 120); do
21553                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21554                 # system may be too busy to destroy all objs in time, use
21555                 # a somewhat small value to not fail autotest
21556                 [ $((old_iused - new_iused)) -gt 400 ] && break
21557                 sleep 1
21558         done
21559
21560         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21561         [ $((old_iused - new_iused)) -gt 400 ] ||
21562                 error "objs not destroyed after unlink"
21563 }
21564 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21565
21566 zfs_oid_to_objid()
21567 {
21568         local ost=$1
21569         local objid=$2
21570
21571         local vdevdir=$(dirname $(facet_vdevice $ost))
21572         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21573         local zfs_zapid=$(do_facet $ost $cmd |
21574                           grep -w "/O/0/d$((objid%32))" -C 5 |
21575                           awk '/Object/{getline; print $1}')
21576         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21577                           awk "/$objid = /"'{printf $3}')
21578
21579         echo $zfs_objid
21580 }
21581
21582 zfs_object_blksz() {
21583         local ost=$1
21584         local objid=$2
21585
21586         local vdevdir=$(dirname $(facet_vdevice $ost))
21587         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21588         local blksz=$(do_facet $ost $cmd $objid |
21589                       awk '/dblk/{getline; printf $4}')
21590
21591         case "${blksz: -1}" in
21592                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21593                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21594                 *) ;;
21595         esac
21596
21597         echo $blksz
21598 }
21599
21600 test_312() { # LU-4856
21601         remote_ost_nodsh && skip "remote OST with nodsh"
21602         [ "$ost1_FSTYPE" = "zfs" ] ||
21603                 skip_env "the test only applies to zfs"
21604
21605         local max_blksz=$(do_facet ost1 \
21606                           $ZFS get -p recordsize $(facet_device ost1) |
21607                           awk '!/VALUE/{print $3}')
21608
21609         # to make life a little bit easier
21610         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21611         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21612
21613         local tf=$DIR/$tdir/$tfile
21614         touch $tf
21615         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21616
21617         # Get ZFS object id
21618         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21619         # block size change by sequential overwrite
21620         local bs
21621
21622         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21623                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21624
21625                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21626                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21627         done
21628         rm -f $tf
21629
21630         # block size change by sequential append write
21631         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21632         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21633         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21634         local count
21635
21636         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21637                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21638                         oflag=sync conv=notrunc
21639
21640                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21641                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21642                         error "blksz error, actual $blksz, " \
21643                                 "expected: 2 * $count * $PAGE_SIZE"
21644         done
21645         rm -f $tf
21646
21647         # random write
21648         touch $tf
21649         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21650         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21651
21652         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21653         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21654         [ $blksz -eq $PAGE_SIZE ] ||
21655                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21656
21657         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21658         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21659         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21660
21661         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21662         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21663         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21664 }
21665 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21666
21667 test_313() {
21668         remote_ost_nodsh && skip "remote OST with nodsh"
21669
21670         local file=$DIR/$tfile
21671
21672         rm -f $file
21673         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21674
21675         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21676         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21677         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21678                 error "write should failed"
21679         do_facet ost1 "$LCTL set_param fail_loc=0"
21680         rm -f $file
21681 }
21682 run_test 313 "io should fail after last_rcvd update fail"
21683
21684 test_314() {
21685         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21686
21687         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21688         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21689         rm -f $DIR/$tfile
21690         wait_delete_completed
21691         do_facet ost1 "$LCTL set_param fail_loc=0"
21692 }
21693 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21694
21695 test_315() { # LU-618
21696         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21697
21698         local file=$DIR/$tfile
21699         rm -f $file
21700
21701         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21702                 error "multiop file write failed"
21703         $MULTIOP $file oO_RDONLY:r4063232_c &
21704         PID=$!
21705
21706         sleep 2
21707
21708         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21709         kill -USR1 $PID
21710
21711         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21712         rm -f $file
21713 }
21714 run_test 315 "read should be accounted"
21715
21716 test_316() {
21717         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21718         large_xattr_enabled || skip_env "ea_inode feature disabled"
21719
21720         rm -rf $DIR/$tdir/d
21721         mkdir -p $DIR/$tdir/d
21722         chown nobody $DIR/$tdir/d
21723         touch $DIR/$tdir/d/file
21724
21725         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21726 }
21727 run_test 316 "lfs mv"
21728
21729 test_317() {
21730         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21731                 skip "Need MDS version at least 2.11.53"
21732         if [ "$ost1_FSTYPE" == "zfs" ]; then
21733                 skip "LU-10370: no implementation for ZFS"
21734         fi
21735
21736         local trunc_sz
21737         local grant_blk_size
21738
21739         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21740                         awk '/grant_block_size:/ { print $2; exit; }')
21741         #
21742         # Create File of size 5M. Truncate it to below size's and verify
21743         # blocks count.
21744         #
21745         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21746                 error "Create file $DIR/$tfile failed"
21747         stack_trap "rm -f $DIR/$tfile" EXIT
21748
21749         for trunc_sz in 2097152 4097 4000 509 0; do
21750                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21751                         error "truncate $tfile to $trunc_sz failed"
21752                 local sz=$(stat --format=%s $DIR/$tfile)
21753                 local blk=$(stat --format=%b $DIR/$tfile)
21754                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21755                                      grant_blk_size) * 8))
21756
21757                 if [[ $blk -ne $trunc_blk ]]; then
21758                         $(which stat) $DIR/$tfile
21759                         error "Expected Block $trunc_blk got $blk for $tfile"
21760                 fi
21761
21762                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21763                         error "Expected Size $trunc_sz got $sz for $tfile"
21764         done
21765
21766         #
21767         # sparse file test
21768         # Create file with a hole and write actual two blocks. Block count
21769         # must be 16.
21770         #
21771         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21772                 conv=fsync || error "Create file : $DIR/$tfile"
21773
21774         # Calculate the final truncate size.
21775         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21776
21777         #
21778         # truncate to size $trunc_sz bytes. Strip the last block
21779         # The block count must drop to 8
21780         #
21781         $TRUNCATE $DIR/$tfile $trunc_sz ||
21782                 error "truncate $tfile to $trunc_sz failed"
21783
21784         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
21785         sz=$(stat --format=%s $DIR/$tfile)
21786         blk=$(stat --format=%b $DIR/$tfile)
21787
21788         if [[ $blk -ne $trunc_bsz ]]; then
21789                 $(which stat) $DIR/$tfile
21790                 error "Expected Block $trunc_bsz got $blk for $tfile"
21791         fi
21792
21793         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21794                 error "Expected Size $trunc_sz got $sz for $tfile"
21795 }
21796 run_test 317 "Verify blocks get correctly update after truncate"
21797
21798 test_318() {
21799         local old_max_active=$($LCTL get_param -n \
21800                             llite.*.max_read_ahead_async_active 2>/dev/null)
21801
21802         $LCTL set_param llite.*.max_read_ahead_async_active=256
21803         local max_active=$($LCTL get_param -n \
21804                            llite.*.max_read_ahead_async_active 2>/dev/null)
21805         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
21806
21807         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
21808                 error "set max_read_ahead_async_active should succeed"
21809
21810         $LCTL set_param llite.*.max_read_ahead_async_active=512
21811         max_active=$($LCTL get_param -n \
21812                      llite.*.max_read_ahead_async_active 2>/dev/null)
21813         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
21814
21815         # restore @max_active
21816         [ $old_max_active -ne 0 ] && $LCTL set_param \
21817                 llite.*.max_read_ahead_async_active=$old_max_active
21818
21819         local old_threshold=$($LCTL get_param -n \
21820                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21821         local max_per_file_mb=$($LCTL get_param -n \
21822                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
21823
21824         local invalid=$(($max_per_file_mb + 1))
21825         $LCTL set_param \
21826                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
21827                         && error "set $invalid should fail"
21828
21829         local valid=$(($invalid - 1))
21830         $LCTL set_param \
21831                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
21832                         error "set $valid should succeed"
21833         local threshold=$($LCTL get_param -n \
21834                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21835         [ $threshold -eq $valid ] || error \
21836                 "expect threshold $valid got $threshold"
21837         $LCTL set_param \
21838                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
21839 }
21840 run_test 318 "Verify async readahead tunables"
21841
21842 test_319() {
21843         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
21844
21845         local before=$(date +%s)
21846         local evict
21847         local mdir=$DIR/$tdir
21848         local file=$mdir/xxx
21849
21850         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
21851         touch $file
21852
21853 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
21854         $LCTL set_param fail_val=5 fail_loc=0x8000032c
21855         $LFS mv -m1 $file &
21856
21857         sleep 1
21858         dd if=$file of=/dev/null
21859         wait
21860         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
21861           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
21862
21863         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
21864 }
21865 run_test 319 "lost lease lock on migrate error"
21866
21867 test_398a() { # LU-4198
21868         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21869         $LCTL set_param ldlm.namespaces.*.lru_size=clear
21870
21871         # request a new lock on client
21872         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21873
21874         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21875         local lock_count=$($LCTL get_param -n \
21876                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21877         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
21878
21879         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
21880
21881         # no lock cached, should use lockless IO and not enqueue new lock
21882         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21883         lock_count=$($LCTL get_param -n \
21884                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21885         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
21886 }
21887 run_test 398a "direct IO should cancel lock otherwise lockless"
21888
21889 test_398b() { # LU-4198
21890         which fio || skip_env "no fio installed"
21891         $LFS setstripe -c -1 $DIR/$tfile
21892
21893         local size=12
21894         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
21895
21896         local njobs=4
21897         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
21898         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21899                 --numjobs=$njobs --fallocate=none \
21900                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21901                 --filename=$DIR/$tfile &
21902         bg_pid=$!
21903
21904         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
21905         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
21906                 --numjobs=$njobs --fallocate=none \
21907                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21908                 --filename=$DIR/$tfile || true
21909         wait $bg_pid
21910
21911         rm -rf $DIR/$tfile
21912 }
21913 run_test 398b "DIO and buffer IO race"
21914
21915 test_398c() { # LU-4198
21916         which fio || skip_env "no fio installed"
21917
21918         saved_debug=$($LCTL get_param -n debug)
21919         $LCTL set_param debug=0
21920
21921         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
21922         ((size /= 1024)) # by megabytes
21923         ((size /= 2)) # write half of the OST at most
21924         [ $size -gt 40 ] && size=40 #reduce test time anyway
21925
21926         $LFS setstripe -c 1 $DIR/$tfile
21927
21928         # it seems like ldiskfs reserves more space than necessary if the
21929         # writing blocks are not mapped, so it extends the file firstly
21930         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
21931         cancel_lru_locks osc
21932
21933         # clear and verify rpc_stats later
21934         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
21935
21936         local njobs=4
21937         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
21938         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
21939                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
21940                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21941                 --filename=$DIR/$tfile
21942         [ $? -eq 0 ] || error "fio write error"
21943
21944         [ $($LCTL get_param -n \
21945          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
21946                 error "Locks were requested while doing AIO"
21947
21948         # get the percentage of 1-page I/O
21949         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
21950                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
21951                 awk '{print $7}')
21952         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
21953
21954         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
21955         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21956                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
21957                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21958                 --filename=$DIR/$tfile
21959         [ $? -eq 0 ] || error "fio mixed read write error"
21960
21961         echo "AIO with large block size ${size}M"
21962         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
21963                 --numjobs=1 --fallocate=none --ioengine=libaio \
21964                 --iodepth=16 --allow_file_create=0 --size=${size}M \
21965                 --filename=$DIR/$tfile
21966         [ $? -eq 0 ] || error "fio large block size failed"
21967
21968         rm -rf $DIR/$tfile
21969         $LCTL set_param debug="$saved_debug"
21970 }
21971 run_test 398c "run fio to test AIO"
21972
21973 test_398d() { #  LU-13846
21974         test -f aiocp || skip_env "no aiocp installed"
21975         local aio_file=$DIR/aio_file
21976
21977         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
21978
21979         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
21980         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
21981
21982         diff $DIR/$tfile $aio_file || "file diff after aiocp"
21983         rm -rf $DIR/$tfile $aio_file
21984 }
21985 run_test 398d "run aiocp to verify block size > stripe size"
21986
21987 test_fake_rw() {
21988         local read_write=$1
21989         if [ "$read_write" = "write" ]; then
21990                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
21991         elif [ "$read_write" = "read" ]; then
21992                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
21993         else
21994                 error "argument error"
21995         fi
21996
21997         # turn off debug for performance testing
21998         local saved_debug=$($LCTL get_param -n debug)
21999         $LCTL set_param debug=0
22000
22001         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22002
22003         # get ost1 size - $FSNAME-OST0000
22004         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22005         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22006         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22007
22008         if [ "$read_write" = "read" ]; then
22009                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
22010         fi
22011
22012         local start_time=$(date +%s.%N)
22013         $dd_cmd bs=1M count=$blocks oflag=sync ||
22014                 error "real dd $read_write error"
22015         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22016
22017         if [ "$read_write" = "write" ]; then
22018                 rm -f $DIR/$tfile
22019         fi
22020
22021         # define OBD_FAIL_OST_FAKE_RW           0x238
22022         do_facet ost1 $LCTL set_param fail_loc=0x238
22023
22024         local start_time=$(date +%s.%N)
22025         $dd_cmd bs=1M count=$blocks oflag=sync ||
22026                 error "fake dd $read_write error"
22027         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22028
22029         if [ "$read_write" = "write" ]; then
22030                 # verify file size
22031                 cancel_lru_locks osc
22032                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22033                         error "$tfile size not $blocks MB"
22034         fi
22035         do_facet ost1 $LCTL set_param fail_loc=0
22036
22037         echo "fake $read_write $duration_fake vs. normal $read_write" \
22038                 "$duration in seconds"
22039         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22040                 error_not_in_vm "fake write is slower"
22041
22042         $LCTL set_param -n debug="$saved_debug"
22043         rm -f $DIR/$tfile
22044 }
22045 test_399a() { # LU-7655 for OST fake write
22046         remote_ost_nodsh && skip "remote OST with nodsh"
22047
22048         test_fake_rw write
22049 }
22050 run_test 399a "fake write should not be slower than normal write"
22051
22052 test_399b() { # LU-8726 for OST fake read
22053         remote_ost_nodsh && skip "remote OST with nodsh"
22054         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22055                 skip_env "ldiskfs only test"
22056         fi
22057
22058         test_fake_rw read
22059 }
22060 run_test 399b "fake read should not be slower than normal read"
22061
22062 test_400a() { # LU-1606, was conf-sanity test_74
22063         if ! which $CC > /dev/null 2>&1; then
22064                 skip_env "$CC is not installed"
22065         fi
22066
22067         local extra_flags=''
22068         local out=$TMP/$tfile
22069         local prefix=/usr/include/lustre
22070         local prog
22071
22072         # Oleg removes c files in his test rig so test if any c files exist
22073         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22074                 skip_env "Needed c test files are missing"
22075
22076         if ! [[ -d $prefix ]]; then
22077                 # Assume we're running in tree and fixup the include path.
22078                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22079                 extra_flags+=" -L$LUSTRE/utils/.lib"
22080         fi
22081
22082         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22083                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22084                         error "client api broken"
22085         done
22086         rm -f $out
22087 }
22088 run_test 400a "Lustre client api program can compile and link"
22089
22090 test_400b() { # LU-1606, LU-5011
22091         local header
22092         local out=$TMP/$tfile
22093         local prefix=/usr/include/linux/lustre
22094
22095         # We use a hard coded prefix so that this test will not fail
22096         # when run in tree. There are headers in lustre/include/lustre/
22097         # that are not packaged (like lustre_idl.h) and have more
22098         # complicated include dependencies (like config.h and lnet/types.h).
22099         # Since this test about correct packaging we just skip them when
22100         # they don't exist (see below) rather than try to fixup cppflags.
22101
22102         if ! which $CC > /dev/null 2>&1; then
22103                 skip_env "$CC is not installed"
22104         fi
22105
22106         for header in $prefix/*.h; do
22107                 if ! [[ -f "$header" ]]; then
22108                         continue
22109                 fi
22110
22111                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22112                         continue # lustre_ioctl.h is internal header
22113                 fi
22114
22115                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22116                         error "cannot compile '$header'"
22117         done
22118         rm -f $out
22119 }
22120 run_test 400b "packaged headers can be compiled"
22121
22122 test_401a() { #LU-7437
22123         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22124         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22125
22126         #count the number of parameters by "list_param -R"
22127         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22128         #count the number of parameters by listing proc files
22129         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22130         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22131         echo "proc_dirs='$proc_dirs'"
22132         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22133         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22134                       sort -u | wc -l)
22135
22136         [ $params -eq $procs ] ||
22137                 error "found $params parameters vs. $procs proc files"
22138
22139         # test the list_param -D option only returns directories
22140         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22141         #count the number of parameters by listing proc directories
22142         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22143                 sort -u | wc -l)
22144
22145         [ $params -eq $procs ] ||
22146                 error "found $params parameters vs. $procs proc files"
22147 }
22148 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22149
22150 test_401b() {
22151         local save=$($LCTL get_param -n jobid_var)
22152         local tmp=testing
22153
22154         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
22155                 error "no error returned when setting bad parameters"
22156
22157         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
22158         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22159
22160         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
22161         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
22162         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22163 }
22164 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22165
22166 test_401c() {
22167         local jobid_var_old=$($LCTL get_param -n jobid_var)
22168         local jobid_var_new
22169
22170         $LCTL set_param jobid_var= &&
22171                 error "no error returned for 'set_param a='"
22172
22173         jobid_var_new=$($LCTL get_param -n jobid_var)
22174         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22175                 error "jobid_var was changed by setting without value"
22176
22177         $LCTL set_param jobid_var &&
22178                 error "no error returned for 'set_param a'"
22179
22180         jobid_var_new=$($LCTL get_param -n jobid_var)
22181         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22182                 error "jobid_var was changed by setting without value"
22183 }
22184 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22185
22186 test_401d() {
22187         local jobid_var_old=$($LCTL get_param -n jobid_var)
22188         local jobid_var_new
22189         local new_value="foo=bar"
22190
22191         $LCTL set_param jobid_var=$new_value ||
22192                 error "'set_param a=b' did not accept a value containing '='"
22193
22194         jobid_var_new=$($LCTL get_param -n jobid_var)
22195         [[ "$jobid_var_new" == "$new_value" ]] ||
22196                 error "'set_param a=b' failed on a value containing '='"
22197
22198         # Reset the jobid_var to test the other format
22199         $LCTL set_param jobid_var=$jobid_var_old
22200         jobid_var_new=$($LCTL get_param -n jobid_var)
22201         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22202                 error "failed to reset jobid_var"
22203
22204         $LCTL set_param jobid_var $new_value ||
22205                 error "'set_param a b' did not accept a value containing '='"
22206
22207         jobid_var_new=$($LCTL get_param -n jobid_var)
22208         [[ "$jobid_var_new" == "$new_value" ]] ||
22209                 error "'set_param a b' failed on a value containing '='"
22210
22211         $LCTL set_param jobid_var $jobid_var_old
22212         jobid_var_new=$($LCTL get_param -n jobid_var)
22213         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22214                 error "failed to reset jobid_var"
22215 }
22216 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22217
22218 test_402() {
22219         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22220         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22221                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22222         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22223                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22224                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22225         remote_mds_nodsh && skip "remote MDS with nodsh"
22226
22227         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22228 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22229         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22230         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22231                 echo "Touch failed - OK"
22232 }
22233 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22234
22235 test_403() {
22236         local file1=$DIR/$tfile.1
22237         local file2=$DIR/$tfile.2
22238         local tfile=$TMP/$tfile
22239
22240         rm -f $file1 $file2 $tfile
22241
22242         touch $file1
22243         ln $file1 $file2
22244
22245         # 30 sec OBD_TIMEOUT in ll_getattr()
22246         # right before populating st_nlink
22247         $LCTL set_param fail_loc=0x80001409
22248         stat -c %h $file1 > $tfile &
22249
22250         # create an alias, drop all locks and reclaim the dentry
22251         < $file2
22252         cancel_lru_locks mdc
22253         cancel_lru_locks osc
22254         sysctl -w vm.drop_caches=2
22255
22256         wait
22257
22258         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22259
22260         rm -f $tfile $file1 $file2
22261 }
22262 run_test 403 "i_nlink should not drop to zero due to aliasing"
22263
22264 test_404() { # LU-6601
22265         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22266                 skip "Need server version newer than 2.8.52"
22267         remote_mds_nodsh && skip "remote MDS with nodsh"
22268
22269         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22270                 awk '/osp .*-osc-MDT/ { print $4}')
22271
22272         local osp
22273         for osp in $mosps; do
22274                 echo "Deactivate: " $osp
22275                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22276                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22277                         awk -vp=$osp '$4 == p { print $2 }')
22278                 [ $stat = IN ] || {
22279                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22280                         error "deactivate error"
22281                 }
22282                 echo "Activate: " $osp
22283                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22284                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22285                         awk -vp=$osp '$4 == p { print $2 }')
22286                 [ $stat = UP ] || {
22287                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22288                         error "activate error"
22289                 }
22290         done
22291 }
22292 run_test 404 "validate manual {de}activated works properly for OSPs"
22293
22294 test_405() {
22295         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22296         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22297                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22298                         skip "Layout swap lock is not supported"
22299
22300         check_swap_layouts_support
22301         check_swap_layout_no_dom $DIR
22302
22303         test_mkdir $DIR/$tdir
22304         swap_lock_test -d $DIR/$tdir ||
22305                 error "One layout swap locked test failed"
22306 }
22307 run_test 405 "Various layout swap lock tests"
22308
22309 test_406() {
22310         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22311         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22312         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22314         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22315                 skip "Need MDS version at least 2.8.50"
22316
22317         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22318         local test_pool=$TESTNAME
22319
22320         pool_add $test_pool || error "pool_add failed"
22321         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22322                 error "pool_add_targets failed"
22323
22324         save_layout_restore_at_exit $MOUNT
22325
22326         # parent set default stripe count only, child will stripe from both
22327         # parent and fs default
22328         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22329                 error "setstripe $MOUNT failed"
22330         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22331         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22332         for i in $(seq 10); do
22333                 local f=$DIR/$tdir/$tfile.$i
22334                 touch $f || error "touch failed"
22335                 local count=$($LFS getstripe -c $f)
22336                 [ $count -eq $OSTCOUNT ] ||
22337                         error "$f stripe count $count != $OSTCOUNT"
22338                 local offset=$($LFS getstripe -i $f)
22339                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22340                 local size=$($LFS getstripe -S $f)
22341                 [ $size -eq $((def_stripe_size * 2)) ] ||
22342                         error "$f stripe size $size != $((def_stripe_size * 2))"
22343                 local pool=$($LFS getstripe -p $f)
22344                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22345         done
22346
22347         # change fs default striping, delete parent default striping, now child
22348         # will stripe from new fs default striping only
22349         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22350                 error "change $MOUNT default stripe failed"
22351         $LFS setstripe -c 0 $DIR/$tdir ||
22352                 error "delete $tdir default stripe failed"
22353         for i in $(seq 11 20); do
22354                 local f=$DIR/$tdir/$tfile.$i
22355                 touch $f || error "touch $f failed"
22356                 local count=$($LFS getstripe -c $f)
22357                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22358                 local offset=$($LFS getstripe -i $f)
22359                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22360                 local size=$($LFS getstripe -S $f)
22361                 [ $size -eq $def_stripe_size ] ||
22362                         error "$f stripe size $size != $def_stripe_size"
22363                 local pool=$($LFS getstripe -p $f)
22364                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22365         done
22366
22367         unlinkmany $DIR/$tdir/$tfile. 1 20
22368
22369         local f=$DIR/$tdir/$tfile
22370         pool_remove_all_targets $test_pool $f
22371         pool_remove $test_pool $f
22372 }
22373 run_test 406 "DNE support fs default striping"
22374
22375 test_407() {
22376         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22377         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22378                 skip "Need MDS version at least 2.8.55"
22379         remote_mds_nodsh && skip "remote MDS with nodsh"
22380
22381         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22382                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22383         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22384                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22385         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22386
22387         #define OBD_FAIL_DT_TXN_STOP    0x2019
22388         for idx in $(seq $MDSCOUNT); do
22389                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22390         done
22391         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22392         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22393                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22394         true
22395 }
22396 run_test 407 "transaction fail should cause operation fail"
22397
22398 test_408() {
22399         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22400
22401         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22402         lctl set_param fail_loc=0x8000040a
22403         # let ll_prepare_partial_page() fail
22404         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22405
22406         rm -f $DIR/$tfile
22407
22408         # create at least 100 unused inodes so that
22409         # shrink_icache_memory(0) should not return 0
22410         touch $DIR/$tfile-{0..100}
22411         rm -f $DIR/$tfile-{0..100}
22412         sync
22413
22414         echo 2 > /proc/sys/vm/drop_caches
22415 }
22416 run_test 408 "drop_caches should not hang due to page leaks"
22417
22418 test_409()
22419 {
22420         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22421
22422         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22423         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22424         touch $DIR/$tdir/guard || error "(2) Fail to create"
22425
22426         local PREFIX=$(str_repeat 'A' 128)
22427         echo "Create 1K hard links start at $(date)"
22428         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22429                 error "(3) Fail to hard link"
22430
22431         echo "Links count should be right although linkEA overflow"
22432         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22433         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22434         [ $linkcount -eq 1001 ] ||
22435                 error "(5) Unexpected hard links count: $linkcount"
22436
22437         echo "List all links start at $(date)"
22438         ls -l $DIR/$tdir/foo > /dev/null ||
22439                 error "(6) Fail to list $DIR/$tdir/foo"
22440
22441         echo "Unlink hard links start at $(date)"
22442         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22443                 error "(7) Fail to unlink"
22444         echo "Unlink hard links finished at $(date)"
22445 }
22446 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22447
22448 test_410()
22449 {
22450         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22451                 skip "Need client version at least 2.9.59"
22452         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22453                 skip "Need MODULES build"
22454
22455         # Create a file, and stat it from the kernel
22456         local testfile=$DIR/$tfile
22457         touch $testfile
22458
22459         local run_id=$RANDOM
22460         local my_ino=$(stat --format "%i" $testfile)
22461
22462         # Try to insert the module. This will always fail as the
22463         # module is designed to not be inserted.
22464         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22465             &> /dev/null
22466
22467         # Anything but success is a test failure
22468         dmesg | grep -q \
22469             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22470             error "no inode match"
22471 }
22472 run_test 410 "Test inode number returned from kernel thread"
22473
22474 cleanup_test411_cgroup() {
22475         trap 0
22476         rmdir "$1"
22477 }
22478
22479 test_411() {
22480         local cg_basedir=/sys/fs/cgroup/memory
22481         # LU-9966
22482         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22483                 skip "no setup for cgroup"
22484
22485         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22486                 error "test file creation failed"
22487         cancel_lru_locks osc
22488
22489         # Create a very small memory cgroup to force a slab allocation error
22490         local cgdir=$cg_basedir/osc_slab_alloc
22491         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22492         trap "cleanup_test411_cgroup $cgdir" EXIT
22493         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22494         echo 1M > $cgdir/memory.limit_in_bytes
22495
22496         # Should not LBUG, just be killed by oom-killer
22497         # dd will return 0 even allocation failure in some environment.
22498         # So don't check return value
22499         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22500         cleanup_test411_cgroup $cgdir
22501
22502         return 0
22503 }
22504 run_test 411 "Slab allocation error with cgroup does not LBUG"
22505
22506 test_412() {
22507         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22508         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22509                 skip "Need server version at least 2.10.55"
22510         fi
22511
22512         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22513                 error "mkdir failed"
22514         $LFS getdirstripe $DIR/$tdir
22515         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22516         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22517                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22518         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22519         [ $stripe_count -eq 2 ] ||
22520                 error "expect 2 get $stripe_count"
22521 }
22522 run_test 412 "mkdir on specific MDTs"
22523
22524 test_qos_mkdir() {
22525         local mkdir_cmd=$1
22526         local stripe_count=$2
22527         local mdts=$(comma_list $(mdts_nodes))
22528
22529         local testdir
22530         local lmv_qos_prio_free
22531         local lmv_qos_threshold_rr
22532         local lmv_qos_maxage
22533         local lod_qos_prio_free
22534         local lod_qos_threshold_rr
22535         local lod_qos_maxage
22536         local count
22537         local i
22538
22539         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22540         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22541         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22542                 head -n1)
22543         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22544         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22545         stack_trap "$LCTL set_param \
22546                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22547         stack_trap "$LCTL set_param \
22548                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22549         stack_trap "$LCTL set_param \
22550                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22551
22552         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22553                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22554         lod_qos_prio_free=${lod_qos_prio_free%%%}
22555         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22556                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22557         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22558         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22559                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22560         stack_trap "do_nodes $mdts $LCTL set_param \
22561                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22562         stack_trap "do_nodes $mdts $LCTL set_param \
22563                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22564                 EXIT
22565         stack_trap "do_nodes $mdts $LCTL set_param \
22566                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22567
22568         echo
22569         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22570
22571         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22572         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22573
22574         testdir=$DIR/$tdir-s$stripe_count/rr
22575
22576         for i in $(seq $((100 * MDSCOUNT))); do
22577                 eval $mkdir_cmd $testdir/subdir$i ||
22578                         error "$mkdir_cmd subdir$i failed"
22579         done
22580
22581         for i in $(seq $MDSCOUNT); do
22582                 count=$($LFS getdirstripe -i $testdir/* |
22583                                 grep ^$((i - 1))$ | wc -l)
22584                 echo "$count directories created on MDT$((i - 1))"
22585                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22586
22587                 if [ $stripe_count -gt 1 ]; then
22588                         count=$($LFS getdirstripe $testdir/* |
22589                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22590                         echo "$count stripes created on MDT$((i - 1))"
22591                         # deviation should < 5% of average
22592                         [ $count -lt $((95 * stripe_count)) ] ||
22593                         [ $count -gt $((105 * stripe_count)) ] &&
22594                                 error "stripes are not evenly distributed"
22595                 fi
22596         done
22597
22598         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22599         do_nodes $mdts $LCTL set_param \
22600                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22601
22602         echo
22603         echo "Check for uneven MDTs: "
22604
22605         local ffree
22606         local bavail
22607         local max
22608         local min
22609         local max_index
22610         local min_index
22611         local tmp
22612
22613         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22614         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22615         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22616
22617         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22618         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22619         max_index=0
22620         min_index=0
22621         for ((i = 1; i < ${#ffree[@]}; i++)); do
22622                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22623                 if [ $tmp -gt $max ]; then
22624                         max=$tmp
22625                         max_index=$i
22626                 fi
22627                 if [ $tmp -lt $min ]; then
22628                         min=$tmp
22629                         min_index=$i
22630                 fi
22631         done
22632
22633         [ ${ffree[min_index]} -eq 0 ] &&
22634                 skip "no free files in MDT$min_index"
22635         [ ${ffree[min_index]} -gt 100000000 ] &&
22636                 skip "too much free files in MDT$min_index"
22637
22638         # Check if we need to generate uneven MDTs
22639         local threshold=50
22640         local diff=$(((max - min) * 100 / min))
22641         local value="$(generate_string 1024)"
22642
22643         while [ $diff -lt $threshold ]; do
22644                 # generate uneven MDTs, create till $threshold% diff
22645                 echo -n "weight diff=$diff% must be > $threshold% ..."
22646                 count=$((${ffree[min_index]} / 10))
22647                 # 50 sec per 10000 files in vm
22648                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22649                         skip "$count files to create"
22650                 echo "Fill MDT$min_index with $count files"
22651                 [ -d $DIR/$tdir-MDT$min_index ] ||
22652                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22653                         error "mkdir $tdir-MDT$min_index failed"
22654                 for i in $(seq $count); do
22655                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22656                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22657                                 error "create f$j_$i failed"
22658                         setfattr -n user.413b -v $value \
22659                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22660                                 error "setfattr f$j_$i failed"
22661                 done
22662
22663                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22664                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22665                 max=$(((${ffree[max_index]} >> 8) * \
22666                         (${bavail[max_index]} * bsize >> 16)))
22667                 min=$(((${ffree[min_index]} >> 8) * \
22668                         (${bavail[min_index]} * bsize >> 16)))
22669                 diff=$(((max - min) * 100 / min))
22670         done
22671
22672         echo "MDT filesfree available: ${ffree[@]}"
22673         echo "MDT blocks available: ${bavail[@]}"
22674         echo "weight diff=$diff%"
22675
22676         echo
22677         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22678
22679         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22680         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22681         # decrease statfs age, so that it can be updated in time
22682         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22683         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22684
22685         sleep 1
22686
22687         testdir=$DIR/$tdir-s$stripe_count/qos
22688
22689         for i in $(seq $((100 * MDSCOUNT))); do
22690                 eval $mkdir_cmd $testdir/subdir$i ||
22691                         error "$mkdir_cmd subdir$i failed"
22692         done
22693
22694         for i in $(seq $MDSCOUNT); do
22695                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22696                         wc -l)
22697                 echo "$count directories created on MDT$((i - 1))"
22698
22699                 if [ $stripe_count -gt 1 ]; then
22700                         count=$($LFS getdirstripe $testdir/* |
22701                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22702                         echo "$count stripes created on MDT$((i - 1))"
22703                 fi
22704         done
22705
22706         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
22707         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22708
22709         # D-value should > 10% of averge
22710         [ $((max - min)) -lt 10 ] &&
22711                 error "subdirs shouldn't be evenly distributed"
22712
22713         # ditto
22714         if [ $stripe_count -gt 1 ]; then
22715                 max=$($LFS getdirstripe $testdir/* |
22716                         grep -P "^\s+$max_index\t" | wc -l)
22717                 min=$($LFS getdirstripe $testdir/* |
22718                         grep -P "^\s+$min_index\t" | wc -l)
22719                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22720                         error "stripes shouldn't be evenly distributed"|| true
22721         fi
22722 }
22723
22724 test_413a() {
22725         [ $MDSCOUNT -lt 2 ] &&
22726                 skip "We need at least 2 MDTs for this test"
22727
22728         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22729                 skip "Need server version at least 2.12.52"
22730
22731         local stripe_count
22732
22733         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22734                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22735                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22736                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22737                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22738         done
22739 }
22740 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22741
22742 test_413b() {
22743         [ $MDSCOUNT -lt 2 ] &&
22744                 skip "We need at least 2 MDTs for this test"
22745
22746         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22747                 skip "Need server version at least 2.12.52"
22748
22749         local stripe_count
22750
22751         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22752                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22753                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22754                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22755                 $LFS setdirstripe -D -c $stripe_count \
22756                         $DIR/$tdir-s$stripe_count/rr ||
22757                         error "setdirstripe failed"
22758                 $LFS setdirstripe -D -c $stripe_count \
22759                         $DIR/$tdir-s$stripe_count/qos ||
22760                         error "setdirstripe failed"
22761                 test_qos_mkdir "mkdir" $stripe_count
22762         done
22763 }
22764 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
22765
22766 test_414() {
22767 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
22768         $LCTL set_param fail_loc=0x80000521
22769         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
22770         rm -f $DIR/$tfile
22771 }
22772 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
22773
22774 test_415() {
22775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22776         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22777                 skip "Need server version at least 2.11.52"
22778
22779         # LU-11102
22780         local total
22781         local setattr_pid
22782         local start_time
22783         local end_time
22784         local duration
22785
22786         total=500
22787         # this test may be slow on ZFS
22788         [ "$mds1_FSTYPE" == "zfs" ] && total=100
22789
22790         # though this test is designed for striped directory, let's test normal
22791         # directory too since lock is always saved as CoS lock.
22792         test_mkdir $DIR/$tdir || error "mkdir $tdir"
22793         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
22794
22795         (
22796                 while true; do
22797                         touch $DIR/$tdir
22798                 done
22799         ) &
22800         setattr_pid=$!
22801
22802         start_time=$(date +%s)
22803         for i in $(seq $total); do
22804                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
22805                         > /dev/null
22806         done
22807         end_time=$(date +%s)
22808         duration=$((end_time - start_time))
22809
22810         kill -9 $setattr_pid
22811
22812         echo "rename $total files took $duration sec"
22813         [ $duration -lt 100 ] || error "rename took $duration sec"
22814 }
22815 run_test 415 "lock revoke is not missing"
22816
22817 test_416() {
22818         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22819                 skip "Need server version at least 2.11.55"
22820
22821         # define OBD_FAIL_OSD_TXN_START    0x19a
22822         do_facet mds1 lctl set_param fail_loc=0x19a
22823
22824         lfs mkdir -c $MDSCOUNT $DIR/$tdir
22825
22826         true
22827 }
22828 run_test 416 "transaction start failure won't cause system hung"
22829
22830 cleanup_417() {
22831         trap 0
22832         do_nodes $(comma_list $(mdts_nodes)) \
22833                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
22834         do_nodes $(comma_list $(mdts_nodes)) \
22835                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
22836         do_nodes $(comma_list $(mdts_nodes)) \
22837                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
22838 }
22839
22840 test_417() {
22841         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22842         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
22843                 skip "Need MDS version at least 2.11.56"
22844
22845         trap cleanup_417 RETURN EXIT
22846
22847         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
22848         do_nodes $(comma_list $(mdts_nodes)) \
22849                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
22850         $LFS migrate -m 0 $DIR/$tdir.1 &&
22851                 error "migrate dir $tdir.1 should fail"
22852
22853         do_nodes $(comma_list $(mdts_nodes)) \
22854                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
22855         $LFS mkdir -i 1 $DIR/$tdir.2 &&
22856                 error "create remote dir $tdir.2 should fail"
22857
22858         do_nodes $(comma_list $(mdts_nodes)) \
22859                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
22860         $LFS mkdir -c 2 $DIR/$tdir.3 &&
22861                 error "create striped dir $tdir.3 should fail"
22862         true
22863 }
22864 run_test 417 "disable remote dir, striped dir and dir migration"
22865
22866 # Checks that the outputs of df [-i] and lfs df [-i] match
22867 #
22868 # usage: check_lfs_df <blocks | inodes> <mountpoint>
22869 check_lfs_df() {
22870         local dir=$2
22871         local inodes
22872         local df_out
22873         local lfs_df_out
22874         local count
22875         local passed=false
22876
22877         # blocks or inodes
22878         [ "$1" == "blocks" ] && inodes= || inodes="-i"
22879
22880         for count in {1..100}; do
22881                 cancel_lru_locks
22882                 sync; sleep 0.2
22883
22884                 # read the lines of interest
22885                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
22886                         error "df $inodes $dir | tail -n +2 failed"
22887                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
22888                         error "lfs df $inodes $dir | grep summary: failed"
22889
22890                 # skip first substrings of each output as they are different
22891                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
22892                 # compare the two outputs
22893                 passed=true
22894                 for i in {1..5}; do
22895                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
22896                 done
22897                 $passed && break
22898         done
22899
22900         if ! $passed; then
22901                 df -P $inodes $dir
22902                 echo
22903                 lfs df $inodes $dir
22904                 error "df and lfs df $1 output mismatch: "      \
22905                       "df ${inodes}: ${df_out[*]}, "            \
22906                       "lfs df ${inodes}: ${lfs_df_out[*]}"
22907         fi
22908 }
22909
22910 test_418() {
22911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22912
22913         local dir=$DIR/$tdir
22914         local numfiles=$((RANDOM % 4096 + 2))
22915         local numblocks=$((RANDOM % 256 + 1))
22916
22917         wait_delete_completed
22918         test_mkdir $dir
22919
22920         # check block output
22921         check_lfs_df blocks $dir
22922         # check inode output
22923         check_lfs_df inodes $dir
22924
22925         # create a single file and retest
22926         echo "Creating a single file and testing"
22927         createmany -o $dir/$tfile- 1 &>/dev/null ||
22928                 error "creating 1 file in $dir failed"
22929         check_lfs_df blocks $dir
22930         check_lfs_df inodes $dir
22931
22932         # create a random number of files
22933         echo "Creating $((numfiles - 1)) files and testing"
22934         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
22935                 error "creating $((numfiles - 1)) files in $dir failed"
22936
22937         # write a random number of blocks to the first test file
22938         echo "Writing $numblocks 4K blocks and testing"
22939         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
22940                 count=$numblocks &>/dev/null ||
22941                 error "dd to $dir/${tfile}-0 failed"
22942
22943         # retest
22944         check_lfs_df blocks $dir
22945         check_lfs_df inodes $dir
22946
22947         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
22948                 error "unlinking $numfiles files in $dir failed"
22949 }
22950 run_test 418 "df and lfs df outputs match"
22951
22952 test_419()
22953 {
22954         local dir=$DIR/$tdir
22955
22956         mkdir -p $dir
22957         touch $dir/file
22958
22959         cancel_lru_locks mdc
22960
22961         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
22962         $LCTL set_param fail_loc=0x1410
22963         cat $dir/file
22964         $LCTL set_param fail_loc=0
22965         rm -rf $dir
22966 }
22967 run_test 419 "Verify open file by name doesn't crash kernel"
22968
22969 test_420()
22970 {
22971         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
22972                 skip "Need MDS version at least 2.12.53"
22973
22974         local SAVE_UMASK=$(umask)
22975         local dir=$DIR/$tdir
22976         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
22977
22978         mkdir -p $dir
22979         umask 0000
22980         mkdir -m03777 $dir/testdir
22981         ls -dn $dir/testdir
22982         # Need to remove trailing '.' when SELinux is enabled
22983         local dirperms=$(ls -dn $dir/testdir |
22984                          awk '{ sub(/\.$/, "", $1); print $1}')
22985         [ $dirperms == "drwxrwsrwt" ] ||
22986                 error "incorrect perms on $dir/testdir"
22987
22988         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
22989                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
22990         ls -n $dir/testdir/testfile
22991         local fileperms=$(ls -n $dir/testdir/testfile |
22992                           awk '{ sub(/\.$/, "", $1); print $1}')
22993         [ $fileperms == "-rwxr-xr-x" ] ||
22994                 error "incorrect perms on $dir/testdir/testfile"
22995
22996         umask $SAVE_UMASK
22997 }
22998 run_test 420 "clear SGID bit on non-directories for non-members"
22999
23000 test_421a() {
23001         local cnt
23002         local fid1
23003         local fid2
23004
23005         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23006                 skip "Need MDS version at least 2.12.54"
23007
23008         test_mkdir $DIR/$tdir
23009         createmany -o $DIR/$tdir/f 3
23010         cnt=$(ls -1 $DIR/$tdir | wc -l)
23011         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23012
23013         fid1=$(lfs path2fid $DIR/$tdir/f1)
23014         fid2=$(lfs path2fid $DIR/$tdir/f2)
23015         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23016
23017         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23018         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23019
23020         cnt=$(ls -1 $DIR/$tdir | wc -l)
23021         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23022
23023         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23024         createmany -o $DIR/$tdir/f 3
23025         cnt=$(ls -1 $DIR/$tdir | wc -l)
23026         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23027
23028         fid1=$(lfs path2fid $DIR/$tdir/f1)
23029         fid2=$(lfs path2fid $DIR/$tdir/f2)
23030         echo "remove using fsname $FSNAME"
23031         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23032
23033         cnt=$(ls -1 $DIR/$tdir | wc -l)
23034         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23035 }
23036 run_test 421a "simple rm by fid"
23037
23038 test_421b() {
23039         local cnt
23040         local FID1
23041         local FID2
23042
23043         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23044                 skip "Need MDS version at least 2.12.54"
23045
23046         test_mkdir $DIR/$tdir
23047         createmany -o $DIR/$tdir/f 3
23048         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23049         MULTIPID=$!
23050
23051         FID1=$(lfs path2fid $DIR/$tdir/f1)
23052         FID2=$(lfs path2fid $DIR/$tdir/f2)
23053         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23054
23055         kill -USR1 $MULTIPID
23056         wait
23057
23058         cnt=$(ls $DIR/$tdir | wc -l)
23059         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23060 }
23061 run_test 421b "rm by fid on open file"
23062
23063 test_421c() {
23064         local cnt
23065         local FIDS
23066
23067         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23068                 skip "Need MDS version at least 2.12.54"
23069
23070         test_mkdir $DIR/$tdir
23071         createmany -o $DIR/$tdir/f 3
23072         touch $DIR/$tdir/$tfile
23073         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23074         cnt=$(ls -1 $DIR/$tdir | wc -l)
23075         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23076
23077         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23078         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23079
23080         cnt=$(ls $DIR/$tdir | wc -l)
23081         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23082 }
23083 run_test 421c "rm by fid against hardlinked files"
23084
23085 test_421d() {
23086         local cnt
23087         local FIDS
23088
23089         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23090                 skip "Need MDS version at least 2.12.54"
23091
23092         test_mkdir $DIR/$tdir
23093         createmany -o $DIR/$tdir/f 4097
23094         cnt=$(ls -1 $DIR/$tdir | wc -l)
23095         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23096
23097         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23098         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23099
23100         cnt=$(ls $DIR/$tdir | wc -l)
23101         rm -rf $DIR/$tdir
23102         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23103 }
23104 run_test 421d "rmfid en masse"
23105
23106 test_421e() {
23107         local cnt
23108         local FID
23109
23110         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23111         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23112                 skip "Need MDS version at least 2.12.54"
23113
23114         mkdir -p $DIR/$tdir
23115         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23116         createmany -o $DIR/$tdir/striped_dir/f 512
23117         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23118         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23119
23120         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23121                 sed "s/[/][^:]*://g")
23122         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23123
23124         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23125         rm -rf $DIR/$tdir
23126         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23127 }
23128 run_test 421e "rmfid in DNE"
23129
23130 test_421f() {
23131         local cnt
23132         local FID
23133
23134         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23135                 skip "Need MDS version at least 2.12.54"
23136
23137         test_mkdir $DIR/$tdir
23138         touch $DIR/$tdir/f
23139         cnt=$(ls -1 $DIR/$tdir | wc -l)
23140         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23141
23142         FID=$(lfs path2fid $DIR/$tdir/f)
23143         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23144         # rmfid should fail
23145         cnt=$(ls -1 $DIR/$tdir | wc -l)
23146         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23147
23148         chmod a+rw $DIR/$tdir
23149         ls -la $DIR/$tdir
23150         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23151         # rmfid should fail
23152         cnt=$(ls -1 $DIR/$tdir | wc -l)
23153         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23154
23155         rm -f $DIR/$tdir/f
23156         $RUNAS touch $DIR/$tdir/f
23157         FID=$(lfs path2fid $DIR/$tdir/f)
23158         echo "rmfid as root"
23159         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23160         cnt=$(ls -1 $DIR/$tdir | wc -l)
23161         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23162
23163         rm -f $DIR/$tdir/f
23164         $RUNAS touch $DIR/$tdir/f
23165         cnt=$(ls -1 $DIR/$tdir | wc -l)
23166         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23167         FID=$(lfs path2fid $DIR/$tdir/f)
23168         # rmfid w/o user_fid2path mount option should fail
23169         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23170         cnt=$(ls -1 $DIR/$tdir | wc -l)
23171         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23172
23173         umount_client $MOUNT || error "failed to umount client"
23174         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23175                 error "failed to mount client'"
23176
23177         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23178         # rmfid should succeed
23179         cnt=$(ls -1 $DIR/$tdir | wc -l)
23180         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23181
23182         # rmfid shouldn't allow to remove files due to dir's permission
23183         chmod a+rwx $DIR/$tdir
23184         touch $DIR/$tdir/f
23185         ls -la $DIR/$tdir
23186         FID=$(lfs path2fid $DIR/$tdir/f)
23187         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23188
23189         umount_client $MOUNT || error "failed to umount client"
23190         mount_client $MOUNT "$MOUNT_OPTS" ||
23191                 error "failed to mount client'"
23192
23193 }
23194 run_test 421f "rmfid checks permissions"
23195
23196 test_421g() {
23197         local cnt
23198         local FIDS
23199
23200         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23201         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23202                 skip "Need MDS version at least 2.12.54"
23203
23204         mkdir -p $DIR/$tdir
23205         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23206         createmany -o $DIR/$tdir/striped_dir/f 512
23207         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23208         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23209
23210         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23211                 sed "s/[/][^:]*://g")
23212
23213         rm -f $DIR/$tdir/striped_dir/f1*
23214         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23215         removed=$((512 - cnt))
23216
23217         # few files have been just removed, so we expect
23218         # rmfid to fail on their fids
23219         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23220         [ $removed != $errors ] && error "$errors != $removed"
23221
23222         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23223         rm -rf $DIR/$tdir
23224         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23225 }
23226 run_test 421g "rmfid to return errors properly"
23227
23228 test_422() {
23229         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23230         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23231         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23232         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23233         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23234
23235         local amc=$(at_max_get client)
23236         local amo=$(at_max_get mds1)
23237         local timeout=`lctl get_param -n timeout`
23238
23239         at_max_set 0 client
23240         at_max_set 0 mds1
23241
23242 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23243         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23244                         fail_val=$(((2*timeout + 10)*1000))
23245         touch $DIR/$tdir/d3/file &
23246         sleep 2
23247 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23248         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23249                         fail_val=$((2*timeout + 5))
23250         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23251         local pid=$!
23252         sleep 1
23253         kill -9 $pid
23254         sleep $((2 * timeout))
23255         echo kill $pid
23256         kill -9 $pid
23257         lctl mark touch
23258         touch $DIR/$tdir/d2/file3
23259         touch $DIR/$tdir/d2/file4
23260         touch $DIR/$tdir/d2/file5
23261
23262         wait
23263         at_max_set $amc client
23264         at_max_set $amo mds1
23265
23266         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23267         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23268                 error "Watchdog is always throttled"
23269 }
23270 run_test 422 "kill a process with RPC in progress"
23271
23272 stat_test() {
23273     df -h $MOUNT &
23274     df -h $MOUNT &
23275     df -h $MOUNT &
23276     df -h $MOUNT &
23277     df -h $MOUNT &
23278     df -h $MOUNT &
23279 }
23280
23281 test_423() {
23282     local _stats
23283     # ensure statfs cache is expired
23284     sleep 2;
23285
23286     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23287     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23288
23289     return 0
23290 }
23291 run_test 423 "statfs should return a right data"
23292
23293 test_424() {
23294 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23295         $LCTL set_param fail_loc=0x80000522
23296         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23297         rm -f $DIR/$tfile
23298 }
23299 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23300
23301 prep_801() {
23302         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23303         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23304                 skip "Need server version at least 2.9.55"
23305
23306         start_full_debug_logging
23307 }
23308
23309 post_801() {
23310         stop_full_debug_logging
23311 }
23312
23313 barrier_stat() {
23314         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23315                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23316                            awk '/The barrier for/ { print $7 }')
23317                 echo $st
23318         else
23319                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23320                 echo \'$st\'
23321         fi
23322 }
23323
23324 barrier_expired() {
23325         local expired
23326
23327         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23328                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23329                           awk '/will be expired/ { print $7 }')
23330         else
23331                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23332         fi
23333
23334         echo $expired
23335 }
23336
23337 test_801a() {
23338         prep_801
23339
23340         echo "Start barrier_freeze at: $(date)"
23341         #define OBD_FAIL_BARRIER_DELAY          0x2202
23342         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23343         # Do not reduce barrier time - See LU-11873
23344         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23345
23346         sleep 2
23347         local b_status=$(barrier_stat)
23348         echo "Got barrier status at: $(date)"
23349         [ "$b_status" = "'freezing_p1'" ] ||
23350                 error "(1) unexpected barrier status $b_status"
23351
23352         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23353         wait
23354         b_status=$(barrier_stat)
23355         [ "$b_status" = "'frozen'" ] ||
23356                 error "(2) unexpected barrier status $b_status"
23357
23358         local expired=$(barrier_expired)
23359         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23360         sleep $((expired + 3))
23361
23362         b_status=$(barrier_stat)
23363         [ "$b_status" = "'expired'" ] ||
23364                 error "(3) unexpected barrier status $b_status"
23365
23366         # Do not reduce barrier time - See LU-11873
23367         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23368                 error "(4) fail to freeze barrier"
23369
23370         b_status=$(barrier_stat)
23371         [ "$b_status" = "'frozen'" ] ||
23372                 error "(5) unexpected barrier status $b_status"
23373
23374         echo "Start barrier_thaw at: $(date)"
23375         #define OBD_FAIL_BARRIER_DELAY          0x2202
23376         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23377         do_facet mgs $LCTL barrier_thaw $FSNAME &
23378
23379         sleep 2
23380         b_status=$(barrier_stat)
23381         echo "Got barrier status at: $(date)"
23382         [ "$b_status" = "'thawing'" ] ||
23383                 error "(6) unexpected barrier status $b_status"
23384
23385         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23386         wait
23387         b_status=$(barrier_stat)
23388         [ "$b_status" = "'thawed'" ] ||
23389                 error "(7) unexpected barrier status $b_status"
23390
23391         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23392         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23393         do_facet mgs $LCTL barrier_freeze $FSNAME
23394
23395         b_status=$(barrier_stat)
23396         [ "$b_status" = "'failed'" ] ||
23397                 error "(8) unexpected barrier status $b_status"
23398
23399         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23400         do_facet mgs $LCTL barrier_thaw $FSNAME
23401
23402         post_801
23403 }
23404 run_test 801a "write barrier user interfaces and stat machine"
23405
23406 test_801b() {
23407         prep_801
23408
23409         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23410         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23411         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23412         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23413         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23414
23415         cancel_lru_locks mdc
23416
23417         # 180 seconds should be long enough
23418         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23419
23420         local b_status=$(barrier_stat)
23421         [ "$b_status" = "'frozen'" ] ||
23422                 error "(6) unexpected barrier status $b_status"
23423
23424         mkdir $DIR/$tdir/d0/d10 &
23425         mkdir_pid=$!
23426
23427         touch $DIR/$tdir/d1/f13 &
23428         touch_pid=$!
23429
23430         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23431         ln_pid=$!
23432
23433         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23434         mv_pid=$!
23435
23436         rm -f $DIR/$tdir/d4/f12 &
23437         rm_pid=$!
23438
23439         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
23440
23441         # To guarantee taht the 'stat' is not blocked
23442         b_status=$(barrier_stat)
23443         [ "$b_status" = "'frozen'" ] ||
23444                 error "(8) unexpected barrier status $b_status"
23445
23446         # let above commands to run at background
23447         sleep 5
23448
23449         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
23450         ps -p $touch_pid || error "(10) touch should be blocked"
23451         ps -p $ln_pid || error "(11) link should be blocked"
23452         ps -p $mv_pid || error "(12) rename should be blocked"
23453         ps -p $rm_pid || error "(13) unlink should be blocked"
23454
23455         b_status=$(barrier_stat)
23456         [ "$b_status" = "'frozen'" ] ||
23457                 error "(14) unexpected barrier status $b_status"
23458
23459         do_facet mgs $LCTL barrier_thaw $FSNAME
23460         b_status=$(barrier_stat)
23461         [ "$b_status" = "'thawed'" ] ||
23462                 error "(15) unexpected barrier status $b_status"
23463
23464         wait $mkdir_pid || error "(16) mkdir should succeed"
23465         wait $touch_pid || error "(17) touch should succeed"
23466         wait $ln_pid || error "(18) link should succeed"
23467         wait $mv_pid || error "(19) rename should succeed"
23468         wait $rm_pid || error "(20) unlink should succeed"
23469
23470         post_801
23471 }
23472 run_test 801b "modification will be blocked by write barrier"
23473
23474 test_801c() {
23475         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23476
23477         prep_801
23478
23479         stop mds2 || error "(1) Fail to stop mds2"
23480
23481         do_facet mgs $LCTL barrier_freeze $FSNAME 30
23482
23483         local b_status=$(barrier_stat)
23484         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
23485                 do_facet mgs $LCTL barrier_thaw $FSNAME
23486                 error "(2) unexpected barrier status $b_status"
23487         }
23488
23489         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23490                 error "(3) Fail to rescan barrier bitmap"
23491
23492         # Do not reduce barrier time - See LU-11873
23493         do_facet mgs $LCTL barrier_freeze $FSNAME 20
23494
23495         b_status=$(barrier_stat)
23496         [ "$b_status" = "'frozen'" ] ||
23497                 error "(4) unexpected barrier status $b_status"
23498
23499         do_facet mgs $LCTL barrier_thaw $FSNAME
23500         b_status=$(barrier_stat)
23501         [ "$b_status" = "'thawed'" ] ||
23502                 error "(5) unexpected barrier status $b_status"
23503
23504         local devname=$(mdsdevname 2)
23505
23506         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
23507
23508         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23509                 error "(7) Fail to rescan barrier bitmap"
23510
23511         post_801
23512 }
23513 run_test 801c "rescan barrier bitmap"
23514
23515 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
23516 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
23517 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
23518 saved_MOUNT_OPTS=$MOUNT_OPTS
23519
23520 cleanup_802a() {
23521         trap 0
23522
23523         stopall
23524         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
23525         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
23526         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
23527         MOUNT_OPTS=$saved_MOUNT_OPTS
23528         setupall
23529 }
23530
23531 test_802a() {
23532         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
23533         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23534         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23535                 skip "Need server version at least 2.9.55"
23536
23537         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
23538
23539         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23540
23541         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23542                 error "(2) Fail to copy"
23543
23544         trap cleanup_802a EXIT
23545
23546         # sync by force before remount as readonly
23547         sync; sync_all_data; sleep 3; sync_all_data
23548
23549         stopall
23550
23551         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
23552         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
23553         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
23554
23555         echo "Mount the server as read only"
23556         setupall server_only || error "(3) Fail to start servers"
23557
23558         echo "Mount client without ro should fail"
23559         mount_client $MOUNT &&
23560                 error "(4) Mount client without 'ro' should fail"
23561
23562         echo "Mount client with ro should succeed"
23563         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
23564         mount_client $MOUNT ||
23565                 error "(5) Mount client with 'ro' should succeed"
23566
23567         echo "Modify should be refused"
23568         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23569
23570         echo "Read should be allowed"
23571         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23572                 error "(7) Read should succeed under ro mode"
23573
23574         cleanup_802a
23575 }
23576 run_test 802a "simulate readonly device"
23577
23578 test_802b() {
23579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23580         remote_mds_nodsh && skip "remote MDS with nodsh"
23581
23582         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
23583                 skip "readonly option not available"
23584
23585         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
23586
23587         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23588                 error "(2) Fail to copy"
23589
23590         # write back all cached data before setting MDT to readonly
23591         cancel_lru_locks
23592         sync_all_data
23593
23594         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
23595         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
23596
23597         echo "Modify should be refused"
23598         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23599
23600         echo "Read should be allowed"
23601         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23602                 error "(7) Read should succeed under ro mode"
23603
23604         # disable readonly
23605         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
23606 }
23607 run_test 802b "be able to set MDTs to readonly"
23608
23609 test_803() {
23610         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23611         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23612                 skip "MDS needs to be newer than 2.10.54"
23613
23614         mkdir -p $DIR/$tdir
23615         # Create some objects on all MDTs to trigger related logs objects
23616         for idx in $(seq $MDSCOUNT); do
23617                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
23618                         $DIR/$tdir/dir${idx} ||
23619                         error "Fail to create $DIR/$tdir/dir${idx}"
23620         done
23621
23622         sync; sleep 3
23623         wait_delete_completed # ensure old test cleanups are finished
23624         echo "before create:"
23625         $LFS df -i $MOUNT
23626         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23627
23628         for i in {1..10}; do
23629                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
23630                         error "Fail to create $DIR/$tdir/foo$i"
23631         done
23632
23633         sync; sleep 3
23634         echo "after create:"
23635         $LFS df -i $MOUNT
23636         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23637
23638         # allow for an llog to be cleaned up during the test
23639         [ $after_used -ge $((before_used + 10 - 1)) ] ||
23640                 error "before ($before_used) + 10 > after ($after_used)"
23641
23642         for i in {1..10}; do
23643                 rm -rf $DIR/$tdir/foo$i ||
23644                         error "Fail to remove $DIR/$tdir/foo$i"
23645         done
23646
23647         sleep 3 # avoid MDT return cached statfs
23648         wait_delete_completed
23649         echo "after unlink:"
23650         $LFS df -i $MOUNT
23651         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23652
23653         # allow for an llog to be created during the test
23654         [ $after_used -le $((before_used + 1)) ] ||
23655                 error "after ($after_used) > before ($before_used) + 1"
23656 }
23657 run_test 803 "verify agent object for remote object"
23658
23659 test_804() {
23660         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23661         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23662                 skip "MDS needs to be newer than 2.10.54"
23663         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
23664
23665         mkdir -p $DIR/$tdir
23666         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
23667                 error "Fail to create $DIR/$tdir/dir0"
23668
23669         local fid=$($LFS path2fid $DIR/$tdir/dir0)
23670         local dev=$(mdsdevname 2)
23671
23672         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23673                 grep ${fid} || error "NOT found agent entry for dir0"
23674
23675         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
23676                 error "Fail to create $DIR/$tdir/dir1"
23677
23678         touch $DIR/$tdir/dir1/foo0 ||
23679                 error "Fail to create $DIR/$tdir/dir1/foo0"
23680         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
23681         local rc=0
23682
23683         for idx in $(seq $MDSCOUNT); do
23684                 dev=$(mdsdevname $idx)
23685                 do_facet mds${idx} \
23686                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23687                         grep ${fid} && rc=$idx
23688         done
23689
23690         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
23691                 error "Fail to rename foo0 to foo1"
23692         if [ $rc -eq 0 ]; then
23693                 for idx in $(seq $MDSCOUNT); do
23694                         dev=$(mdsdevname $idx)
23695                         do_facet mds${idx} \
23696                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23697                         grep ${fid} && rc=$idx
23698                 done
23699         fi
23700
23701         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
23702                 error "Fail to rename foo1 to foo2"
23703         if [ $rc -eq 0 ]; then
23704                 for idx in $(seq $MDSCOUNT); do
23705                         dev=$(mdsdevname $idx)
23706                         do_facet mds${idx} \
23707                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23708                         grep ${fid} && rc=$idx
23709                 done
23710         fi
23711
23712         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
23713
23714         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
23715                 error "Fail to link to $DIR/$tdir/dir1/foo2"
23716         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
23717                 error "Fail to rename foo2 to foo0"
23718         unlink $DIR/$tdir/dir1/foo0 ||
23719                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
23720         rm -rf $DIR/$tdir/dir0 ||
23721                 error "Fail to rm $DIR/$tdir/dir0"
23722
23723         for idx in $(seq $MDSCOUNT); do
23724                 dev=$(mdsdevname $idx)
23725                 rc=0
23726
23727                 stop mds${idx}
23728                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
23729                         rc=$?
23730                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
23731                         error "mount mds$idx failed"
23732                 df $MOUNT > /dev/null 2>&1
23733
23734                 # e2fsck should not return error
23735                 [ $rc -eq 0 ] ||
23736                         error "e2fsck detected error on MDT${idx}: rc=$rc"
23737         done
23738 }
23739 run_test 804 "verify agent entry for remote entry"
23740
23741 cleanup_805() {
23742         do_facet $SINGLEMDS zfs set quota=$old $fsset
23743         unlinkmany $DIR/$tdir/f- 1000000
23744         trap 0
23745 }
23746
23747 test_805() {
23748         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
23749         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
23750         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
23751                 skip "netfree not implemented before 0.7"
23752         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
23753                 skip "Need MDS version at least 2.10.57"
23754
23755         local fsset
23756         local freekb
23757         local usedkb
23758         local old
23759         local quota
23760         local pref="osd-zfs.$FSNAME-MDT0000."
23761
23762         # limit available space on MDS dataset to meet nospace issue
23763         # quickly. then ZFS 0.7.2 can use reserved space if asked
23764         # properly (using netfree flag in osd_declare_destroy()
23765         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
23766         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
23767                 gawk '{print $3}')
23768         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
23769         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
23770         let "usedkb=usedkb-freekb"
23771         let "freekb=freekb/2"
23772         if let "freekb > 5000"; then
23773                 let "freekb=5000"
23774         fi
23775         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
23776         trap cleanup_805 EXIT
23777         mkdir $DIR/$tdir
23778         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
23779                 error "Can't set PFL layout"
23780         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
23781         rm -rf $DIR/$tdir || error "not able to remove"
23782         do_facet $SINGLEMDS zfs set quota=$old $fsset
23783         trap 0
23784 }
23785 run_test 805 "ZFS can remove from full fs"
23786
23787 # Size-on-MDS test
23788 check_lsom_data()
23789 {
23790         local file=$1
23791         local size=$($LFS getsom -s $file)
23792         local expect=$(stat -c %s $file)
23793
23794         [[ $size == $expect ]] ||
23795                 error "$file expected size: $expect, got: $size"
23796
23797         local blocks=$($LFS getsom -b $file)
23798         expect=$(stat -c %b $file)
23799         [[ $blocks == $expect ]] ||
23800                 error "$file expected blocks: $expect, got: $blocks"
23801 }
23802
23803 check_lsom_size()
23804 {
23805         local size=$($LFS getsom -s $1)
23806         local expect=$2
23807
23808         [[ $size == $expect ]] ||
23809                 error "$file expected size: $expect, got: $size"
23810 }
23811
23812 test_806() {
23813         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23814                 skip "Need MDS version at least 2.11.52"
23815
23816         local bs=1048576
23817
23818         touch $DIR/$tfile || error "touch $tfile failed"
23819
23820         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23821         save_lustre_params client "llite.*.xattr_cache" > $save
23822         lctl set_param llite.*.xattr_cache=0
23823         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23824
23825         # single-threaded write
23826         echo "Test SOM for single-threaded write"
23827         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
23828                 error "write $tfile failed"
23829         check_lsom_size $DIR/$tfile $bs
23830
23831         local num=32
23832         local size=$(($num * $bs))
23833         local offset=0
23834         local i
23835
23836         echo "Test SOM for single client multi-threaded($num) write"
23837         $TRUNCATE $DIR/$tfile 0
23838         for ((i = 0; i < $num; i++)); do
23839                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23840                 local pids[$i]=$!
23841                 offset=$((offset + $bs))
23842         done
23843         for (( i=0; i < $num; i++ )); do
23844                 wait ${pids[$i]}
23845         done
23846         check_lsom_size $DIR/$tfile $size
23847
23848         $TRUNCATE $DIR/$tfile 0
23849         for ((i = 0; i < $num; i++)); do
23850                 offset=$((offset - $bs))
23851                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23852                 local pids[$i]=$!
23853         done
23854         for (( i=0; i < $num; i++ )); do
23855                 wait ${pids[$i]}
23856         done
23857         check_lsom_size $DIR/$tfile $size
23858
23859         # multi-client writes
23860         num=$(get_node_count ${CLIENTS//,/ })
23861         size=$(($num * $bs))
23862         offset=0
23863         i=0
23864
23865         echo "Test SOM for multi-client ($num) writes"
23866         $TRUNCATE $DIR/$tfile 0
23867         for client in ${CLIENTS//,/ }; do
23868                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23869                 local pids[$i]=$!
23870                 i=$((i + 1))
23871                 offset=$((offset + $bs))
23872         done
23873         for (( i=0; i < $num; i++ )); do
23874                 wait ${pids[$i]}
23875         done
23876         check_lsom_size $DIR/$tfile $offset
23877
23878         i=0
23879         $TRUNCATE $DIR/$tfile 0
23880         for client in ${CLIENTS//,/ }; do
23881                 offset=$((offset - $bs))
23882                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23883                 local pids[$i]=$!
23884                 i=$((i + 1))
23885         done
23886         for (( i=0; i < $num; i++ )); do
23887                 wait ${pids[$i]}
23888         done
23889         check_lsom_size $DIR/$tfile $size
23890
23891         # verify truncate
23892         echo "Test SOM for truncate"
23893         $TRUNCATE $DIR/$tfile 1048576
23894         check_lsom_size $DIR/$tfile 1048576
23895         $TRUNCATE $DIR/$tfile 1234
23896         check_lsom_size $DIR/$tfile 1234
23897
23898         # verify SOM blocks count
23899         echo "Verify SOM block count"
23900         $TRUNCATE $DIR/$tfile 0
23901         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
23902                 error "failed to write file $tfile"
23903         check_lsom_data $DIR/$tfile
23904 }
23905 run_test 806 "Verify Lazy Size on MDS"
23906
23907 test_807() {
23908         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23909         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23910                 skip "Need MDS version at least 2.11.52"
23911
23912         # Registration step
23913         changelog_register || error "changelog_register failed"
23914         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
23915         changelog_users $SINGLEMDS | grep -q $cl_user ||
23916                 error "User $cl_user not found in changelog_users"
23917
23918         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23919         save_lustre_params client "llite.*.xattr_cache" > $save
23920         lctl set_param llite.*.xattr_cache=0
23921         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23922
23923         rm -rf $DIR/$tdir || error "rm $tdir failed"
23924         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23925         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
23926         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
23927         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
23928                 error "truncate $tdir/trunc failed"
23929
23930         local bs=1048576
23931         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
23932                 error "write $tfile failed"
23933
23934         # multi-client wirtes
23935         local num=$(get_node_count ${CLIENTS//,/ })
23936         local offset=0
23937         local i=0
23938
23939         echo "Test SOM for multi-client ($num) writes"
23940         touch $DIR/$tfile || error "touch $tfile failed"
23941         $TRUNCATE $DIR/$tfile 0
23942         for client in ${CLIENTS//,/ }; do
23943                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23944                 local pids[$i]=$!
23945                 i=$((i + 1))
23946                 offset=$((offset + $bs))
23947         done
23948         for (( i=0; i < $num; i++ )); do
23949                 wait ${pids[$i]}
23950         done
23951
23952         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
23953         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
23954         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
23955         check_lsom_data $DIR/$tdir/trunc
23956         check_lsom_data $DIR/$tdir/single_dd
23957         check_lsom_data $DIR/$tfile
23958
23959         rm -rf $DIR/$tdir
23960         # Deregistration step
23961         changelog_deregister || error "changelog_deregister failed"
23962 }
23963 run_test 807 "verify LSOM syncing tool"
23964
23965 check_som_nologged()
23966 {
23967         local lines=$($LFS changelog $FSNAME-MDT0000 |
23968                 grep 'x=trusted.som' | wc -l)
23969         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
23970 }
23971
23972 test_808() {
23973         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23974                 skip "Need MDS version at least 2.11.55"
23975
23976         # Registration step
23977         changelog_register || error "changelog_register failed"
23978
23979         touch $DIR/$tfile || error "touch $tfile failed"
23980         check_som_nologged
23981
23982         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
23983                 error "write $tfile failed"
23984         check_som_nologged
23985
23986         $TRUNCATE $DIR/$tfile 1234
23987         check_som_nologged
23988
23989         $TRUNCATE $DIR/$tfile 1048576
23990         check_som_nologged
23991
23992         # Deregistration step
23993         changelog_deregister || error "changelog_deregister failed"
23994 }
23995 run_test 808 "Check trusted.som xattr not logged in Changelogs"
23996
23997 check_som_nodata()
23998 {
23999         $LFS getsom $1
24000         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24001 }
24002
24003 test_809() {
24004         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24005                 skip "Need MDS version at least 2.11.56"
24006
24007         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24008                 error "failed to create DoM-only file $DIR/$tfile"
24009         touch $DIR/$tfile || error "touch $tfile failed"
24010         check_som_nodata $DIR/$tfile
24011
24012         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24013                 error "write $tfile failed"
24014         check_som_nodata $DIR/$tfile
24015
24016         $TRUNCATE $DIR/$tfile 1234
24017         check_som_nodata $DIR/$tfile
24018
24019         $TRUNCATE $DIR/$tfile 4097
24020         check_som_nodata $DIR/$file
24021 }
24022 run_test 809 "Verify no SOM xattr store for DoM-only files"
24023
24024 test_810() {
24025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24026         $GSS && skip_env "could not run with gss"
24027         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24028                 skip "OST < 2.12.58 doesn't align checksum"
24029
24030         set_checksums 1
24031         stack_trap "set_checksums $ORIG_CSUM" EXIT
24032         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24033
24034         local csum
24035         local before
24036         local after
24037         for csum in $CKSUM_TYPES; do
24038                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24039                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24040                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24041                         eval set -- $i
24042                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24043                         before=$(md5sum $DIR/$tfile)
24044                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24045                         after=$(md5sum $DIR/$tfile)
24046                         [ "$before" == "$after" ] ||
24047                                 error "$csum: $before != $after bs=$1 seek=$2"
24048                 done
24049         done
24050 }
24051 run_test 810 "partial page writes on ZFS (LU-11663)"
24052
24053 test_812a() {
24054         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24055                 skip "OST < 2.12.51 doesn't support this fail_loc"
24056         [ "$SHARED_KEY" = true ] &&
24057                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24058
24059         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24060         # ensure ost1 is connected
24061         stat $DIR/$tfile >/dev/null || error "can't stat"
24062         wait_osc_import_state client ost1 FULL
24063         # no locks, no reqs to let the connection idle
24064         cancel_lru_locks osc
24065
24066         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24067 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24068         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24069         wait_osc_import_state client ost1 CONNECTING
24070         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24071
24072         stat $DIR/$tfile >/dev/null || error "can't stat file"
24073 }
24074 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24075
24076 test_812b() { # LU-12378
24077         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24078                 skip "OST < 2.12.51 doesn't support this fail_loc"
24079         [ "$SHARED_KEY" = true ] &&
24080                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24081
24082         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24083         # ensure ost1 is connected
24084         stat $DIR/$tfile >/dev/null || error "can't stat"
24085         wait_osc_import_state client ost1 FULL
24086         # no locks, no reqs to let the connection idle
24087         cancel_lru_locks osc
24088
24089         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24090 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24091         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24092         wait_osc_import_state client ost1 CONNECTING
24093         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24094
24095         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24096         wait_osc_import_state client ost1 IDLE
24097 }
24098 run_test 812b "do not drop no resend request for idle connect"
24099
24100 test_813() {
24101         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24102         [ -z "$file_heat_sav" ] && skip "no file heat support"
24103
24104         local readsample
24105         local writesample
24106         local readbyte
24107         local writebyte
24108         local readsample1
24109         local writesample1
24110         local readbyte1
24111         local writebyte1
24112
24113         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24114         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24115
24116         $LCTL set_param -n llite.*.file_heat=1
24117         echo "Turn on file heat"
24118         echo "Period second: $period_second, Decay percentage: $decay_pct"
24119
24120         echo "QQQQ" > $DIR/$tfile
24121         echo "QQQQ" > $DIR/$tfile
24122         echo "QQQQ" > $DIR/$tfile
24123         cat $DIR/$tfile > /dev/null
24124         cat $DIR/$tfile > /dev/null
24125         cat $DIR/$tfile > /dev/null
24126         cat $DIR/$tfile > /dev/null
24127
24128         local out=$($LFS heat_get $DIR/$tfile)
24129
24130         $LFS heat_get $DIR/$tfile
24131         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24132         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24133         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24134         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24135
24136         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24137         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24138         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24139         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24140
24141         sleep $((period_second + 3))
24142         echo "Sleep $((period_second + 3)) seconds..."
24143         # The recursion formula to calculate the heat of the file f is as
24144         # follow:
24145         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24146         # Where Hi is the heat value in the period between time points i*I and
24147         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24148         # to the weight of Ci.
24149         out=$($LFS heat_get $DIR/$tfile)
24150         $LFS heat_get $DIR/$tfile
24151         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24152         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24153         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24154         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24155
24156         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24157                 error "read sample ($readsample) is wrong"
24158         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24159                 error "write sample ($writesample) is wrong"
24160         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24161                 error "read bytes ($readbyte) is wrong"
24162         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24163                 error "write bytes ($writebyte) is wrong"
24164
24165         echo "QQQQ" > $DIR/$tfile
24166         echo "QQQQ" > $DIR/$tfile
24167         echo "QQQQ" > $DIR/$tfile
24168         cat $DIR/$tfile > /dev/null
24169         cat $DIR/$tfile > /dev/null
24170         cat $DIR/$tfile > /dev/null
24171         cat $DIR/$tfile > /dev/null
24172
24173         sleep $((period_second + 3))
24174         echo "Sleep $((period_second + 3)) seconds..."
24175
24176         out=$($LFS heat_get $DIR/$tfile)
24177         $LFS heat_get $DIR/$tfile
24178         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24179         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24180         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24181         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24182
24183         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24184                 4 * $decay_pct) / 100") -eq 1 ] ||
24185                 error "read sample ($readsample1) is wrong"
24186         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24187                 3 * $decay_pct) / 100") -eq 1 ] ||
24188                 error "write sample ($writesample1) is wrong"
24189         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24190                 20 * $decay_pct) / 100") -eq 1 ] ||
24191                 error "read bytes ($readbyte1) is wrong"
24192         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24193                 15 * $decay_pct) / 100") -eq 1 ] ||
24194                 error "write bytes ($writebyte1) is wrong"
24195
24196         echo "Turn off file heat for the file $DIR/$tfile"
24197         $LFS heat_set -o $DIR/$tfile
24198
24199         echo "QQQQ" > $DIR/$tfile
24200         echo "QQQQ" > $DIR/$tfile
24201         echo "QQQQ" > $DIR/$tfile
24202         cat $DIR/$tfile > /dev/null
24203         cat $DIR/$tfile > /dev/null
24204         cat $DIR/$tfile > /dev/null
24205         cat $DIR/$tfile > /dev/null
24206
24207         out=$($LFS heat_get $DIR/$tfile)
24208         $LFS heat_get $DIR/$tfile
24209         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24210         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24211         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24212         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24213
24214         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24215         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24216         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24217         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24218
24219         echo "Trun on file heat for the file $DIR/$tfile"
24220         $LFS heat_set -O $DIR/$tfile
24221
24222         echo "QQQQ" > $DIR/$tfile
24223         echo "QQQQ" > $DIR/$tfile
24224         echo "QQQQ" > $DIR/$tfile
24225         cat $DIR/$tfile > /dev/null
24226         cat $DIR/$tfile > /dev/null
24227         cat $DIR/$tfile > /dev/null
24228         cat $DIR/$tfile > /dev/null
24229
24230         out=$($LFS heat_get $DIR/$tfile)
24231         $LFS heat_get $DIR/$tfile
24232         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24233         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24234         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24235         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24236
24237         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24238         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24239         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24240         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24241
24242         $LFS heat_set -c $DIR/$tfile
24243         $LCTL set_param -n llite.*.file_heat=0
24244         echo "Turn off file heat support for the Lustre filesystem"
24245
24246         echo "QQQQ" > $DIR/$tfile
24247         echo "QQQQ" > $DIR/$tfile
24248         echo "QQQQ" > $DIR/$tfile
24249         cat $DIR/$tfile > /dev/null
24250         cat $DIR/$tfile > /dev/null
24251         cat $DIR/$tfile > /dev/null
24252         cat $DIR/$tfile > /dev/null
24253
24254         out=$($LFS heat_get $DIR/$tfile)
24255         $LFS heat_get $DIR/$tfile
24256         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24257         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24258         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24259         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24260
24261         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24262         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24263         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24264         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24265
24266         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24267         rm -f $DIR/$tfile
24268 }
24269 run_test 813 "File heat verfication"
24270
24271 test_814()
24272 {
24273         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24274         echo -n y >> $DIR/$tfile
24275         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24276         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24277 }
24278 run_test 814 "sparse cp works as expected (LU-12361)"
24279
24280 test_815()
24281 {
24282         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24283         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24284 }
24285 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24286
24287 test_816() {
24288         [ "$SHARED_KEY" = true ] &&
24289                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24290
24291         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24292         # ensure ost1 is connected
24293         stat $DIR/$tfile >/dev/null || error "can't stat"
24294         wait_osc_import_state client ost1 FULL
24295         # no locks, no reqs to let the connection idle
24296         cancel_lru_locks osc
24297         lru_resize_disable osc
24298         local before
24299         local now
24300         before=$($LCTL get_param -n \
24301                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24302
24303         wait_osc_import_state client ost1 IDLE
24304         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24305         now=$($LCTL get_param -n \
24306               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24307         [ $before == $now ] || error "lru_size changed $before != $now"
24308 }
24309 run_test 816 "do not reset lru_resize on idle reconnect"
24310
24311 cleanup_817() {
24312         umount $tmpdir
24313         exportfs -u localhost:$DIR/nfsexp
24314         rm -rf $DIR/nfsexp
24315 }
24316
24317 test_817() {
24318         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24319
24320         mkdir -p $DIR/nfsexp
24321         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24322                 error "failed to export nfs"
24323
24324         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24325         stack_trap cleanup_817 EXIT
24326
24327         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24328                 error "failed to mount nfs to $tmpdir"
24329
24330         cp /bin/true $tmpdir
24331         $DIR/nfsexp/true || error "failed to execute 'true' command"
24332 }
24333 run_test 817 "nfsd won't cache write lock for exec file"
24334
24335 test_818() {
24336         mkdir $DIR/$tdir
24337         $LFS setstripe -c1 -i0 $DIR/$tfile
24338         $LFS setstripe -c1 -i1 $DIR/$tfile
24339         stop $SINGLEMDS
24340         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24341         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24342         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24343                 error "start $SINGLEMDS failed"
24344         rm -rf $DIR/$tdir
24345 }
24346 run_test 818 "unlink with failed llog"
24347
24348 test_819a() {
24349         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24350         cancel_lru_locks osc
24351         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24352         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24353         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24354         rm -f $TDIR/$tfile
24355 }
24356 run_test 819a "too big niobuf in read"
24357
24358 test_819b() {
24359         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24360         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24361         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24362         cancel_lru_locks osc
24363         sleep 1
24364         rm -f $TDIR/$tfile
24365 }
24366 run_test 819b "too big niobuf in write"
24367
24368
24369 function test_820_start_ost() {
24370         sleep 5
24371
24372         for num in $(seq $OSTCOUNT); do
24373                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24374         done
24375 }
24376
24377 test_820() {
24378         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24379
24380         mkdir $DIR/$tdir
24381         umount_client $MOUNT || error "umount failed"
24382         for num in $(seq $OSTCOUNT); do
24383                 stop ost$num
24384         done
24385
24386         # mount client with no active OSTs
24387         # so that the client can't initialize max LOV EA size
24388         # from OSC notifications
24389         mount_client $MOUNT || error "mount failed"
24390         # delay OST starting to keep this 0 max EA size for a while
24391         test_820_start_ost &
24392
24393         # create a directory on MDS2
24394         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24395                 error "Failed to create directory"
24396         # open intent should update default EA size
24397         # see mdc_update_max_ea_from_body()
24398         # notice this is the very first RPC to MDS2
24399         cp /etc/services $DIR/$tdir/mds2 ||
24400                 error "Failed to copy files to mds$n"
24401 }
24402 run_test 820 "update max EA from open intent"
24403
24404 #
24405 # tests that do cleanup/setup should be run at the end
24406 #
24407
24408 test_900() {
24409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24410         local ls
24411
24412         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
24413         $LCTL set_param fail_loc=0x903
24414
24415         cancel_lru_locks MGC
24416
24417         FAIL_ON_ERROR=true cleanup
24418         FAIL_ON_ERROR=true setup
24419 }
24420 run_test 900 "umount should not race with any mgc requeue thread"
24421
24422 # LUS-6253/LU-11185
24423 test_901() {
24424         local oldc
24425         local newc
24426         local olds
24427         local news
24428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24429
24430         # some get_param have a bug to handle dot in param name
24431         cancel_lru_locks MGC
24432         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24433         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24434         umount_client $MOUNT || error "umount failed"
24435         mount_client $MOUNT || error "mount failed"
24436         cancel_lru_locks MGC
24437         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24438         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24439
24440         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
24441         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
24442
24443         return 0
24444 }
24445 run_test 901 "don't leak a mgc lock on client umount"
24446
24447 # LU-13377
24448 test_902() {
24449         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
24450                 skip "client does not have LU-13377 fix"
24451         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
24452         $LCTL set_param fail_loc=0x1415
24453         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24454         cancel_lru_locks osc
24455         rm -f $DIR/$tfile
24456 }
24457 run_test 902 "test short write doesn't hang lustre"
24458
24459 complete $SECONDS
24460 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
24461 check_and_cleanup_lustre
24462 if [ "$I_MOUNTED" != "yes" ]; then
24463         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
24464 fi
24465 exit_status