Whamcloud - gitweb
LU-13599 mdt: add test for rs_lock limit exceeding
[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         # Wait for multiop to exit
4884         wait $pid
4885 }
4886 run_test 43A "execution of file opened for write should return -ETXTBSY"
4887
4888 test_43a() {
4889         test_mkdir $DIR/$tdir
4890         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4891         $DIR/$tdir/sleep 60 &
4892         SLEEP_PID=$!
4893         # Make sure exec of $tdir/sleep wins race with truncate
4894         sleep 1
4895         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4896         kill $SLEEP_PID
4897 }
4898 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4899
4900 test_43b() {
4901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4902
4903         test_mkdir $DIR/$tdir
4904         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4905         $DIR/$tdir/sleep 60 &
4906         SLEEP_PID=$!
4907         # Make sure exec of $tdir/sleep wins race with truncate
4908         sleep 1
4909         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4910         kill $SLEEP_PID
4911 }
4912 run_test 43b "truncate of file being executed should return -ETXTBSY"
4913
4914 test_43c() {
4915         local testdir="$DIR/$tdir"
4916         test_mkdir $testdir
4917         cp $SHELL $testdir/
4918         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4919                 ( cd $testdir && md5sum -c )
4920 }
4921 run_test 43c "md5sum of copy into lustre"
4922
4923 test_44A() { # was test_44
4924         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4925
4926         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4927         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4928 }
4929 run_test 44A "zero length read from a sparse stripe"
4930
4931 test_44a() {
4932         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4933                 awk '{ print $2 }')
4934         [ -z "$nstripe" ] && skip "can't get stripe info"
4935         [[ $nstripe -gt $OSTCOUNT ]] &&
4936                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4937
4938         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4939                 awk '{ print $2 }')
4940         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4941                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4942                         awk '{ print $2 }')
4943         fi
4944
4945         OFFSETS="0 $((stride/2)) $((stride-1))"
4946         for offset in $OFFSETS; do
4947                 for i in $(seq 0 $((nstripe-1))); do
4948                         local GLOBALOFFSETS=""
4949                         # size in Bytes
4950                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4951                         local myfn=$DIR/d44a-$size
4952                         echo "--------writing $myfn at $size"
4953                         ll_sparseness_write $myfn $size ||
4954                                 error "ll_sparseness_write"
4955                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4956                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4957                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4958
4959                         for j in $(seq 0 $((nstripe-1))); do
4960                                 # size in Bytes
4961                                 size=$((((j + $nstripe )*$stride + $offset)))
4962                                 ll_sparseness_write $myfn $size ||
4963                                         error "ll_sparseness_write"
4964                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4965                         done
4966                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4967                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4968                         rm -f $myfn
4969                 done
4970         done
4971 }
4972 run_test 44a "test sparse pwrite ==============================="
4973
4974 dirty_osc_total() {
4975         tot=0
4976         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4977                 tot=$(($tot + $d))
4978         done
4979         echo $tot
4980 }
4981 do_dirty_record() {
4982         before=`dirty_osc_total`
4983         echo executing "\"$*\""
4984         eval $*
4985         after=`dirty_osc_total`
4986         echo before $before, after $after
4987 }
4988 test_45() {
4989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4990
4991         f="$DIR/f45"
4992         # Obtain grants from OST if it supports it
4993         echo blah > ${f}_grant
4994         stop_writeback
4995         sync
4996         do_dirty_record "echo blah > $f"
4997         [[ $before -eq $after ]] && error "write wasn't cached"
4998         do_dirty_record "> $f"
4999         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5000         do_dirty_record "echo blah > $f"
5001         [[ $before -eq $after ]] && error "write wasn't cached"
5002         do_dirty_record "sync"
5003         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5004         do_dirty_record "echo blah > $f"
5005         [[ $before -eq $after ]] && error "write wasn't cached"
5006         do_dirty_record "cancel_lru_locks osc"
5007         [[ $before -gt $after ]] ||
5008                 error "lock cancellation didn't lower dirty count"
5009         start_writeback
5010 }
5011 run_test 45 "osc io page accounting ============================"
5012
5013 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5014 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5015 # objects offset and an assert hit when an rpc was built with 1023's mapped
5016 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5017 test_46() {
5018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5019
5020         f="$DIR/f46"
5021         stop_writeback
5022         sync
5023         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5024         sync
5025         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5026         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5027         sync
5028         start_writeback
5029 }
5030 run_test 46 "dirtying a previously written page ================"
5031
5032 # test_47 is removed "Device nodes check" is moved to test_28
5033
5034 test_48a() { # bug 2399
5035         [ "$mds1_FSTYPE" = "zfs" ] &&
5036         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5037                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5038
5039         test_mkdir $DIR/$tdir
5040         cd $DIR/$tdir
5041         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5042         test_mkdir $DIR/$tdir
5043         touch foo || error "'touch foo' failed after recreating cwd"
5044         test_mkdir bar
5045         touch .foo || error "'touch .foo' failed after recreating cwd"
5046         test_mkdir .bar
5047         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5048         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5049         cd . || error "'cd .' failed after recreating cwd"
5050         mkdir . && error "'mkdir .' worked after recreating cwd"
5051         rmdir . && error "'rmdir .' worked after recreating cwd"
5052         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5053         cd .. || error "'cd ..' failed after recreating cwd"
5054 }
5055 run_test 48a "Access renamed working dir (should return errors)="
5056
5057 test_48b() { # bug 2399
5058         rm -rf $DIR/$tdir
5059         test_mkdir $DIR/$tdir
5060         cd $DIR/$tdir
5061         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5062         touch foo && error "'touch foo' worked after removing cwd"
5063         mkdir foo && error "'mkdir foo' worked after removing cwd"
5064         touch .foo && error "'touch .foo' worked after removing cwd"
5065         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5066         ls . > /dev/null && error "'ls .' worked after removing cwd"
5067         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5068         mkdir . && error "'mkdir .' worked after removing cwd"
5069         rmdir . && error "'rmdir .' worked after removing cwd"
5070         ln -s . foo && error "'ln -s .' worked after removing cwd"
5071         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5072 }
5073 run_test 48b "Access removed working dir (should return errors)="
5074
5075 test_48c() { # bug 2350
5076         #lctl set_param debug=-1
5077         #set -vx
5078         rm -rf $DIR/$tdir
5079         test_mkdir -p $DIR/$tdir/dir
5080         cd $DIR/$tdir/dir
5081         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5082         $TRACE touch foo && error "touch foo worked after removing cwd"
5083         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5084         touch .foo && error "touch .foo worked after removing cwd"
5085         mkdir .foo && error "mkdir .foo worked after removing cwd"
5086         $TRACE ls . && error "'ls .' worked after removing cwd"
5087         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5088         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5089         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5090         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5091         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5092 }
5093 run_test 48c "Access removed working subdir (should return errors)"
5094
5095 test_48d() { # bug 2350
5096         #lctl set_param debug=-1
5097         #set -vx
5098         rm -rf $DIR/$tdir
5099         test_mkdir -p $DIR/$tdir/dir
5100         cd $DIR/$tdir/dir
5101         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5102         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5103         $TRACE touch foo && error "'touch foo' worked after removing parent"
5104         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5105         touch .foo && error "'touch .foo' worked after removing parent"
5106         mkdir .foo && error "mkdir .foo worked after removing parent"
5107         $TRACE ls . && error "'ls .' worked after removing parent"
5108         $TRACE ls .. && error "'ls ..' worked after removing parent"
5109         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5110         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5111         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5112         true
5113 }
5114 run_test 48d "Access removed parent subdir (should return errors)"
5115
5116 test_48e() { # bug 4134
5117         #lctl set_param debug=-1
5118         #set -vx
5119         rm -rf $DIR/$tdir
5120         test_mkdir -p $DIR/$tdir/dir
5121         cd $DIR/$tdir/dir
5122         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5123         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5124         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5125         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5126         # On a buggy kernel addition of "touch foo" after cd .. will
5127         # produce kernel oops in lookup_hash_it
5128         touch ../foo && error "'cd ..' worked after recreate parent"
5129         cd $DIR
5130         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5131 }
5132 run_test 48e "Access to recreated parent subdir (should return errors)"
5133
5134 test_49() { # LU-1030
5135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5136         remote_ost_nodsh && skip "remote OST with nodsh"
5137
5138         # get ost1 size - $FSNAME-OST0000
5139         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5140                 awk '{ print $4 }')
5141         # write 800M at maximum
5142         [[ $ost1_size -lt 2 ]] && ost1_size=2
5143         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5144
5145         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5146         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5147         local dd_pid=$!
5148
5149         # change max_pages_per_rpc while writing the file
5150         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5151         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5152         # loop until dd process exits
5153         while ps ax -opid | grep -wq $dd_pid; do
5154                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5155                 sleep $((RANDOM % 5 + 1))
5156         done
5157         # restore original max_pages_per_rpc
5158         $LCTL set_param $osc1_mppc=$orig_mppc
5159         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5160 }
5161 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5162
5163 test_50() {
5164         # bug 1485
5165         test_mkdir $DIR/$tdir
5166         cd $DIR/$tdir
5167         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5168 }
5169 run_test 50 "special situations: /proc symlinks  ==============="
5170
5171 test_51a() {    # was test_51
5172         # bug 1516 - create an empty entry right after ".." then split dir
5173         test_mkdir -c1 $DIR/$tdir
5174         touch $DIR/$tdir/foo
5175         $MCREATE $DIR/$tdir/bar
5176         rm $DIR/$tdir/foo
5177         createmany -m $DIR/$tdir/longfile 201
5178         FNUM=202
5179         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5180                 $MCREATE $DIR/$tdir/longfile$FNUM
5181                 FNUM=$(($FNUM + 1))
5182                 echo -n "+"
5183         done
5184         echo
5185         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5186 }
5187 run_test 51a "special situations: split htree with empty entry =="
5188
5189 cleanup_print_lfs_df () {
5190         trap 0
5191         $LFS df
5192         $LFS df -i
5193 }
5194
5195 test_51b() {
5196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5197
5198         local dir=$DIR/$tdir
5199         local nrdirs=$((65536 + 100))
5200
5201         # cleanup the directory
5202         rm -fr $dir
5203
5204         test_mkdir -c1 $dir
5205
5206         $LFS df
5207         $LFS df -i
5208         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5209         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5210         [[ $numfree -lt $nrdirs ]] &&
5211                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5212
5213         # need to check free space for the directories as well
5214         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5215         numfree=$(( blkfree / $(fs_inode_ksize) ))
5216         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5217
5218         trap cleanup_print_lfs_df EXIT
5219
5220         # create files
5221         createmany -d $dir/d $nrdirs || {
5222                 unlinkmany $dir/d $nrdirs
5223                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5224         }
5225
5226         # really created :
5227         nrdirs=$(ls -U $dir | wc -l)
5228
5229         # unlink all but 100 subdirectories, then check it still works
5230         local left=100
5231         local delete=$((nrdirs - left))
5232
5233         $LFS df
5234         $LFS df -i
5235
5236         # for ldiskfs the nlink count should be 1, but this is OSD specific
5237         # and so this is listed for informational purposes only
5238         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5239         unlinkmany -d $dir/d $delete ||
5240                 error "unlink of first $delete subdirs failed"
5241
5242         echo "nlink between: $(stat -c %h $dir)"
5243         local found=$(ls -U $dir | wc -l)
5244         [ $found -ne $left ] &&
5245                 error "can't find subdirs: found only $found, expected $left"
5246
5247         unlinkmany -d $dir/d $delete $left ||
5248                 error "unlink of second $left subdirs failed"
5249         # regardless of whether the backing filesystem tracks nlink accurately
5250         # or not, the nlink count shouldn't be more than "." and ".." here
5251         local after=$(stat -c %h $dir)
5252         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5253                 echo "nlink after: $after"
5254
5255         cleanup_print_lfs_df
5256 }
5257 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5258
5259 test_51d() {
5260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5261         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5262
5263         test_mkdir $DIR/$tdir
5264         createmany -o $DIR/$tdir/t- 1000
5265         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5266         for N in $(seq 0 $((OSTCOUNT - 1))); do
5267                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5268                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5269                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5270                         '($1 == '$N') { objs += 1 } \
5271                         END { printf("%0.0f", objs) }')
5272                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5273         done
5274         unlinkmany $DIR/$tdir/t- 1000
5275
5276         NLAST=0
5277         for N in $(seq 1 $((OSTCOUNT - 1))); do
5278                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5279                         error "OST $N has less objects vs OST $NLAST" \
5280                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5281                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5282                         error "OST $N has less objects vs OST $NLAST" \
5283                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5284
5285                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5286                         error "OST $N has less #0 objects vs OST $NLAST" \
5287                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5288                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5289                         error "OST $N has less #0 objects vs OST $NLAST" \
5290                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5291                 NLAST=$N
5292         done
5293         rm -f $TMP/$tfile
5294 }
5295 run_test 51d "check object distribution"
5296
5297 test_51e() {
5298         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5299                 skip_env "ldiskfs only test"
5300         fi
5301
5302         test_mkdir -c1 $DIR/$tdir
5303         test_mkdir -c1 $DIR/$tdir/d0
5304
5305         touch $DIR/$tdir/d0/foo
5306         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5307                 error "file exceed 65000 nlink limit!"
5308         unlinkmany $DIR/$tdir/d0/f- 65001
5309         return 0
5310 }
5311 run_test 51e "check file nlink limit"
5312
5313 test_51f() {
5314         test_mkdir $DIR/$tdir
5315
5316         local max=100000
5317         local ulimit_old=$(ulimit -n)
5318         local spare=20 # number of spare fd's for scripts/libraries, etc.
5319         local mdt=$($LFS getstripe -m $DIR/$tdir)
5320         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5321
5322         echo "MDT$mdt numfree=$numfree, max=$max"
5323         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5324         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5325                 while ! ulimit -n $((numfree + spare)); do
5326                         numfree=$((numfree * 3 / 4))
5327                 done
5328                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5329         else
5330                 echo "left ulimit at $ulimit_old"
5331         fi
5332
5333         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5334                 unlinkmany $DIR/$tdir/f $numfree
5335                 error "create+open $numfree files in $DIR/$tdir failed"
5336         }
5337         ulimit -n $ulimit_old
5338
5339         # if createmany exits at 120s there will be fewer than $numfree files
5340         unlinkmany $DIR/$tdir/f $numfree || true
5341 }
5342 run_test 51f "check many open files limit"
5343
5344 test_52a() {
5345         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5346         test_mkdir $DIR/$tdir
5347         touch $DIR/$tdir/foo
5348         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5349         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5350         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5351         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5352         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5353                                         error "link worked"
5354         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5355         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5356         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5357                                                      error "lsattr"
5358         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5359         cp -r $DIR/$tdir $TMP/
5360         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5361 }
5362 run_test 52a "append-only flag test (should return errors)"
5363
5364 test_52b() {
5365         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5366         test_mkdir $DIR/$tdir
5367         touch $DIR/$tdir/foo
5368         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5369         cat test > $DIR/$tdir/foo && error "cat test worked"
5370         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5371         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5372         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5373                                         error "link worked"
5374         echo foo >> $DIR/$tdir/foo && error "echo worked"
5375         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5376         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5377         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5378         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5379                                                         error "lsattr"
5380         chattr -i $DIR/$tdir/foo || error "chattr failed"
5381
5382         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5383 }
5384 run_test 52b "immutable flag test (should return errors) ======="
5385
5386 test_53() {
5387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5388         remote_mds_nodsh && skip "remote MDS with nodsh"
5389         remote_ost_nodsh && skip "remote OST with nodsh"
5390
5391         local param
5392         local param_seq
5393         local ostname
5394         local mds_last
5395         local mds_last_seq
5396         local ost_last
5397         local ost_last_seq
5398         local ost_last_id
5399         local ostnum
5400         local node
5401         local found=false
5402         local support_last_seq=true
5403
5404         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5405                 support_last_seq=false
5406
5407         # only test MDT0000
5408         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5409         local value
5410         for value in $(do_facet $SINGLEMDS \
5411                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5412                 param=$(echo ${value[0]} | cut -d "=" -f1)
5413                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5414
5415                 if $support_last_seq; then
5416                         param_seq=$(echo $param |
5417                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5418                         mds_last_seq=$(do_facet $SINGLEMDS \
5419                                        $LCTL get_param -n $param_seq)
5420                 fi
5421                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5422
5423                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5424                 node=$(facet_active_host ost$((ostnum+1)))
5425                 param="obdfilter.$ostname.last_id"
5426                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5427                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5428                         ost_last_id=$ost_last
5429
5430                         if $support_last_seq; then
5431                                 ost_last_id=$(echo $ost_last |
5432                                               awk -F':' '{print $2}' |
5433                                               sed -e "s/^0x//g")
5434                                 ost_last_seq=$(echo $ost_last |
5435                                                awk -F':' '{print $1}')
5436                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5437                         fi
5438
5439                         if [[ $ost_last_id != $mds_last ]]; then
5440                                 error "$ost_last_id != $mds_last"
5441                         else
5442                                 found=true
5443                                 break
5444                         fi
5445                 done
5446         done
5447         $found || error "can not match last_seq/last_id for $mdtosc"
5448         return 0
5449 }
5450 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5451
5452 test_54a() {
5453         perl -MSocket -e ';' || skip "no Socket perl module installed"
5454
5455         $SOCKETSERVER $DIR/socket ||
5456                 error "$SOCKETSERVER $DIR/socket failed: $?"
5457         $SOCKETCLIENT $DIR/socket ||
5458                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5459         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5460 }
5461 run_test 54a "unix domain socket test =========================="
5462
5463 test_54b() {
5464         f="$DIR/f54b"
5465         mknod $f c 1 3
5466         chmod 0666 $f
5467         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5468 }
5469 run_test 54b "char device works in lustre ======================"
5470
5471 find_loop_dev() {
5472         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5473         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5474         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5475
5476         for i in $(seq 3 7); do
5477                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5478                 LOOPDEV=$LOOPBASE$i
5479                 LOOPNUM=$i
5480                 break
5481         done
5482 }
5483
5484 cleanup_54c() {
5485         local rc=0
5486         loopdev="$DIR/loop54c"
5487
5488         trap 0
5489         $UMOUNT $DIR/$tdir || rc=$?
5490         losetup -d $loopdev || true
5491         losetup -d $LOOPDEV || true
5492         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5493         return $rc
5494 }
5495
5496 test_54c() {
5497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5498
5499         loopdev="$DIR/loop54c"
5500
5501         find_loop_dev
5502         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5503         trap cleanup_54c EXIT
5504         mknod $loopdev b 7 $LOOPNUM
5505         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5506         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5507         losetup $loopdev $DIR/$tfile ||
5508                 error "can't set up $loopdev for $DIR/$tfile"
5509         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5510         test_mkdir $DIR/$tdir
5511         mount -t ext2 $loopdev $DIR/$tdir ||
5512                 error "error mounting $loopdev on $DIR/$tdir"
5513         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5514                 error "dd write"
5515         df $DIR/$tdir
5516         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5517                 error "dd read"
5518         cleanup_54c
5519 }
5520 run_test 54c "block device works in lustre ====================="
5521
5522 test_54d() {
5523         f="$DIR/f54d"
5524         string="aaaaaa"
5525         mknod $f p
5526         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5527 }
5528 run_test 54d "fifo device works in lustre ======================"
5529
5530 test_54e() {
5531         f="$DIR/f54e"
5532         string="aaaaaa"
5533         cp -aL /dev/console $f
5534         echo $string > $f || error "echo $string to $f failed"
5535 }
5536 run_test 54e "console/tty device works in lustre ======================"
5537
5538 test_56a() {
5539         local numfiles=3
5540         local dir=$DIR/$tdir
5541
5542         rm -rf $dir
5543         test_mkdir -p $dir/dir
5544         for i in $(seq $numfiles); do
5545                 touch $dir/file$i
5546                 touch $dir/dir/file$i
5547         done
5548
5549         local numcomp=$($LFS getstripe --component-count $dir)
5550
5551         [[ $numcomp == 0 ]] && numcomp=1
5552
5553         # test lfs getstripe with --recursive
5554         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5555
5556         [[ $filenum -eq $((numfiles * 2)) ]] ||
5557                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5558         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5559         [[ $filenum -eq $numfiles ]] ||
5560                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5561         echo "$LFS getstripe showed obdidx or l_ost_idx"
5562
5563         # test lfs getstripe with file instead of dir
5564         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5565         [[ $filenum -eq 1 ]] ||
5566                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5567         echo "$LFS getstripe file1 passed"
5568
5569         #test lfs getstripe with --verbose
5570         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5571         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5572                 error "$LFS getstripe --verbose $dir: "\
5573                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5574         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5575                 error "$LFS getstripe $dir: showed lmm_magic"
5576
5577         #test lfs getstripe with -v prints lmm_fid
5578         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5579         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5580                 error "$LFS getstripe -v $dir: "\
5581                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5582         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5583                 error "$LFS getstripe $dir: showed lmm_fid by default"
5584         echo "$LFS getstripe --verbose passed"
5585
5586         #check for FID information
5587         local fid1=$($LFS getstripe --fid $dir/file1)
5588         local fid2=$($LFS getstripe --verbose $dir/file1 |
5589                      awk '/lmm_fid: / { print $2; exit; }')
5590         local fid3=$($LFS path2fid $dir/file1)
5591
5592         [ "$fid1" != "$fid2" ] &&
5593                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5594         [ "$fid1" != "$fid3" ] &&
5595                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5596         echo "$LFS getstripe --fid passed"
5597
5598         #test lfs getstripe with --obd
5599         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5600                 error "$LFS getstripe --obd wrong_uuid: should return error"
5601
5602         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5603
5604         local ostidx=1
5605         local obduuid=$(ostuuid_from_index $ostidx)
5606         local found=$($LFS getstripe -r --obd $obduuid $dir |
5607                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5608
5609         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5610         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5611                 ((filenum--))
5612         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5613                 ((filenum--))
5614
5615         [[ $found -eq $filenum ]] ||
5616                 error "$LFS getstripe --obd: found $found expect $filenum"
5617         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5618                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5619                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5620                 error "$LFS getstripe --obd: should not show file on other obd"
5621         echo "$LFS getstripe --obd passed"
5622 }
5623 run_test 56a "check $LFS getstripe"
5624
5625 test_56b() {
5626         local dir=$DIR/$tdir
5627         local numdirs=3
5628
5629         test_mkdir $dir
5630         for i in $(seq $numdirs); do
5631                 test_mkdir $dir/dir$i
5632         done
5633
5634         # test lfs getdirstripe default mode is non-recursion, which is
5635         # different from lfs getstripe
5636         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5637
5638         [[ $dircnt -eq 1 ]] ||
5639                 error "$LFS getdirstripe: found $dircnt, not 1"
5640         dircnt=$($LFS getdirstripe --recursive $dir |
5641                 grep -c lmv_stripe_count)
5642         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5643                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5644 }
5645 run_test 56b "check $LFS getdirstripe"
5646
5647 test_56c() {
5648         remote_ost_nodsh && skip "remote OST with nodsh"
5649
5650         local ost_idx=0
5651         local ost_name=$(ostname_from_index $ost_idx)
5652         local old_status=$(ost_dev_status $ost_idx)
5653         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5654
5655         [[ -z "$old_status" ]] ||
5656                 skip_env "OST $ost_name is in $old_status status"
5657
5658         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5659         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5660                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5661         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5662                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5663                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5664         fi
5665
5666         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5667                 error "$LFS df -v showing inactive devices"
5668         sleep_maxage
5669
5670         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5671
5672         [[ "$new_status" =~ "D" ]] ||
5673                 error "$ost_name status is '$new_status', missing 'D'"
5674         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5675                 [[ "$new_status" =~ "N" ]] ||
5676                         error "$ost_name status is '$new_status', missing 'N'"
5677         fi
5678         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5679                 [[ "$new_status" =~ "f" ]] ||
5680                         error "$ost_name status is '$new_status', missing 'f'"
5681         fi
5682
5683         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5684         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5685                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5686         [[ -z "$p" ]] && restore_lustre_params < $p || true
5687         sleep_maxage
5688
5689         new_status=$(ost_dev_status $ost_idx)
5690         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5691                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5692         # can't check 'f' as devices may actually be on flash
5693 }
5694 run_test 56c "check 'lfs df' showing device status"
5695
5696 test_56d() {
5697         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5698         local osts=$($LFS df -v $MOUNT | grep -c OST)
5699
5700         $LFS df $MOUNT
5701
5702         (( mdts == MDSCOUNT )) ||
5703                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5704         (( osts == OSTCOUNT )) ||
5705                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5706 }
5707 run_test 56d "'lfs df -v' prints only configured devices"
5708
5709 NUMFILES=3
5710 NUMDIRS=3
5711 setup_56() {
5712         local local_tdir="$1"
5713         local local_numfiles="$2"
5714         local local_numdirs="$3"
5715         local dir_params="$4"
5716         local dir_stripe_params="$5"
5717
5718         if [ ! -d "$local_tdir" ] ; then
5719                 test_mkdir -p $dir_stripe_params $local_tdir
5720                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5721                 for i in $(seq $local_numfiles) ; do
5722                         touch $local_tdir/file$i
5723                 done
5724                 for i in $(seq $local_numdirs) ; do
5725                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5726                         for j in $(seq $local_numfiles) ; do
5727                                 touch $local_tdir/dir$i/file$j
5728                         done
5729                 done
5730         fi
5731 }
5732
5733 setup_56_special() {
5734         local local_tdir=$1
5735         local local_numfiles=$2
5736         local local_numdirs=$3
5737
5738         setup_56 $local_tdir $local_numfiles $local_numdirs
5739
5740         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5741                 for i in $(seq $local_numfiles) ; do
5742                         mknod $local_tdir/loop${i}b b 7 $i
5743                         mknod $local_tdir/null${i}c c 1 3
5744                         ln -s $local_tdir/file1 $local_tdir/link${i}
5745                 done
5746                 for i in $(seq $local_numdirs) ; do
5747                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5748                         mknod $local_tdir/dir$i/null${i}c c 1 3
5749                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5750                 done
5751         fi
5752 }
5753
5754 test_56g() {
5755         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5756         local expected=$(($NUMDIRS + 2))
5757
5758         setup_56 $dir $NUMFILES $NUMDIRS
5759
5760         # test lfs find with -name
5761         for i in $(seq $NUMFILES) ; do
5762                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5763
5764                 [ $nums -eq $expected ] ||
5765                         error "lfs find -name '*$i' $dir wrong: "\
5766                               "found $nums, expected $expected"
5767         done
5768 }
5769 run_test 56g "check lfs find -name"
5770
5771 test_56h() {
5772         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5773         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5774
5775         setup_56 $dir $NUMFILES $NUMDIRS
5776
5777         # test lfs find with ! -name
5778         for i in $(seq $NUMFILES) ; do
5779                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5780
5781                 [ $nums -eq $expected ] ||
5782                         error "lfs find ! -name '*$i' $dir wrong: "\
5783                               "found $nums, expected $expected"
5784         done
5785 }
5786 run_test 56h "check lfs find ! -name"
5787
5788 test_56i() {
5789         local dir=$DIR/$tdir
5790
5791         test_mkdir $dir
5792
5793         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5794         local out=$($cmd)
5795
5796         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5797 }
5798 run_test 56i "check 'lfs find -ost UUID' skips directories"
5799
5800 test_56j() {
5801         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5802
5803         setup_56_special $dir $NUMFILES $NUMDIRS
5804
5805         local expected=$((NUMDIRS + 1))
5806         local cmd="$LFS find -type d $dir"
5807         local nums=$($cmd | wc -l)
5808
5809         [ $nums -eq $expected ] ||
5810                 error "'$cmd' wrong: found $nums, expected $expected"
5811 }
5812 run_test 56j "check lfs find -type d"
5813
5814 test_56k() {
5815         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5816
5817         setup_56_special $dir $NUMFILES $NUMDIRS
5818
5819         local expected=$(((NUMDIRS + 1) * NUMFILES))
5820         local cmd="$LFS find -type f $dir"
5821         local nums=$($cmd | wc -l)
5822
5823         [ $nums -eq $expected ] ||
5824                 error "'$cmd' wrong: found $nums, expected $expected"
5825 }
5826 run_test 56k "check lfs find -type f"
5827
5828 test_56l() {
5829         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5830
5831         setup_56_special $dir $NUMFILES $NUMDIRS
5832
5833         local expected=$((NUMDIRS + NUMFILES))
5834         local cmd="$LFS find -type b $dir"
5835         local nums=$($cmd | wc -l)
5836
5837         [ $nums -eq $expected ] ||
5838                 error "'$cmd' wrong: found $nums, expected $expected"
5839 }
5840 run_test 56l "check lfs find -type b"
5841
5842 test_56m() {
5843         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5844
5845         setup_56_special $dir $NUMFILES $NUMDIRS
5846
5847         local expected=$((NUMDIRS + NUMFILES))
5848         local cmd="$LFS find -type c $dir"
5849         local nums=$($cmd | wc -l)
5850         [ $nums -eq $expected ] ||
5851                 error "'$cmd' wrong: found $nums, expected $expected"
5852 }
5853 run_test 56m "check lfs find -type c"
5854
5855 test_56n() {
5856         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5857         setup_56_special $dir $NUMFILES $NUMDIRS
5858
5859         local expected=$((NUMDIRS + NUMFILES))
5860         local cmd="$LFS find -type l $dir"
5861         local nums=$($cmd | wc -l)
5862
5863         [ $nums -eq $expected ] ||
5864                 error "'$cmd' wrong: found $nums, expected $expected"
5865 }
5866 run_test 56n "check lfs find -type l"
5867
5868 test_56o() {
5869         local dir=$DIR/$tdir
5870
5871         setup_56 $dir $NUMFILES $NUMDIRS
5872         utime $dir/file1 > /dev/null || error "utime (1)"
5873         utime $dir/file2 > /dev/null || error "utime (2)"
5874         utime $dir/dir1 > /dev/null || error "utime (3)"
5875         utime $dir/dir2 > /dev/null || error "utime (4)"
5876         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5877         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5878
5879         local expected=4
5880         local nums=$($LFS find -mtime +0 $dir | wc -l)
5881
5882         [ $nums -eq $expected ] ||
5883                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5884
5885         expected=12
5886         cmd="$LFS find -mtime 0 $dir"
5887         nums=$($cmd | wc -l)
5888         [ $nums -eq $expected ] ||
5889                 error "'$cmd' wrong: found $nums, expected $expected"
5890 }
5891 run_test 56o "check lfs find -mtime for old files"
5892
5893 test_56ob() {
5894         local dir=$DIR/$tdir
5895         local expected=1
5896         local count=0
5897
5898         # just to make sure there is something that won't be found
5899         test_mkdir $dir
5900         touch $dir/$tfile.now
5901
5902         for age in year week day hour min; do
5903                 count=$((count + 1))
5904
5905                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5906                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5907                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5908
5909                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5910                 local nums=$($cmd | wc -l)
5911                 [ $nums -eq $expected ] ||
5912                         error "'$cmd' wrong: found $nums, expected $expected"
5913
5914                 cmd="$LFS find $dir -atime $count${age:0:1}"
5915                 nums=$($cmd | wc -l)
5916                 [ $nums -eq $expected ] ||
5917                         error "'$cmd' wrong: found $nums, expected $expected"
5918         done
5919
5920         sleep 2
5921         cmd="$LFS find $dir -ctime +1s -type f"
5922         nums=$($cmd | wc -l)
5923         (( $nums == $count * 2 + 1)) ||
5924                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
5925 }
5926 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5927
5928 test_newerXY_base() {
5929         local x=$1
5930         local y=$2
5931         local dir=$DIR/$tdir
5932         local ref
5933         local negref
5934
5935         if [ $y == "t" ]; then
5936                 if [ $x == "b" ]; then
5937                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5938                 else
5939                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5940                 fi
5941         else
5942                 ref=$DIR/$tfile.newer.$x$y
5943                 touch $ref || error "touch $ref failed"
5944         fi
5945         sleep 2
5946         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5947         sleep 2
5948         if [ $y == "t" ]; then
5949                 if [ $x == "b" ]; then
5950                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5951                 else
5952                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5953                 fi
5954         else
5955                 negref=$DIR/$tfile.negnewer.$x$y
5956                 touch $negref || error "touch $negref failed"
5957         fi
5958
5959         local cmd="$LFS find $dir -newer$x$y $ref"
5960         local nums=$(eval $cmd | wc -l)
5961         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5962
5963         [ $nums -eq $expected ] ||
5964                 error "'$cmd' wrong: found $nums, expected $expected"
5965
5966         cmd="$LFS find $dir ! -newer$x$y $negref"
5967         nums=$(eval $cmd | wc -l)
5968         [ $nums -eq $expected ] ||
5969                 error "'$cmd' wrong: found $nums, expected $expected"
5970
5971         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
5972         nums=$(eval $cmd | wc -l)
5973         [ $nums -eq $expected ] ||
5974                 error "'$cmd' wrong: found $nums, expected $expected"
5975
5976         rm -rf $DIR/*
5977 }
5978
5979 test_56oc() {
5980         test_newerXY_base "b" "t"
5981         test_newerXY_base "a" "a"
5982         test_newerXY_base "a" "m"
5983         test_newerXY_base "a" "c"
5984         test_newerXY_base "m" "a"
5985         test_newerXY_base "m" "m"
5986         test_newerXY_base "m" "c"
5987         test_newerXY_base "c" "a"
5988         test_newerXY_base "c" "m"
5989         test_newerXY_base "c" "c"
5990         test_newerXY_base "b" "b"
5991         test_newerXY_base "a" "t"
5992         test_newerXY_base "m" "t"
5993         test_newerXY_base "c" "t"
5994         test_newerXY_base "b" "t"
5995 }
5996 run_test 56oc "check lfs find -newerXY work"
5997
5998 btime_supported() {
5999         local dir=$DIR/$tdir
6000         local rc
6001
6002         mkdir -p $dir
6003         touch $dir/$tfile
6004         $LFS find $dir -btime -1d -type f
6005         rc=$?
6006         rm -rf $dir
6007         return $rc
6008 }
6009
6010 test_56od() {
6011         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6012                 ! btime_supported && skip "btime unsupported on MDS"
6013
6014         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6015                 ! btime_supported && skip "btime unsupported on clients"
6016
6017         local dir=$DIR/$tdir
6018         local ref=$DIR/$tfile.ref
6019         local negref=$DIR/$tfile.negref
6020
6021         mkdir $dir || error "mkdir $dir failed"
6022         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6023         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6024         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6025         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6026         touch $ref || error "touch $ref failed"
6027         # sleep 3 seconds at least
6028         sleep 3
6029
6030         local before=$(do_facet mds1 date +%s)
6031         local skew=$(($(date +%s) - before + 1))
6032
6033         if (( skew < 0 && skew > -5 )); then
6034                 sleep $((0 - skew + 1))
6035                 skew=0
6036         fi
6037
6038         # Set the dir stripe params to limit files all on MDT0,
6039         # otherwise we need to calc the max clock skew between
6040         # the client and MDTs.
6041         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6042         sleep 2
6043         touch $negref || error "touch $negref failed"
6044
6045         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6046         local nums=$($cmd | wc -l)
6047         local expected=$(((NUMFILES + 1) * NUMDIRS))
6048
6049         [ $nums -eq $expected ] ||
6050                 error "'$cmd' wrong: found $nums, expected $expected"
6051
6052         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6053         nums=$($cmd | wc -l)
6054         expected=$((NUMFILES + 1))
6055         [ $nums -eq $expected ] ||
6056                 error "'$cmd' wrong: found $nums, expected $expected"
6057
6058         [ $skew -lt 0 ] && return
6059
6060         local after=$(do_facet mds1 date +%s)
6061         local age=$((after - before + 1 + skew))
6062
6063         cmd="$LFS find $dir -btime -${age}s -type f"
6064         nums=$($cmd | wc -l)
6065         expected=$(((NUMFILES + 1) * NUMDIRS))
6066
6067         echo "Clock skew between client and server: $skew, age:$age"
6068         [ $nums -eq $expected ] ||
6069                 error "'$cmd' wrong: found $nums, expected $expected"
6070
6071         expected=$(($NUMDIRS + 1))
6072         cmd="$LFS find $dir -btime -${age}s -type d"
6073         nums=$($cmd | wc -l)
6074         [ $nums -eq $expected ] ||
6075                 error "'$cmd' wrong: found $nums, expected $expected"
6076         rm -f $ref $negref || error "Failed to remove $ref $negref"
6077 }
6078 run_test 56od "check lfs find -btime with units"
6079
6080 test_56p() {
6081         [ $RUNAS_ID -eq $UID ] &&
6082                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6083
6084         local dir=$DIR/$tdir
6085
6086         setup_56 $dir $NUMFILES $NUMDIRS
6087         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6088
6089         local expected=$NUMFILES
6090         local cmd="$LFS find -uid $RUNAS_ID $dir"
6091         local nums=$($cmd | wc -l)
6092
6093         [ $nums -eq $expected ] ||
6094                 error "'$cmd' wrong: found $nums, expected $expected"
6095
6096         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6097         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6098         nums=$($cmd | wc -l)
6099         [ $nums -eq $expected ] ||
6100                 error "'$cmd' wrong: found $nums, expected $expected"
6101 }
6102 run_test 56p "check lfs find -uid and ! -uid"
6103
6104 test_56q() {
6105         [ $RUNAS_ID -eq $UID ] &&
6106                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6107
6108         local dir=$DIR/$tdir
6109
6110         setup_56 $dir $NUMFILES $NUMDIRS
6111         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6112
6113         local expected=$NUMFILES
6114         local cmd="$LFS find -gid $RUNAS_GID $dir"
6115         local nums=$($cmd | wc -l)
6116
6117         [ $nums -eq $expected ] ||
6118                 error "'$cmd' wrong: found $nums, expected $expected"
6119
6120         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6121         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6122         nums=$($cmd | wc -l)
6123         [ $nums -eq $expected ] ||
6124                 error "'$cmd' wrong: found $nums, expected $expected"
6125 }
6126 run_test 56q "check lfs find -gid and ! -gid"
6127
6128 test_56r() {
6129         local dir=$DIR/$tdir
6130
6131         setup_56 $dir $NUMFILES $NUMDIRS
6132
6133         local expected=12
6134         local cmd="$LFS find -size 0 -type f -lazy $dir"
6135         local nums=$($cmd | wc -l)
6136
6137         [ $nums -eq $expected ] ||
6138                 error "'$cmd' wrong: found $nums, expected $expected"
6139         cmd="$LFS find -size 0 -type f $dir"
6140         nums=$($cmd | wc -l)
6141         [ $nums -eq $expected ] ||
6142                 error "'$cmd' wrong: found $nums, expected $expected"
6143
6144         expected=0
6145         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6146         nums=$($cmd | wc -l)
6147         [ $nums -eq $expected ] ||
6148                 error "'$cmd' wrong: found $nums, expected $expected"
6149         cmd="$LFS find ! -size 0 -type f $dir"
6150         nums=$($cmd | wc -l)
6151         [ $nums -eq $expected ] ||
6152                 error "'$cmd' wrong: found $nums, expected $expected"
6153
6154         echo "test" > $dir/$tfile
6155         echo "test2" > $dir/$tfile.2 && sync
6156         expected=1
6157         cmd="$LFS find -size 5 -type f -lazy $dir"
6158         nums=$($cmd | wc -l)
6159         [ $nums -eq $expected ] ||
6160                 error "'$cmd' wrong: found $nums, expected $expected"
6161         cmd="$LFS find -size 5 -type f $dir"
6162         nums=$($cmd | wc -l)
6163         [ $nums -eq $expected ] ||
6164                 error "'$cmd' wrong: found $nums, expected $expected"
6165
6166         expected=1
6167         cmd="$LFS find -size +5 -type f -lazy $dir"
6168         nums=$($cmd | wc -l)
6169         [ $nums -eq $expected ] ||
6170                 error "'$cmd' wrong: found $nums, expected $expected"
6171         cmd="$LFS find -size +5 -type f $dir"
6172         nums=$($cmd | wc -l)
6173         [ $nums -eq $expected ] ||
6174                 error "'$cmd' wrong: found $nums, expected $expected"
6175
6176         expected=2
6177         cmd="$LFS find -size +0 -type f -lazy $dir"
6178         nums=$($cmd | wc -l)
6179         [ $nums -eq $expected ] ||
6180                 error "'$cmd' wrong: found $nums, expected $expected"
6181         cmd="$LFS find -size +0 -type f $dir"
6182         nums=$($cmd | wc -l)
6183         [ $nums -eq $expected ] ||
6184                 error "'$cmd' wrong: found $nums, expected $expected"
6185
6186         expected=2
6187         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6188         nums=$($cmd | wc -l)
6189         [ $nums -eq $expected ] ||
6190                 error "'$cmd' wrong: found $nums, expected $expected"
6191         cmd="$LFS find ! -size -5 -type f $dir"
6192         nums=$($cmd | wc -l)
6193         [ $nums -eq $expected ] ||
6194                 error "'$cmd' wrong: found $nums, expected $expected"
6195
6196         expected=12
6197         cmd="$LFS find -size -5 -type f -lazy $dir"
6198         nums=$($cmd | wc -l)
6199         [ $nums -eq $expected ] ||
6200                 error "'$cmd' wrong: found $nums, expected $expected"
6201         cmd="$LFS find -size -5 -type f $dir"
6202         nums=$($cmd | wc -l)
6203         [ $nums -eq $expected ] ||
6204                 error "'$cmd' wrong: found $nums, expected $expected"
6205 }
6206 run_test 56r "check lfs find -size works"
6207
6208 test_56ra_sub() {
6209         local expected=$1
6210         local glimpses=$2
6211         local cmd="$3"
6212
6213         cancel_lru_locks $OSC
6214
6215         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6216         local nums=$($cmd | wc -l)
6217
6218         [ $nums -eq $expected ] ||
6219                 error "'$cmd' wrong: found $nums, expected $expected"
6220
6221         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6222
6223         if (( rpcs_before + glimpses != rpcs_after )); then
6224                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6225                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6226
6227                 if [[ $glimpses == 0 ]]; then
6228                         error "'$cmd' should not send glimpse RPCs to OST"
6229                 else
6230                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6231                 fi
6232         fi
6233 }
6234
6235 test_56ra() {
6236         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6237                 skip "MDS < 2.12.58 doesn't return LSOM data"
6238         local dir=$DIR/$tdir
6239
6240         [[ $OSC == "mdc" ]] && skip "DoM files" && return
6241
6242         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6243         # open and close all files to ensure LSOM is updated
6244         cancel_lru_locks $OSC
6245         find $dir -type f | xargs cat > /dev/null
6246
6247         #   expect_found  glimpse_rpcs  command_to_run
6248         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6249         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6250         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6251         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6252
6253         echo "test" > $dir/$tfile
6254         echo "test2" > $dir/$tfile.2 && sync
6255         cancel_lru_locks $OSC
6256         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6257
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         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6261         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6262
6263         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6264         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6265         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6266         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6267         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6268         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6269 }
6270 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6271
6272 test_56rb() {
6273         local dir=$DIR/$tdir
6274         local tmp=$TMP/$tfile.log
6275         local mdt_idx;
6276
6277         test_mkdir -p $dir || error "failed to mkdir $dir"
6278         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6279                 error "failed to setstripe $dir/$tfile"
6280         mdt_idx=$($LFS getdirstripe -i $dir)
6281         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6282
6283         stack_trap "rm -f $tmp" EXIT
6284         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6285         ! grep -q obd_uuid $tmp ||
6286                 error "failed to find --size +100K --ost 0 $dir"
6287         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6288         ! grep -q obd_uuid $tmp ||
6289                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6290 }
6291 run_test 56rb "check lfs find --size --ost/--mdt works"
6292
6293 test_56s() { # LU-611 #LU-9369
6294         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6295
6296         local dir=$DIR/$tdir
6297         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6298
6299         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6300         for i in $(seq $NUMDIRS); do
6301                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6302         done
6303
6304         local expected=$NUMDIRS
6305         local cmd="$LFS find -c $OSTCOUNT $dir"
6306         local nums=$($cmd | wc -l)
6307
6308         [ $nums -eq $expected ] || {
6309                 $LFS getstripe -R $dir
6310                 error "'$cmd' wrong: found $nums, expected $expected"
6311         }
6312
6313         expected=$((NUMDIRS + onestripe))
6314         cmd="$LFS find -stripe-count +0 -type f $dir"
6315         nums=$($cmd | wc -l)
6316         [ $nums -eq $expected ] || {
6317                 $LFS getstripe -R $dir
6318                 error "'$cmd' wrong: found $nums, expected $expected"
6319         }
6320
6321         expected=$onestripe
6322         cmd="$LFS find -stripe-count 1 -type f $dir"
6323         nums=$($cmd | wc -l)
6324         [ $nums -eq $expected ] || {
6325                 $LFS getstripe -R $dir
6326                 error "'$cmd' wrong: found $nums, expected $expected"
6327         }
6328
6329         cmd="$LFS find -stripe-count -2 -type f $dir"
6330         nums=$($cmd | wc -l)
6331         [ $nums -eq $expected ] || {
6332                 $LFS getstripe -R $dir
6333                 error "'$cmd' wrong: found $nums, expected $expected"
6334         }
6335
6336         expected=0
6337         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6338         nums=$($cmd | wc -l)
6339         [ $nums -eq $expected ] || {
6340                 $LFS getstripe -R $dir
6341                 error "'$cmd' wrong: found $nums, expected $expected"
6342         }
6343 }
6344 run_test 56s "check lfs find -stripe-count works"
6345
6346 test_56t() { # LU-611 #LU-9369
6347         local dir=$DIR/$tdir
6348
6349         setup_56 $dir 0 $NUMDIRS
6350         for i in $(seq $NUMDIRS); do
6351                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6352         done
6353
6354         local expected=$NUMDIRS
6355         local cmd="$LFS find -S 8M $dir"
6356         local nums=$($cmd | wc -l)
6357
6358         [ $nums -eq $expected ] || {
6359                 $LFS getstripe -R $dir
6360                 error "'$cmd' wrong: found $nums, expected $expected"
6361         }
6362         rm -rf $dir
6363
6364         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6365
6366         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6367
6368         expected=$(((NUMDIRS + 1) * NUMFILES))
6369         cmd="$LFS find -stripe-size 512k -type f $dir"
6370         nums=$($cmd | wc -l)
6371         [ $nums -eq $expected ] ||
6372                 error "'$cmd' wrong: found $nums, expected $expected"
6373
6374         cmd="$LFS find -stripe-size +320k -type f $dir"
6375         nums=$($cmd | wc -l)
6376         [ $nums -eq $expected ] ||
6377                 error "'$cmd' wrong: found $nums, expected $expected"
6378
6379         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6380         cmd="$LFS find -stripe-size +200k -type f $dir"
6381         nums=$($cmd | wc -l)
6382         [ $nums -eq $expected ] ||
6383                 error "'$cmd' wrong: found $nums, expected $expected"
6384
6385         cmd="$LFS find -stripe-size -640k -type f $dir"
6386         nums=$($cmd | wc -l)
6387         [ $nums -eq $expected ] ||
6388                 error "'$cmd' wrong: found $nums, expected $expected"
6389
6390         expected=4
6391         cmd="$LFS find -stripe-size 256k -type f $dir"
6392         nums=$($cmd | wc -l)
6393         [ $nums -eq $expected ] ||
6394                 error "'$cmd' wrong: found $nums, expected $expected"
6395
6396         cmd="$LFS find -stripe-size -320k -type f $dir"
6397         nums=$($cmd | wc -l)
6398         [ $nums -eq $expected ] ||
6399                 error "'$cmd' wrong: found $nums, expected $expected"
6400
6401         expected=0
6402         cmd="$LFS find -stripe-size 1024k -type f $dir"
6403         nums=$($cmd | wc -l)
6404         [ $nums -eq $expected ] ||
6405                 error "'$cmd' wrong: found $nums, expected $expected"
6406 }
6407 run_test 56t "check lfs find -stripe-size works"
6408
6409 test_56u() { # LU-611
6410         local dir=$DIR/$tdir
6411
6412         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6413
6414         if [[ $OSTCOUNT -gt 1 ]]; then
6415                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6416                 onestripe=4
6417         else
6418                 onestripe=0
6419         fi
6420
6421         local expected=$(((NUMDIRS + 1) * NUMFILES))
6422         local cmd="$LFS find -stripe-index 0 -type f $dir"
6423         local nums=$($cmd | wc -l)
6424
6425         [ $nums -eq $expected ] ||
6426                 error "'$cmd' wrong: found $nums, expected $expected"
6427
6428         expected=$onestripe
6429         cmd="$LFS find -stripe-index 1 -type f $dir"
6430         nums=$($cmd | wc -l)
6431         [ $nums -eq $expected ] ||
6432                 error "'$cmd' wrong: found $nums, expected $expected"
6433
6434         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6435         nums=$($cmd | wc -l)
6436         [ $nums -eq $expected ] ||
6437                 error "'$cmd' wrong: found $nums, expected $expected"
6438
6439         expected=0
6440         # This should produce an error and not return any files
6441         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6442         nums=$($cmd 2>/dev/null | wc -l)
6443         [ $nums -eq $expected ] ||
6444                 error "'$cmd' wrong: found $nums, expected $expected"
6445
6446         if [[ $OSTCOUNT -gt 1 ]]; then
6447                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6448                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6449                 nums=$($cmd | wc -l)
6450                 [ $nums -eq $expected ] ||
6451                         error "'$cmd' wrong: found $nums, expected $expected"
6452         fi
6453 }
6454 run_test 56u "check lfs find -stripe-index works"
6455
6456 test_56v() {
6457         local mdt_idx=0
6458         local dir=$DIR/$tdir
6459
6460         setup_56 $dir $NUMFILES $NUMDIRS
6461
6462         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6463         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6464
6465         for file in $($LFS find -m $UUID $dir); do
6466                 file_midx=$($LFS getstripe -m $file)
6467                 [ $file_midx -eq $mdt_idx ] ||
6468                         error "lfs find -m $UUID != getstripe -m $file_midx"
6469         done
6470 }
6471 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6472
6473 test_56w() {
6474         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6476
6477         local dir=$DIR/$tdir
6478
6479         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6480
6481         local stripe_size=$($LFS getstripe -S -d $dir) ||
6482                 error "$LFS getstripe -S -d $dir failed"
6483         stripe_size=${stripe_size%% *}
6484
6485         local file_size=$((stripe_size * OSTCOUNT))
6486         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6487         local required_space=$((file_num * file_size))
6488         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6489                            head -n1)
6490         [[ $free_space -le $((required_space / 1024)) ]] &&
6491                 skip_env "need $required_space, have $free_space kbytes"
6492
6493         local dd_bs=65536
6494         local dd_count=$((file_size / dd_bs))
6495
6496         # write data into the files
6497         local i
6498         local j
6499         local file
6500
6501         for i in $(seq $NUMFILES); do
6502                 file=$dir/file$i
6503                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6504                         error "write data into $file failed"
6505         done
6506         for i in $(seq $NUMDIRS); do
6507                 for j in $(seq $NUMFILES); do
6508                         file=$dir/dir$i/file$j
6509                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6510                                 error "write data into $file failed"
6511                 done
6512         done
6513
6514         # $LFS_MIGRATE will fail if hard link migration is unsupported
6515         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6516                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6517                         error "creating links to $dir/dir1/file1 failed"
6518         fi
6519
6520         local expected=-1
6521
6522         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6523
6524         # lfs_migrate file
6525         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6526
6527         echo "$cmd"
6528         eval $cmd || error "$cmd failed"
6529
6530         check_stripe_count $dir/file1 $expected
6531
6532         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6533         then
6534                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6535                 # OST 1 if it is on OST 0. This file is small enough to
6536                 # be on only one stripe.
6537                 file=$dir/migr_1_ost
6538                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6539                         error "write data into $file failed"
6540                 local obdidx=$($LFS getstripe -i $file)
6541                 local oldmd5=$(md5sum $file)
6542                 local newobdidx=0
6543
6544                 [[ $obdidx -eq 0 ]] && newobdidx=1
6545                 cmd="$LFS migrate -i $newobdidx $file"
6546                 echo $cmd
6547                 eval $cmd || error "$cmd failed"
6548
6549                 local realobdix=$($LFS getstripe -i $file)
6550                 local newmd5=$(md5sum $file)
6551
6552                 [[ $newobdidx -ne $realobdix ]] &&
6553                         error "new OST is different (was=$obdidx, "\
6554                               "wanted=$newobdidx, got=$realobdix)"
6555                 [[ "$oldmd5" != "$newmd5" ]] &&
6556                         error "md5sum differ: $oldmd5, $newmd5"
6557         fi
6558
6559         # lfs_migrate dir
6560         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6561         echo "$cmd"
6562         eval $cmd || error "$cmd failed"
6563
6564         for j in $(seq $NUMFILES); do
6565                 check_stripe_count $dir/dir1/file$j $expected
6566         done
6567
6568         # lfs_migrate works with lfs find
6569         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6570              $LFS_MIGRATE -y -c $expected"
6571         echo "$cmd"
6572         eval $cmd || error "$cmd failed"
6573
6574         for i in $(seq 2 $NUMFILES); do
6575                 check_stripe_count $dir/file$i $expected
6576         done
6577         for i in $(seq 2 $NUMDIRS); do
6578                 for j in $(seq $NUMFILES); do
6579                 check_stripe_count $dir/dir$i/file$j $expected
6580                 done
6581         done
6582 }
6583 run_test 56w "check lfs_migrate -c stripe_count works"
6584
6585 test_56wb() {
6586         local file1=$DIR/$tdir/file1
6587         local create_pool=false
6588         local initial_pool=$($LFS getstripe -p $DIR)
6589         local pool_list=()
6590         local pool=""
6591
6592         echo -n "Creating test dir..."
6593         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6594         echo "done."
6595
6596         echo -n "Creating test file..."
6597         touch $file1 || error "cannot create file"
6598         echo "done."
6599
6600         echo -n "Detecting existing pools..."
6601         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6602
6603         if [ ${#pool_list[@]} -gt 0 ]; then
6604                 echo "${pool_list[@]}"
6605                 for thispool in "${pool_list[@]}"; do
6606                         if [[ -z "$initial_pool" ||
6607                               "$initial_pool" != "$thispool" ]]; then
6608                                 pool="$thispool"
6609                                 echo "Using existing pool '$pool'"
6610                                 break
6611                         fi
6612                 done
6613         else
6614                 echo "none detected."
6615         fi
6616         if [ -z "$pool" ]; then
6617                 pool=${POOL:-testpool}
6618                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6619                 echo -n "Creating pool '$pool'..."
6620                 create_pool=true
6621                 pool_add $pool &> /dev/null ||
6622                         error "pool_add failed"
6623                 echo "done."
6624
6625                 echo -n "Adding target to pool..."
6626                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6627                         error "pool_add_targets failed"
6628                 echo "done."
6629         fi
6630
6631         echo -n "Setting pool using -p option..."
6632         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6633                 error "migrate failed rc = $?"
6634         echo "done."
6635
6636         echo -n "Verifying test file is in pool after migrating..."
6637         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6638                 error "file was not migrated to pool $pool"
6639         echo "done."
6640
6641         echo -n "Removing test file from pool '$pool'..."
6642         # "lfs migrate $file" won't remove the file from the pool
6643         # until some striping information is changed.
6644         $LFS migrate -c 1 $file1 &> /dev/null ||
6645                 error "cannot remove from pool"
6646         [ "$($LFS getstripe -p $file1)" ] &&
6647                 error "pool still set"
6648         echo "done."
6649
6650         echo -n "Setting pool using --pool option..."
6651         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6652                 error "migrate failed rc = $?"
6653         echo "done."
6654
6655         # Clean up
6656         rm -f $file1
6657         if $create_pool; then
6658                 destroy_test_pools 2> /dev/null ||
6659                         error "destroy test pools failed"
6660         fi
6661 }
6662 run_test 56wb "check lfs_migrate pool support"
6663
6664 test_56wc() {
6665         local file1="$DIR/$tdir/file1"
6666         local parent_ssize
6667         local parent_scount
6668         local cur_ssize
6669         local cur_scount
6670         local orig_ssize
6671
6672         echo -n "Creating test dir..."
6673         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6674         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6675                 error "cannot set stripe by '-S 1M -c 1'"
6676         echo "done"
6677
6678         echo -n "Setting initial stripe for test file..."
6679         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6680                 error "cannot set stripe"
6681         cur_ssize=$($LFS getstripe -S "$file1")
6682         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6683         echo "done."
6684
6685         # File currently set to -S 512K -c 1
6686
6687         # Ensure -c and -S options are rejected when -R is set
6688         echo -n "Verifying incompatible options are detected..."
6689         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6690                 error "incompatible -c and -R options not detected"
6691         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6692                 error "incompatible -S and -R options not detected"
6693         echo "done."
6694
6695         # Ensure unrecognized options are passed through to 'lfs migrate'
6696         echo -n "Verifying -S option is passed through to lfs migrate..."
6697         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6698                 error "migration failed"
6699         cur_ssize=$($LFS getstripe -S "$file1")
6700         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6701         echo "done."
6702
6703         # File currently set to -S 1M -c 1
6704
6705         # Ensure long options are supported
6706         echo -n "Verifying long options supported..."
6707         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6708                 error "long option without argument not supported"
6709         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6710                 error "long option with argument not supported"
6711         cur_ssize=$($LFS getstripe -S "$file1")
6712         [ $cur_ssize -eq 524288 ] ||
6713                 error "migrate --stripe-size $cur_ssize != 524288"
6714         echo "done."
6715
6716         # File currently set to -S 512K -c 1
6717
6718         if [ "$OSTCOUNT" -gt 1 ]; then
6719                 echo -n "Verifying explicit stripe count can be set..."
6720                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6721                         error "migrate failed"
6722                 cur_scount=$($LFS getstripe -c "$file1")
6723                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6724                 echo "done."
6725         fi
6726
6727         # File currently set to -S 512K -c 1 or -S 512K -c 2
6728
6729         # Ensure parent striping is used if -R is set, and no stripe
6730         # count or size is specified
6731         echo -n "Setting stripe for parent directory..."
6732         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6733                 error "cannot set stripe '-S 2M -c 1'"
6734         echo "done."
6735
6736         echo -n "Verifying restripe option uses parent stripe settings..."
6737         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6738         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6739         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6740                 error "migrate failed"
6741         cur_ssize=$($LFS getstripe -S "$file1")
6742         [ $cur_ssize -eq $parent_ssize ] ||
6743                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6744         cur_scount=$($LFS getstripe -c "$file1")
6745         [ $cur_scount -eq $parent_scount ] ||
6746                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6747         echo "done."
6748
6749         # File currently set to -S 1M -c 1
6750
6751         # Ensure striping is preserved if -R is not set, and no stripe
6752         # count or size is specified
6753         echo -n "Verifying striping size preserved when not specified..."
6754         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6755         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6756                 error "cannot set stripe on parent directory"
6757         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6758                 error "migrate failed"
6759         cur_ssize=$($LFS getstripe -S "$file1")
6760         [ $cur_ssize -eq $orig_ssize ] ||
6761                 error "migrate by default $cur_ssize != $orig_ssize"
6762         echo "done."
6763
6764         # Ensure file name properly detected when final option has no argument
6765         echo -n "Verifying file name properly detected..."
6766         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6767                 error "file name interpreted as option argument"
6768         echo "done."
6769
6770         # Clean up
6771         rm -f "$file1"
6772 }
6773 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6774
6775 test_56wd() {
6776         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6777
6778         local file1=$DIR/$tdir/file1
6779
6780         echo -n "Creating test dir..."
6781         test_mkdir $DIR/$tdir || error "cannot create dir"
6782         echo "done."
6783
6784         echo -n "Creating test file..."
6785         touch $file1
6786         echo "done."
6787
6788         # Ensure 'lfs migrate' will fail by using a non-existent option,
6789         # and make sure rsync is not called to recover
6790         echo -n "Make sure --no-rsync option works..."
6791         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6792                 grep -q 'refusing to fall back to rsync' ||
6793                 error "rsync was called with --no-rsync set"
6794         echo "done."
6795
6796         # Ensure rsync is called without trying 'lfs migrate' first
6797         echo -n "Make sure --rsync option works..."
6798         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6799                 grep -q 'falling back to rsync' &&
6800                 error "lfs migrate was called with --rsync set"
6801         echo "done."
6802
6803         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6804         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6805                 grep -q 'at the same time' ||
6806                 error "--rsync and --no-rsync accepted concurrently"
6807         echo "done."
6808
6809         # Clean up
6810         rm -f $file1
6811 }
6812 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6813
6814 test_56we() {
6815         local td=$DIR/$tdir
6816         local tf=$td/$tfile
6817
6818         test_mkdir $td || error "cannot create $td"
6819         touch $tf || error "cannot touch $tf"
6820
6821         echo -n "Make sure --non-direct|-D works..."
6822         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6823                 grep -q "lfs migrate --non-direct" ||
6824                 error "--non-direct option cannot work correctly"
6825         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6826                 grep -q "lfs migrate -D" ||
6827                 error "-D option cannot work correctly"
6828         echo "done."
6829 }
6830 run_test 56we "check lfs_migrate --non-direct|-D support"
6831
6832 test_56x() {
6833         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6834         check_swap_layouts_support
6835
6836         local dir=$DIR/$tdir
6837         local ref1=/etc/passwd
6838         local file1=$dir/file1
6839
6840         test_mkdir $dir || error "creating dir $dir"
6841         $LFS setstripe -c 2 $file1
6842         cp $ref1 $file1
6843         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6844         stripe=$($LFS getstripe -c $file1)
6845         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6846         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6847
6848         # clean up
6849         rm -f $file1
6850 }
6851 run_test 56x "lfs migration support"
6852
6853 test_56xa() {
6854         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6855         check_swap_layouts_support
6856
6857         local dir=$DIR/$tdir/$testnum
6858
6859         test_mkdir -p $dir
6860
6861         local ref1=/etc/passwd
6862         local file1=$dir/file1
6863
6864         $LFS setstripe -c 2 $file1
6865         cp $ref1 $file1
6866         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6867
6868         local stripe=$($LFS getstripe -c $file1)
6869
6870         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6871         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6872
6873         # clean up
6874         rm -f $file1
6875 }
6876 run_test 56xa "lfs migration --block support"
6877
6878 check_migrate_links() {
6879         local dir="$1"
6880         local file1="$dir/file1"
6881         local begin="$2"
6882         local count="$3"
6883         local runas="$4"
6884         local total_count=$(($begin + $count - 1))
6885         local symlink_count=10
6886         local uniq_count=10
6887
6888         if [ ! -f "$file1" ]; then
6889                 echo -n "creating initial file..."
6890                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6891                         error "cannot setstripe initial file"
6892                 echo "done"
6893
6894                 echo -n "creating symlinks..."
6895                 for s in $(seq 1 $symlink_count); do
6896                         ln -s "$file1" "$dir/slink$s" ||
6897                                 error "cannot create symlinks"
6898                 done
6899                 echo "done"
6900
6901                 echo -n "creating nonlinked files..."
6902                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6903                         error "cannot create nonlinked files"
6904                 echo "done"
6905         fi
6906
6907         # create hard links
6908         if [ ! -f "$dir/file$total_count" ]; then
6909                 echo -n "creating hard links $begin:$total_count..."
6910                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6911                         /dev/null || error "cannot create hard links"
6912                 echo "done"
6913         fi
6914
6915         echo -n "checking number of hard links listed in xattrs..."
6916         local fid=$($LFS getstripe -F "$file1")
6917         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6918
6919         echo "${#paths[*]}"
6920         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6921                         skip "hard link list has unexpected size, skipping test"
6922         fi
6923         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6924                         error "link names should exceed xattrs size"
6925         fi
6926
6927         echo -n "migrating files..."
6928         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6929         local rc=$?
6930         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6931         echo "done"
6932
6933         # make sure all links have been properly migrated
6934         echo -n "verifying files..."
6935         fid=$($LFS getstripe -F "$file1") ||
6936                 error "cannot get fid for file $file1"
6937         for i in $(seq 2 $total_count); do
6938                 local fid2=$($LFS getstripe -F $dir/file$i)
6939
6940                 [ "$fid2" == "$fid" ] ||
6941                         error "migrated hard link has mismatched FID"
6942         done
6943
6944         # make sure hard links were properly detected, and migration was
6945         # performed only once for the entire link set; nonlinked files should
6946         # also be migrated
6947         local actual=$(grep -c 'done' <<< "$migrate_out")
6948         local expected=$(($uniq_count + 1))
6949
6950         [ "$actual" -eq  "$expected" ] ||
6951                 error "hard links individually migrated ($actual != $expected)"
6952
6953         # make sure the correct number of hard links are present
6954         local hardlinks=$(stat -c '%h' "$file1")
6955
6956         [ $hardlinks -eq $total_count ] ||
6957                 error "num hard links $hardlinks != $total_count"
6958         echo "done"
6959
6960         return 0
6961 }
6962
6963 test_56xb() {
6964         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6965                 skip "Need MDS version at least 2.10.55"
6966
6967         local dir="$DIR/$tdir"
6968
6969         test_mkdir "$dir" || error "cannot create dir $dir"
6970
6971         echo "testing lfs migrate mode when all links fit within xattrs"
6972         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6973
6974         echo "testing rsync mode when all links fit within xattrs"
6975         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6976
6977         echo "testing lfs migrate mode when all links do not fit within xattrs"
6978         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6979
6980         echo "testing rsync mode when all links do not fit within xattrs"
6981         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6982
6983         chown -R $RUNAS_ID $dir
6984         echo "testing non-root lfs migrate mode when not all links are in xattr"
6985         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
6986
6987         # clean up
6988         rm -rf $dir
6989 }
6990 run_test 56xb "lfs migration hard link support"
6991
6992 test_56xc() {
6993         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6994
6995         local dir="$DIR/$tdir"
6996
6997         test_mkdir "$dir" || error "cannot create dir $dir"
6998
6999         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7000         echo -n "Setting initial stripe for 20MB test file..."
7001         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7002                 error "cannot setstripe 20MB file"
7003         echo "done"
7004         echo -n "Sizing 20MB test file..."
7005         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7006         echo "done"
7007         echo -n "Verifying small file autostripe count is 1..."
7008         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7009                 error "cannot migrate 20MB file"
7010         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7011                 error "cannot get stripe for $dir/20mb"
7012         [ $stripe_count -eq 1 ] ||
7013                 error "unexpected stripe count $stripe_count for 20MB file"
7014         rm -f "$dir/20mb"
7015         echo "done"
7016
7017         # Test 2: File is small enough to fit within the available space on
7018         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7019         # have at least an additional 1KB for each desired stripe for test 3
7020         echo -n "Setting stripe for 1GB test file..."
7021         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7022         echo "done"
7023         echo -n "Sizing 1GB test file..."
7024         # File size is 1GB + 3KB
7025         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7026         echo "done"
7027
7028         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7029         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7030         if (( avail > 524288 * OSTCOUNT )); then
7031                 echo -n "Migrating 1GB file..."
7032                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7033                         error "cannot migrate 1GB file"
7034                 echo "done"
7035                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7036                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7037                         error "cannot getstripe for 1GB file"
7038                 [ $stripe_count -eq 2 ] ||
7039                         error "unexpected stripe count $stripe_count != 2"
7040                 echo "done"
7041         fi
7042
7043         # Test 3: File is too large to fit within the available space on
7044         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7045         if [ $OSTCOUNT -ge 3 ]; then
7046                 # The required available space is calculated as
7047                 # file size (1GB + 3KB) / OST count (3).
7048                 local kb_per_ost=349526
7049
7050                 echo -n "Migrating 1GB file with limit..."
7051                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7052                         error "cannot migrate 1GB file with limit"
7053                 echo "done"
7054
7055                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7056                 echo -n "Verifying 1GB autostripe count with limited space..."
7057                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7058                         error "unexpected stripe count $stripe_count (min 3)"
7059                 echo "done"
7060         fi
7061
7062         # clean up
7063         rm -rf $dir
7064 }
7065 run_test 56xc "lfs migration autostripe"
7066
7067 test_56xd() {
7068         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7069
7070         local dir=$DIR/$tdir
7071         local f_mgrt=$dir/$tfile.mgrt
7072         local f_yaml=$dir/$tfile.yaml
7073         local f_copy=$dir/$tfile.copy
7074         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7075         local layout_copy="-c 2 -S 2M -i 1"
7076         local yamlfile=$dir/yamlfile
7077         local layout_before;
7078         local layout_after;
7079
7080         test_mkdir "$dir" || error "cannot create dir $dir"
7081         $LFS setstripe $layout_yaml $f_yaml ||
7082                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7083         $LFS getstripe --yaml $f_yaml > $yamlfile
7084         $LFS setstripe $layout_copy $f_copy ||
7085                 error "cannot setstripe $f_copy with layout $layout_copy"
7086         touch $f_mgrt
7087         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7088
7089         # 1. test option --yaml
7090         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7091                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7092         layout_before=$(get_layout_param $f_yaml)
7093         layout_after=$(get_layout_param $f_mgrt)
7094         [ "$layout_after" == "$layout_before" ] ||
7095                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7096
7097         # 2. test option --copy
7098         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7099                 error "cannot migrate $f_mgrt with --copy $f_copy"
7100         layout_before=$(get_layout_param $f_copy)
7101         layout_after=$(get_layout_param $f_mgrt)
7102         [ "$layout_after" == "$layout_before" ] ||
7103                 error "lfs_migrate --copy: $layout_after != $layout_before"
7104 }
7105 run_test 56xd "check lfs_migrate --yaml and --copy support"
7106
7107 test_56xe() {
7108         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7109
7110         local dir=$DIR/$tdir
7111         local f_comp=$dir/$tfile
7112         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7113         local layout_before=""
7114         local layout_after=""
7115
7116         test_mkdir "$dir" || error "cannot create dir $dir"
7117         $LFS setstripe $layout $f_comp ||
7118                 error "cannot setstripe $f_comp with layout $layout"
7119         layout_before=$(get_layout_param $f_comp)
7120         dd if=/dev/zero of=$f_comp bs=1M count=4
7121
7122         # 1. migrate a comp layout file by lfs_migrate
7123         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7124         layout_after=$(get_layout_param $f_comp)
7125         [ "$layout_before" == "$layout_after" ] ||
7126                 error "lfs_migrate: $layout_before != $layout_after"
7127
7128         # 2. migrate a comp layout file by lfs migrate
7129         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7130         layout_after=$(get_layout_param $f_comp)
7131         [ "$layout_before" == "$layout_after" ] ||
7132                 error "lfs migrate: $layout_before != $layout_after"
7133 }
7134 run_test 56xe "migrate a composite layout file"
7135
7136 test_56xf() {
7137         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7138
7139         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7140                 skip "Need server version at least 2.13.53"
7141
7142         local dir=$DIR/$tdir
7143         local f_comp=$dir/$tfile
7144         local layout="-E 1M -c1 -E -1 -c2"
7145         local fid_before=""
7146         local fid_after=""
7147
7148         test_mkdir "$dir" || error "cannot create dir $dir"
7149         $LFS setstripe $layout $f_comp ||
7150                 error "cannot setstripe $f_comp with layout $layout"
7151         fid_before=$($LFS getstripe --fid $f_comp)
7152         dd if=/dev/zero of=$f_comp bs=1M count=4
7153
7154         # 1. migrate a comp layout file to a comp layout
7155         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7156         fid_after=$($LFS getstripe --fid $f_comp)
7157         [ "$fid_before" == "$fid_after" ] ||
7158                 error "comp-to-comp migrate: $fid_before != $fid_after"
7159
7160         # 2. migrate a comp layout file to a plain layout
7161         $LFS migrate -c2 $f_comp ||
7162                 error "cannot migrate $f_comp by lfs migrate"
7163         fid_after=$($LFS getstripe --fid $f_comp)
7164         [ "$fid_before" == "$fid_after" ] ||
7165                 error "comp-to-plain migrate: $fid_before != $fid_after"
7166
7167         # 3. migrate a plain layout file to a comp layout
7168         $LFS migrate $layout $f_comp ||
7169                 error "cannot migrate $f_comp by lfs migrate"
7170         fid_after=$($LFS getstripe --fid $f_comp)
7171         [ "$fid_before" == "$fid_after" ] ||
7172                 error "plain-to-comp migrate: $fid_before != $fid_after"
7173 }
7174 run_test 56xf "FID is not lost during migration of a composite layout file"
7175
7176 test_56y() {
7177         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7178                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7179
7180         local res=""
7181         local dir=$DIR/$tdir
7182         local f1=$dir/file1
7183         local f2=$dir/file2
7184
7185         test_mkdir -p $dir || error "creating dir $dir"
7186         touch $f1 || error "creating std file $f1"
7187         $MULTIOP $f2 H2c || error "creating released file $f2"
7188
7189         # a directory can be raid0, so ask only for files
7190         res=$($LFS find $dir -L raid0 -type f | wc -l)
7191         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7192
7193         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7194         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7195
7196         # only files can be released, so no need to force file search
7197         res=$($LFS find $dir -L released)
7198         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7199
7200         res=$($LFS find $dir -type f \! -L released)
7201         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7202 }
7203 run_test 56y "lfs find -L raid0|released"
7204
7205 test_56z() { # LU-4824
7206         # This checks to make sure 'lfs find' continues after errors
7207         # There are two classes of errors that should be caught:
7208         # - If multiple paths are provided, all should be searched even if one
7209         #   errors out
7210         # - If errors are encountered during the search, it should not terminate
7211         #   early
7212         local dir=$DIR/$tdir
7213         local i
7214
7215         test_mkdir $dir
7216         for i in d{0..9}; do
7217                 test_mkdir $dir/$i
7218                 touch $dir/$i/$tfile
7219         done
7220         $LFS find $DIR/non_existent_dir $dir &&
7221                 error "$LFS find did not return an error"
7222         # Make a directory unsearchable. This should NOT be the last entry in
7223         # directory order.  Arbitrarily pick the 6th entry
7224         chmod 700 $($LFS find $dir -type d | sed '6!d')
7225
7226         $RUNAS $LFS find $DIR/non_existent $dir
7227         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7228
7229         # The user should be able to see 10 directories and 9 files
7230         (( count == 19 )) ||
7231                 error "$LFS find found $count != 19 entries after error"
7232 }
7233 run_test 56z "lfs find should continue after an error"
7234
7235 test_56aa() { # LU-5937
7236         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7237
7238         local dir=$DIR/$tdir
7239
7240         mkdir $dir
7241         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7242
7243         createmany -o $dir/striped_dir/${tfile}- 1024
7244         local dirs=$($LFS find --size +8k $dir/)
7245
7246         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7247 }
7248 run_test 56aa "lfs find --size under striped dir"
7249
7250 test_56ab() { # LU-10705
7251         test_mkdir $DIR/$tdir
7252         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7253         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7254         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7255         # Flush writes to ensure valid blocks.  Need to be more thorough for
7256         # ZFS, since blocks are not allocated/returned to client immediately.
7257         sync_all_data
7258         wait_zfs_commit ost1 2
7259         cancel_lru_locks osc
7260         ls -ls $DIR/$tdir
7261
7262         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7263
7264         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7265
7266         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7267         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7268
7269         rm -f $DIR/$tdir/$tfile.[123]
7270 }
7271 run_test 56ab "lfs find --blocks"
7272
7273 test_56ba() {
7274         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7275                 skip "Need MDS version at least 2.10.50"
7276
7277         # Create composite files with one component
7278         local dir=$DIR/$tdir
7279
7280         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7281         # Create composite files with three components
7282         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7283         # Create non-composite files
7284         createmany -o $dir/${tfile}- 10
7285
7286         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7287
7288         [[ $nfiles == 10 ]] ||
7289                 error "lfs find -E 1M found $nfiles != 10 files"
7290
7291         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7292         [[ $nfiles == 25 ]] ||
7293                 error "lfs find ! -E 1M found $nfiles != 25 files"
7294
7295         # All files have a component that starts at 0
7296         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7297         [[ $nfiles == 35 ]] ||
7298                 error "lfs find --component-start 0 - $nfiles != 35 files"
7299
7300         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7301         [[ $nfiles == 15 ]] ||
7302                 error "lfs find --component-start 2M - $nfiles != 15 files"
7303
7304         # All files created here have a componenet that does not starts at 2M
7305         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7306         [[ $nfiles == 35 ]] ||
7307                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7308
7309         # Find files with a specified number of components
7310         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7311         [[ $nfiles == 15 ]] ||
7312                 error "lfs find --component-count 3 - $nfiles != 15 files"
7313
7314         # Remember non-composite files have a component count of zero
7315         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7316         [[ $nfiles == 10 ]] ||
7317                 error "lfs find --component-count 0 - $nfiles != 10 files"
7318
7319         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7320         [[ $nfiles == 20 ]] ||
7321                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7322
7323         # All files have a flag called "init"
7324         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7325         [[ $nfiles == 35 ]] ||
7326                 error "lfs find --component-flags init - $nfiles != 35 files"
7327
7328         # Multi-component files will have a component not initialized
7329         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7330         [[ $nfiles == 15 ]] ||
7331                 error "lfs find !--component-flags init - $nfiles != 15 files"
7332
7333         rm -rf $dir
7334
7335 }
7336 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7337
7338 test_56ca() {
7339         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7340                 skip "Need MDS version at least 2.10.57"
7341
7342         local td=$DIR/$tdir
7343         local tf=$td/$tfile
7344         local dir
7345         local nfiles
7346         local cmd
7347         local i
7348         local j
7349
7350         # create mirrored directories and mirrored files
7351         mkdir $td || error "mkdir $td failed"
7352         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7353         createmany -o $tf- 10 || error "create $tf- failed"
7354
7355         for i in $(seq 2); do
7356                 dir=$td/dir$i
7357                 mkdir $dir || error "mkdir $dir failed"
7358                 $LFS mirror create -N$((3 + i)) $dir ||
7359                         error "create mirrored dir $dir failed"
7360                 createmany -o $dir/$tfile- 10 ||
7361                         error "create $dir/$tfile- failed"
7362         done
7363
7364         # change the states of some mirrored files
7365         echo foo > $tf-6
7366         for i in $(seq 2); do
7367                 dir=$td/dir$i
7368                 for j in $(seq 4 9); do
7369                         echo foo > $dir/$tfile-$j
7370                 done
7371         done
7372
7373         # find mirrored files with specific mirror count
7374         cmd="$LFS find --mirror-count 3 --type f $td"
7375         nfiles=$($cmd | wc -l)
7376         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7377
7378         cmd="$LFS find ! --mirror-count 3 --type f $td"
7379         nfiles=$($cmd | wc -l)
7380         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7381
7382         cmd="$LFS find --mirror-count +2 --type f $td"
7383         nfiles=$($cmd | wc -l)
7384         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7385
7386         cmd="$LFS find --mirror-count -6 --type f $td"
7387         nfiles=$($cmd | wc -l)
7388         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7389
7390         # find mirrored files with specific file state
7391         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7392         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7393
7394         cmd="$LFS find --mirror-state=ro --type f $td"
7395         nfiles=$($cmd | wc -l)
7396         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7397
7398         cmd="$LFS find ! --mirror-state=ro --type f $td"
7399         nfiles=$($cmd | wc -l)
7400         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7401
7402         cmd="$LFS find --mirror-state=wp --type f $td"
7403         nfiles=$($cmd | wc -l)
7404         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7405
7406         cmd="$LFS find ! --mirror-state=sp --type f $td"
7407         nfiles=$($cmd | wc -l)
7408         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7409 }
7410 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7411
7412 test_57a() {
7413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7414         # note test will not do anything if MDS is not local
7415         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7416                 skip_env "ldiskfs only test"
7417         fi
7418         remote_mds_nodsh && skip "remote MDS with nodsh"
7419
7420         local MNTDEV="osd*.*MDT*.mntdev"
7421         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7422         [ -z "$DEV" ] && error "can't access $MNTDEV"
7423         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7424                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7425                         error "can't access $DEV"
7426                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7427                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7428                 rm $TMP/t57a.dump
7429         done
7430 }
7431 run_test 57a "verify MDS filesystem created with large inodes =="
7432
7433 test_57b() {
7434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7435         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7436                 skip_env "ldiskfs only test"
7437         fi
7438         remote_mds_nodsh && skip "remote MDS with nodsh"
7439
7440         local dir=$DIR/$tdir
7441         local filecount=100
7442         local file1=$dir/f1
7443         local fileN=$dir/f$filecount
7444
7445         rm -rf $dir || error "removing $dir"
7446         test_mkdir -c1 $dir
7447         local mdtidx=$($LFS getstripe -m $dir)
7448         local mdtname=MDT$(printf %04x $mdtidx)
7449         local facet=mds$((mdtidx + 1))
7450
7451         echo "mcreating $filecount files"
7452         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7453
7454         # verify that files do not have EAs yet
7455         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7456                 error "$file1 has an EA"
7457         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7458                 error "$fileN has an EA"
7459
7460         sync
7461         sleep 1
7462         df $dir  #make sure we get new statfs data
7463         local mdsfree=$(do_facet $facet \
7464                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7465         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7466         local file
7467
7468         echo "opening files to create objects/EAs"
7469         for file in $(seq -f $dir/f%g 1 $filecount); do
7470                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7471                         error "opening $file"
7472         done
7473
7474         # verify that files have EAs now
7475         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7476         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7477
7478         sleep 1  #make sure we get new statfs data
7479         df $dir
7480         local mdsfree2=$(do_facet $facet \
7481                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7482         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7483
7484         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7485                 if [ "$mdsfree" != "$mdsfree2" ]; then
7486                         error "MDC before $mdcfree != after $mdcfree2"
7487                 else
7488                         echo "MDC before $mdcfree != after $mdcfree2"
7489                         echo "unable to confirm if MDS has large inodes"
7490                 fi
7491         fi
7492         rm -rf $dir
7493 }
7494 run_test 57b "default LOV EAs are stored inside large inodes ==="
7495
7496 test_58() {
7497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7498         [ -z "$(which wiretest 2>/dev/null)" ] &&
7499                         skip_env "could not find wiretest"
7500
7501         wiretest
7502 }
7503 run_test 58 "verify cross-platform wire constants =============="
7504
7505 test_59() {
7506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7507
7508         echo "touch 130 files"
7509         createmany -o $DIR/f59- 130
7510         echo "rm 130 files"
7511         unlinkmany $DIR/f59- 130
7512         sync
7513         # wait for commitment of removal
7514         wait_delete_completed
7515 }
7516 run_test 59 "verify cancellation of llog records async ========="
7517
7518 TEST60_HEAD="test_60 run $RANDOM"
7519 test_60a() {
7520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7521         remote_mgs_nodsh && skip "remote MGS with nodsh"
7522         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7523                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7524                         skip_env "missing subtest run-llog.sh"
7525
7526         log "$TEST60_HEAD - from kernel mode"
7527         do_facet mgs "$LCTL dk > /dev/null"
7528         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7529         do_facet mgs $LCTL dk > $TMP/$tfile
7530
7531         # LU-6388: test llog_reader
7532         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7533         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7534         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7535                         skip_env "missing llog_reader"
7536         local fstype=$(facet_fstype mgs)
7537         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7538                 skip_env "Only for ldiskfs or zfs type mgs"
7539
7540         local mntpt=$(facet_mntpt mgs)
7541         local mgsdev=$(mgsdevname 1)
7542         local fid_list
7543         local fid
7544         local rec_list
7545         local rec
7546         local rec_type
7547         local obj_file
7548         local path
7549         local seq
7550         local oid
7551         local pass=true
7552
7553         #get fid and record list
7554         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7555                 tail -n 4))
7556         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7557                 tail -n 4))
7558         #remount mgs as ldiskfs or zfs type
7559         stop mgs || error "stop mgs failed"
7560         mount_fstype mgs || error "remount mgs failed"
7561         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7562                 fid=${fid_list[i]}
7563                 rec=${rec_list[i]}
7564                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7565                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7566                 oid=$((16#$oid))
7567
7568                 case $fstype in
7569                         ldiskfs )
7570                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7571                         zfs )
7572                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7573                 esac
7574                 echo "obj_file is $obj_file"
7575                 do_facet mgs $llog_reader $obj_file
7576
7577                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7578                         awk '{ print $3 }' | sed -e "s/^type=//g")
7579                 if [ $rec_type != $rec ]; then
7580                         echo "FAILED test_60a wrong record type $rec_type," \
7581                               "should be $rec"
7582                         pass=false
7583                         break
7584                 fi
7585
7586                 #check obj path if record type is LLOG_LOGID_MAGIC
7587                 if [ "$rec" == "1064553b" ]; then
7588                         path=$(do_facet mgs $llog_reader $obj_file |
7589                                 grep "path=" | awk '{ print $NF }' |
7590                                 sed -e "s/^path=//g")
7591                         if [ $obj_file != $mntpt/$path ]; then
7592                                 echo "FAILED test_60a wrong obj path" \
7593                                       "$montpt/$path, should be $obj_file"
7594                                 pass=false
7595                                 break
7596                         fi
7597                 fi
7598         done
7599         rm -f $TMP/$tfile
7600         #restart mgs before "error", otherwise it will block the next test
7601         stop mgs || error "stop mgs failed"
7602         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7603         $pass || error "test failed, see FAILED test_60a messages for specifics"
7604 }
7605 run_test 60a "llog_test run from kernel module and test llog_reader"
7606
7607 test_60b() { # bug 6411
7608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7609
7610         dmesg > $DIR/$tfile
7611         LLOG_COUNT=$(do_facet mgs dmesg |
7612                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7613                           /llog_[a-z]*.c:[0-9]/ {
7614                                 if (marker)
7615                                         from_marker++
7616                                 from_begin++
7617                           }
7618                           END {
7619                                 if (marker)
7620                                         print from_marker
7621                                 else
7622                                         print from_begin
7623                           }")
7624
7625         [[ $LLOG_COUNT -gt 120 ]] &&
7626                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7627 }
7628 run_test 60b "limit repeated messages from CERROR/CWARN"
7629
7630 test_60c() {
7631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7632
7633         echo "create 5000 files"
7634         createmany -o $DIR/f60c- 5000
7635 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7636         lctl set_param fail_loc=0x80000137
7637         unlinkmany $DIR/f60c- 5000
7638         lctl set_param fail_loc=0
7639 }
7640 run_test 60c "unlink file when mds full"
7641
7642 test_60d() {
7643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7644
7645         SAVEPRINTK=$(lctl get_param -n printk)
7646         # verify "lctl mark" is even working"
7647         MESSAGE="test message ID $RANDOM $$"
7648         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7649         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7650
7651         lctl set_param printk=0 || error "set lnet.printk failed"
7652         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7653         MESSAGE="new test message ID $RANDOM $$"
7654         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7655         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7656         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7657
7658         lctl set_param -n printk="$SAVEPRINTK"
7659 }
7660 run_test 60d "test printk console message masking"
7661
7662 test_60e() {
7663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7664         remote_mds_nodsh && skip "remote MDS with nodsh"
7665
7666         touch $DIR/$tfile
7667 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7668         do_facet mds1 lctl set_param fail_loc=0x15b
7669         rm $DIR/$tfile
7670 }
7671 run_test 60e "no space while new llog is being created"
7672
7673 test_60g() {
7674         local pid
7675         local i
7676
7677         test_mkdir -c $MDSCOUNT $DIR/$tdir
7678
7679         (
7680                 local index=0
7681                 while true; do
7682                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7683                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7684                                 2>/dev/null
7685                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7686                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7687                         index=$((index + 1))
7688                 done
7689         ) &
7690
7691         pid=$!
7692
7693         for i in {0..100}; do
7694                 # define OBD_FAIL_OSD_TXN_START    0x19a
7695                 local index=$((i % MDSCOUNT + 1))
7696
7697                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7698                         > /dev/null
7699                 usleep 100
7700         done
7701
7702         kill -9 $pid
7703
7704         for i in $(seq $MDSCOUNT); do
7705                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7706         done
7707
7708         mkdir $DIR/$tdir/new || error "mkdir failed"
7709         rmdir $DIR/$tdir/new || error "rmdir failed"
7710
7711         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7712                 -t namespace
7713         for i in $(seq $MDSCOUNT); do
7714                 wait_update_facet mds$i "$LCTL get_param -n \
7715                         mdd.$(facet_svc mds$i).lfsck_namespace |
7716                         awk '/^status/ { print \\\$2 }'" "completed"
7717         done
7718
7719         ls -R $DIR/$tdir || error "ls failed"
7720         rm -rf $DIR/$tdir || error "rmdir failed"
7721 }
7722 run_test 60g "transaction abort won't cause MDT hung"
7723
7724 test_60h() {
7725         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7726                 skip "Need MDS version at least 2.12.52"
7727         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7728
7729         local f
7730
7731         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7732         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7733         for fail_loc in 0x80000188 0x80000189; do
7734                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7735                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7736                         error "mkdir $dir-$fail_loc failed"
7737                 for i in {0..10}; do
7738                         # create may fail on missing stripe
7739                         echo $i > $DIR/$tdir-$fail_loc/$i
7740                 done
7741                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7742                         error "getdirstripe $tdir-$fail_loc failed"
7743                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7744                         error "migrate $tdir-$fail_loc failed"
7745                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7746                         error "getdirstripe $tdir-$fail_loc failed"
7747                 pushd $DIR/$tdir-$fail_loc
7748                 for f in *; do
7749                         echo $f | cmp $f - || error "$f data mismatch"
7750                 done
7751                 popd
7752                 rm -rf $DIR/$tdir-$fail_loc
7753         done
7754 }
7755 run_test 60h "striped directory with missing stripes can be accessed"
7756
7757 test_61a() {
7758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7759
7760         f="$DIR/f61"
7761         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7762         cancel_lru_locks osc
7763         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7764         sync
7765 }
7766 run_test 61a "mmap() writes don't make sync hang ================"
7767
7768 test_61b() {
7769         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7770 }
7771 run_test 61b "mmap() of unstriped file is successful"
7772
7773 # bug 2330 - insufficient obd_match error checking causes LBUG
7774 test_62() {
7775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7776
7777         f="$DIR/f62"
7778         echo foo > $f
7779         cancel_lru_locks osc
7780         lctl set_param fail_loc=0x405
7781         cat $f && error "cat succeeded, expect -EIO"
7782         lctl set_param fail_loc=0
7783 }
7784 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7785 # match every page all of the time.
7786 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7787
7788 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7789 # Though this test is irrelevant anymore, it helped to reveal some
7790 # other grant bugs (LU-4482), let's keep it.
7791 test_63a() {   # was test_63
7792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7793
7794         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7795
7796         for i in `seq 10` ; do
7797                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7798                 sleep 5
7799                 kill $!
7800                 sleep 1
7801         done
7802
7803         rm -f $DIR/f63 || true
7804 }
7805 run_test 63a "Verify oig_wait interruption does not crash ======="
7806
7807 # bug 2248 - async write errors didn't return to application on sync
7808 # bug 3677 - async write errors left page locked
7809 test_63b() {
7810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7811
7812         debugsave
7813         lctl set_param debug=-1
7814
7815         # ensure we have a grant to do async writes
7816         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7817         rm $DIR/$tfile
7818
7819         sync    # sync lest earlier test intercept the fail_loc
7820
7821         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7822         lctl set_param fail_loc=0x80000406
7823         $MULTIOP $DIR/$tfile Owy && \
7824                 error "sync didn't return ENOMEM"
7825         sync; sleep 2; sync     # do a real sync this time to flush page
7826         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7827                 error "locked page left in cache after async error" || true
7828         debugrestore
7829 }
7830 run_test 63b "async write errors should be returned to fsync ==="
7831
7832 test_64a () {
7833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7834
7835         lfs df $DIR
7836         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7837 }
7838 run_test 64a "verify filter grant calculations (in kernel) ====="
7839
7840 test_64b () {
7841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7842
7843         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7844 }
7845 run_test 64b "check out-of-space detection on client"
7846
7847 test_64c() {
7848         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7849 }
7850 run_test 64c "verify grant shrink"
7851
7852 import_param() {
7853         local tgt=$1
7854         local param=$2
7855
7856         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7857 }
7858
7859 # this does exactly what osc_request.c:osc_announce_cached() does in
7860 # order to calculate max amount of grants to ask from server
7861 want_grant() {
7862         local tgt=$1
7863
7864         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7865         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7866
7867         ((rpc_in_flight++));
7868         nrpages=$((nrpages * rpc_in_flight))
7869
7870         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7871
7872         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7873
7874         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7875         local undirty=$((nrpages * PAGE_SIZE))
7876
7877         local max_extent_pages
7878         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7879         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7880         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7881         local grant_extent_tax
7882         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7883
7884         undirty=$((undirty + nrextents * grant_extent_tax))
7885
7886         echo $undirty
7887 }
7888
7889 # this is size of unit for grant allocation. It should be equal to
7890 # what tgt_grant.c:tgt_grant_chunk() calculates
7891 grant_chunk() {
7892         local tgt=$1
7893         local max_brw_size
7894         local grant_extent_tax
7895
7896         max_brw_size=$(import_param $tgt max_brw_size)
7897
7898         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7899
7900         echo $(((max_brw_size + grant_extent_tax) * 2))
7901 }
7902
7903 test_64d() {
7904         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7905                 skip "OST < 2.10.55 doesn't limit grants enough"
7906
7907         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7908
7909         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7910                 skip "no grant_param connect flag"
7911
7912         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7913
7914         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7915         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7916
7917
7918         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7919         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7920
7921         $LFS setstripe $DIR/$tfile -i 0 -c 1
7922         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7923         ddpid=$!
7924
7925         while kill -0 $ddpid; do
7926                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7927
7928                 if [[ $cur_grant -gt $max_cur_granted ]]; then
7929                         kill $ddpid
7930                         error "cur_grant $cur_grant > $max_cur_granted"
7931                 fi
7932
7933                 sleep 1
7934         done
7935 }
7936 run_test 64d "check grant limit exceed"
7937
7938 check_grants() {
7939         local tgt=$1
7940         local expected=$2
7941         local msg=$3
7942         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7943
7944         ((cur_grants == expected)) ||
7945                 error "$msg: grants mismatch: $cur_grants, expected $expected"
7946 }
7947
7948 round_up_p2() {
7949         echo $((($1 + $2 - 1) & ~($2 - 1)))
7950 }
7951
7952 test_64e() {
7953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7954         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
7955                 skip "Need OSS version at least 2.11.56"
7956
7957         # Remount client to reset grant
7958         remount_client $MOUNT || error "failed to remount client"
7959         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
7960
7961         local init_grants=$(import_param $osc_tgt initial_grant)
7962
7963         check_grants $osc_tgt $init_grants "init grants"
7964
7965         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
7966         local max_brw_size=$(import_param $osc_tgt max_brw_size)
7967         local gbs=$(import_param $osc_tgt grant_block_size)
7968
7969         # write random number of bytes from max_brw_size / 4 to max_brw_size
7970         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
7971         # align for direct io
7972         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
7973         # round to grant consumption unit
7974         local wb_round_up=$(round_up_p2 $write_bytes gbs)
7975
7976         local grants=$((wb_round_up + extent_tax))
7977
7978         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
7979
7980         # define OBD_FAIL_TGT_NO_GRANT 0x725
7981         # make the server not grant more back
7982         do_facet ost1 $LCTL set_param fail_loc=0x725
7983         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
7984
7985         do_facet ost1 $LCTL set_param fail_loc=0
7986
7987         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
7988
7989         rm -f $DIR/$tfile || error "rm failed"
7990
7991         # Remount client to reset grant
7992         remount_client $MOUNT || error "failed to remount client"
7993         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
7994
7995         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
7996
7997         # define OBD_FAIL_TGT_NO_GRANT 0x725
7998         # make the server not grant more back
7999         do_facet ost1 $LCTL set_param fail_loc=0x725
8000         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8001         do_facet ost1 $LCTL set_param fail_loc=0
8002
8003         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8004 }
8005 run_test 64e "check grant consumption (no grant allocation)"
8006
8007 test_64f() {
8008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8009
8010         # Remount client to reset grant
8011         remount_client $MOUNT || error "failed to remount client"
8012         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8013
8014         local init_grants=$(import_param $osc_tgt initial_grant)
8015         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8016         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8017         local gbs=$(import_param $osc_tgt grant_block_size)
8018         local chunk=$(grant_chunk $osc_tgt)
8019
8020         # write random number of bytes from max_brw_size / 4 to max_brw_size
8021         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8022         # align for direct io
8023         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8024         # round to grant consumption unit
8025         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8026
8027         local grants=$((wb_round_up + extent_tax))
8028
8029         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8030         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8031                 error "error writing to $DIR/$tfile"
8032
8033         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8034                 "direct io with grant allocation"
8035
8036         rm -f $DIR/$tfile || error "rm failed"
8037
8038         # Remount client to reset grant
8039         remount_client $MOUNT || error "failed to remount client"
8040         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8041
8042         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8043
8044         local cmd="oO_WRONLY:w${write_bytes}_yc"
8045
8046         $MULTIOP $DIR/$tfile $cmd &
8047         MULTIPID=$!
8048         sleep 1
8049
8050         check_grants $osc_tgt $((init_grants - grants)) \
8051                 "buffered io, not write rpc"
8052
8053         kill -USR1 $MULTIPID
8054         wait
8055
8056         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8057                 "buffered io, one RPC"
8058 }
8059 run_test 64f "check grant consumption (with grant allocation)"
8060
8061 # bug 1414 - set/get directories' stripe info
8062 test_65a() {
8063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8064
8065         test_mkdir $DIR/$tdir
8066         touch $DIR/$tdir/f1
8067         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8068 }
8069 run_test 65a "directory with no stripe info"
8070
8071 test_65b() {
8072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8073
8074         test_mkdir $DIR/$tdir
8075         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8076
8077         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8078                                                 error "setstripe"
8079         touch $DIR/$tdir/f2
8080         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8081 }
8082 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8083
8084 test_65c() {
8085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8086         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8087
8088         test_mkdir $DIR/$tdir
8089         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8090
8091         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8092                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8093         touch $DIR/$tdir/f3
8094         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8095 }
8096 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8097
8098 test_65d() {
8099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8100
8101         test_mkdir $DIR/$tdir
8102         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8103         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8104
8105         if [[ $STRIPECOUNT -le 0 ]]; then
8106                 sc=1
8107         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8108                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8109                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8110         else
8111                 sc=$(($STRIPECOUNT - 1))
8112         fi
8113         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8114         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8115         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8116                 error "lverify failed"
8117 }
8118 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8119
8120 test_65e() {
8121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8122
8123         test_mkdir $DIR/$tdir
8124
8125         $LFS setstripe $DIR/$tdir || error "setstripe"
8126         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8127                                         error "no stripe info failed"
8128         touch $DIR/$tdir/f6
8129         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8130 }
8131 run_test 65e "directory setstripe defaults"
8132
8133 test_65f() {
8134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8135
8136         test_mkdir $DIR/${tdir}f
8137         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8138                 error "setstripe succeeded" || true
8139 }
8140 run_test 65f "dir setstripe permission (should return error) ==="
8141
8142 test_65g() {
8143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8144
8145         test_mkdir $DIR/$tdir
8146         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8147
8148         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8149                 error "setstripe -S failed"
8150         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8151         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8152                 error "delete default stripe failed"
8153 }
8154 run_test 65g "directory setstripe -d"
8155
8156 test_65h() {
8157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8158
8159         test_mkdir $DIR/$tdir
8160         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8161
8162         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8163                 error "setstripe -S failed"
8164         test_mkdir $DIR/$tdir/dd1
8165         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8166                 error "stripe info inherit failed"
8167 }
8168 run_test 65h "directory stripe info inherit ===================="
8169
8170 test_65i() {
8171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8172
8173         save_layout_restore_at_exit $MOUNT
8174
8175         # bug6367: set non-default striping on root directory
8176         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8177
8178         # bug12836: getstripe on -1 default directory striping
8179         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8180
8181         # bug12836: getstripe -v on -1 default directory striping
8182         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8183
8184         # bug12836: new find on -1 default directory striping
8185         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8186 }
8187 run_test 65i "various tests to set root directory striping"
8188
8189 test_65j() { # bug6367
8190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8191
8192         sync; sleep 1
8193
8194         # if we aren't already remounting for each test, do so for this test
8195         if [ "$I_MOUNTED" = "yes" ]; then
8196                 cleanup || error "failed to unmount"
8197                 setup
8198         fi
8199
8200         save_layout_restore_at_exit $MOUNT
8201
8202         $LFS setstripe -d $MOUNT || error "setstripe failed"
8203 }
8204 run_test 65j "set default striping on root directory (bug 6367)="
8205
8206 cleanup_65k() {
8207         rm -rf $DIR/$tdir
8208         wait_delete_completed
8209         do_facet $SINGLEMDS "lctl set_param -n \
8210                 osp.$ost*MDT0000.max_create_count=$max_count"
8211         do_facet $SINGLEMDS "lctl set_param -n \
8212                 osp.$ost*MDT0000.create_count=$count"
8213         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8214         echo $INACTIVE_OSC "is Activate"
8215
8216         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8217 }
8218
8219 test_65k() { # bug11679
8220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8221         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8222         remote_mds_nodsh && skip "remote MDS with nodsh"
8223
8224         local disable_precreate=true
8225         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8226                 disable_precreate=false
8227
8228         echo "Check OST status: "
8229         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8230                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8231
8232         for OSC in $MDS_OSCS; do
8233                 echo $OSC "is active"
8234                 do_facet $SINGLEMDS lctl --device %$OSC activate
8235         done
8236
8237         for INACTIVE_OSC in $MDS_OSCS; do
8238                 local ost=$(osc_to_ost $INACTIVE_OSC)
8239                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8240                                lov.*md*.target_obd |
8241                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8242
8243                 mkdir -p $DIR/$tdir
8244                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8245                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8246
8247                 echo "Deactivate: " $INACTIVE_OSC
8248                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8249
8250                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8251                               osp.$ost*MDT0000.create_count")
8252                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8253                                   osp.$ost*MDT0000.max_create_count")
8254                 $disable_precreate &&
8255                         do_facet $SINGLEMDS "lctl set_param -n \
8256                                 osp.$ost*MDT0000.max_create_count=0"
8257
8258                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8259                         [ -f $DIR/$tdir/$idx ] && continue
8260                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8261                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8262                                 { cleanup_65k;
8263                                   error "setstripe $idx should succeed"; }
8264                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8265                 done
8266                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8267                 rmdir $DIR/$tdir
8268
8269                 do_facet $SINGLEMDS "lctl set_param -n \
8270                         osp.$ost*MDT0000.max_create_count=$max_count"
8271                 do_facet $SINGLEMDS "lctl set_param -n \
8272                         osp.$ost*MDT0000.create_count=$count"
8273                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8274                 echo $INACTIVE_OSC "is Activate"
8275
8276                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8277         done
8278 }
8279 run_test 65k "validate manual striping works properly with deactivated OSCs"
8280
8281 test_65l() { # bug 12836
8282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8283
8284         test_mkdir -p $DIR/$tdir/test_dir
8285         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8286         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8287 }
8288 run_test 65l "lfs find on -1 stripe dir ========================"
8289
8290 test_65m() {
8291         local layout=$(save_layout $MOUNT)
8292         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8293                 restore_layout $MOUNT $layout
8294                 error "setstripe should fail by non-root users"
8295         }
8296         true
8297 }
8298 run_test 65m "normal user can't set filesystem default stripe"
8299
8300 test_65n() {
8301         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8302         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8303                 skip "Need MDS version at least 2.12.50"
8304         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8305
8306         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8307         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8308         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8309
8310         local root_layout=$(save_layout $MOUNT)
8311         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8312
8313         # new subdirectory under root directory should not inherit
8314         # the default layout from root
8315         local dir1=$MOUNT/$tdir-1
8316         mkdir $dir1 || error "mkdir $dir1 failed"
8317         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8318                 error "$dir1 shouldn't have LOV EA"
8319
8320         # delete the default layout on root directory
8321         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8322
8323         local dir2=$MOUNT/$tdir-2
8324         mkdir $dir2 || error "mkdir $dir2 failed"
8325         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8326                 error "$dir2 shouldn't have LOV EA"
8327
8328         # set a new striping pattern on root directory
8329         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8330         local new_def_stripe_size=$((def_stripe_size * 2))
8331         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8332                 error "set stripe size on $MOUNT failed"
8333
8334         # new file created in $dir2 should inherit the new stripe size from
8335         # the filesystem default
8336         local file2=$dir2/$tfile-2
8337         touch $file2 || error "touch $file2 failed"
8338
8339         local file2_stripe_size=$($LFS getstripe -S $file2)
8340         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8341                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8342
8343         local dir3=$MOUNT/$tdir-3
8344         mkdir $dir3 || error "mkdir $dir3 failed"
8345         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8346         # the root layout, which is the actual default layout that will be used
8347         # when new files are created in $dir3.
8348         local dir3_layout=$(get_layout_param $dir3)
8349         local root_dir_layout=$(get_layout_param $MOUNT)
8350         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8351                 error "$dir3 should show the default layout from $MOUNT"
8352
8353         # set OST pool on root directory
8354         local pool=$TESTNAME
8355         pool_add $pool || error "add $pool failed"
8356         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8357                 error "add targets to $pool failed"
8358
8359         $LFS setstripe -p $pool $MOUNT ||
8360                 error "set OST pool on $MOUNT failed"
8361
8362         # new file created in $dir3 should inherit the pool from
8363         # the filesystem default
8364         local file3=$dir3/$tfile-3
8365         touch $file3 || error "touch $file3 failed"
8366
8367         local file3_pool=$($LFS getstripe -p $file3)
8368         [[ "$file3_pool" = "$pool" ]] ||
8369                 error "$file3 didn't inherit OST pool $pool"
8370
8371         local dir4=$MOUNT/$tdir-4
8372         mkdir $dir4 || error "mkdir $dir4 failed"
8373         local dir4_layout=$(get_layout_param $dir4)
8374         root_dir_layout=$(get_layout_param $MOUNT)
8375         echo "$LFS getstripe -d $dir4"
8376         $LFS getstripe -d $dir4
8377         echo "$LFS getstripe -d $MOUNT"
8378         $LFS getstripe -d $MOUNT
8379         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8380                 error "$dir4 should show the default layout from $MOUNT"
8381
8382         # new file created in $dir4 should inherit the pool from
8383         # the filesystem default
8384         local file4=$dir4/$tfile-4
8385         touch $file4 || error "touch $file4 failed"
8386
8387         local file4_pool=$($LFS getstripe -p $file4)
8388         [[ "$file4_pool" = "$pool" ]] ||
8389                 error "$file4 didn't inherit OST pool $pool"
8390
8391         # new subdirectory under non-root directory should inherit
8392         # the default layout from its parent directory
8393         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8394                 error "set directory layout on $dir4 failed"
8395
8396         local dir5=$dir4/$tdir-5
8397         mkdir $dir5 || error "mkdir $dir5 failed"
8398
8399         dir4_layout=$(get_layout_param $dir4)
8400         local dir5_layout=$(get_layout_param $dir5)
8401         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8402                 error "$dir5 should inherit the default layout from $dir4"
8403
8404         # though subdir under ROOT doesn't inherit default layout, but
8405         # its sub dir/file should be created with default layout.
8406         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8407         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8408                 skip "Need MDS version at least 2.12.59"
8409
8410         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8411         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8412         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8413
8414         if [ $default_lmv_hash == "none" ]; then
8415                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8416         else
8417                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8418                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8419         fi
8420
8421         $LFS setdirstripe -D -c 2 $MOUNT ||
8422                 error "setdirstripe -D -c 2 failed"
8423         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8424         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8425         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8426 }
8427 run_test 65n "don't inherit default layout from root for new subdirectories"
8428
8429 # bug 2543 - update blocks count on client
8430 test_66() {
8431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8432
8433         COUNT=${COUNT:-8}
8434         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8435         sync; sync_all_data; sync; sync_all_data
8436         cancel_lru_locks osc
8437         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8438         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8439 }
8440 run_test 66 "update inode blocks count on client ==============="
8441
8442 meminfo() {
8443         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8444 }
8445
8446 swap_used() {
8447         swapon -s | awk '($1 == "'$1'") { print $4 }'
8448 }
8449
8450 # bug5265, obdfilter oa2dentry return -ENOENT
8451 # #define OBD_FAIL_SRV_ENOENT 0x217
8452 test_69() {
8453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8454         remote_ost_nodsh && skip "remote OST with nodsh"
8455
8456         f="$DIR/$tfile"
8457         $LFS setstripe -c 1 -i 0 $f
8458
8459         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8460
8461         do_facet ost1 lctl set_param fail_loc=0x217
8462         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8463         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8464
8465         do_facet ost1 lctl set_param fail_loc=0
8466         $DIRECTIO write $f 0 2 || error "write error"
8467
8468         cancel_lru_locks osc
8469         $DIRECTIO read $f 0 1 || error "read error"
8470
8471         do_facet ost1 lctl set_param fail_loc=0x217
8472         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8473
8474         do_facet ost1 lctl set_param fail_loc=0
8475         rm -f $f
8476 }
8477 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8478
8479 test_71() {
8480         test_mkdir $DIR/$tdir
8481         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8482         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8483 }
8484 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8485
8486 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8488         [ "$RUNAS_ID" = "$UID" ] &&
8489                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8490         # Check that testing environment is properly set up. Skip if not
8491         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8492                 skip_env "User $RUNAS_ID does not exist - skipping"
8493
8494         touch $DIR/$tfile
8495         chmod 777 $DIR/$tfile
8496         chmod ug+s $DIR/$tfile
8497         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8498                 error "$RUNAS dd $DIR/$tfile failed"
8499         # See if we are still setuid/sgid
8500         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8501                 error "S/gid is not dropped on write"
8502         # Now test that MDS is updated too
8503         cancel_lru_locks mdc
8504         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8505                 error "S/gid is not dropped on MDS"
8506         rm -f $DIR/$tfile
8507 }
8508 run_test 72a "Test that remove suid works properly (bug5695) ===="
8509
8510 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8511         local perm
8512
8513         [ "$RUNAS_ID" = "$UID" ] &&
8514                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8515         [ "$RUNAS_ID" -eq 0 ] &&
8516                 skip_env "RUNAS_ID = 0 -- skipping"
8517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8518         # Check that testing environment is properly set up. Skip if not
8519         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8520                 skip_env "User $RUNAS_ID does not exist - skipping"
8521
8522         touch $DIR/${tfile}-f{g,u}
8523         test_mkdir $DIR/${tfile}-dg
8524         test_mkdir $DIR/${tfile}-du
8525         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8526         chmod g+s $DIR/${tfile}-{f,d}g
8527         chmod u+s $DIR/${tfile}-{f,d}u
8528         for perm in 777 2777 4777; do
8529                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8530                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8531                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8532                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8533         done
8534         true
8535 }
8536 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8537
8538 # bug 3462 - multiple simultaneous MDC requests
8539 test_73() {
8540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8541
8542         test_mkdir $DIR/d73-1
8543         test_mkdir $DIR/d73-2
8544         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8545         pid1=$!
8546
8547         lctl set_param fail_loc=0x80000129
8548         $MULTIOP $DIR/d73-1/f73-2 Oc &
8549         sleep 1
8550         lctl set_param fail_loc=0
8551
8552         $MULTIOP $DIR/d73-2/f73-3 Oc &
8553         pid3=$!
8554
8555         kill -USR1 $pid1
8556         wait $pid1 || return 1
8557
8558         sleep 25
8559
8560         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8561         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8562         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8563
8564         rm -rf $DIR/d73-*
8565 }
8566 run_test 73 "multiple MDC requests (should not deadlock)"
8567
8568 test_74a() { # bug 6149, 6184
8569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8570
8571         touch $DIR/f74a
8572         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8573         #
8574         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8575         # will spin in a tight reconnection loop
8576         $LCTL set_param fail_loc=0x8000030e
8577         # get any lock that won't be difficult - lookup works.
8578         ls $DIR/f74a
8579         $LCTL set_param fail_loc=0
8580         rm -f $DIR/f74a
8581         true
8582 }
8583 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8584
8585 test_74b() { # bug 13310
8586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8587
8588         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8589         #
8590         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8591         # will spin in a tight reconnection loop
8592         $LCTL set_param fail_loc=0x8000030e
8593         # get a "difficult" lock
8594         touch $DIR/f74b
8595         $LCTL set_param fail_loc=0
8596         rm -f $DIR/f74b
8597         true
8598 }
8599 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8600
8601 test_74c() {
8602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8603
8604         #define OBD_FAIL_LDLM_NEW_LOCK
8605         $LCTL set_param fail_loc=0x319
8606         touch $DIR/$tfile && error "touch successful"
8607         $LCTL set_param fail_loc=0
8608         true
8609 }
8610 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8611
8612 num_inodes() {
8613         [ -f /sys/kernel/slab/lustre_inode_cache/shrink ] &&
8614                 echo 1 > /sys/kernel/slab/lustre_inode_cache/shrink
8615         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
8616 }
8617
8618 test_76() { # Now for bug 20433, added originally in bug 1443
8619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8620
8621         cancel_lru_locks osc
8622         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8623         local before=$(num_inodes)
8624         local count=$((512 * cpus))
8625         [ "$SLOW" = "no" ] && count=$((64 * cpus))
8626
8627         echo "before inodes: $before"
8628         for i in $(seq $count); do
8629                 touch $DIR/$tfile
8630                 rm -f $DIR/$tfile
8631         done
8632         cancel_lru_locks osc
8633         local after=$(num_inodes)
8634         echo "after inodes: $after"
8635         while (( after > before + 8 * ${cpus:-1} )); do
8636                 sleep 1
8637                 after=$(num_inodes)
8638                 wait=$((wait + 1))
8639                 (( wait % 5 == 0 )) && echo "wait $wait seconds inodes: $after"
8640                 if (( wait > 30 )); then
8641                         error "inode slab grew from $before to $after"
8642                 fi
8643         done
8644 }
8645 run_test 76 "confirm clients recycle inodes properly ===="
8646
8647
8648 export ORIG_CSUM=""
8649 set_checksums()
8650 {
8651         # Note: in sptlrpc modes which enable its own bulk checksum, the
8652         # original crc32_le bulk checksum will be automatically disabled,
8653         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8654         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8655         # In this case set_checksums() will not be no-op, because sptlrpc
8656         # bulk checksum will be enabled all through the test.
8657
8658         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8659         lctl set_param -n osc.*.checksums $1
8660         return 0
8661 }
8662
8663 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8664                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8665 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8666                              tr -d [] | head -n1)}
8667 set_checksum_type()
8668 {
8669         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8670         rc=$?
8671         log "set checksum type to $1, rc = $rc"
8672         return $rc
8673 }
8674
8675 get_osc_checksum_type()
8676 {
8677         # arugment 1: OST name, like OST0000
8678         ost=$1
8679         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8680                         sed 's/.*\[\(.*\)\].*/\1/g')
8681         rc=$?
8682         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8683         echo $checksum_type
8684 }
8685
8686 F77_TMP=$TMP/f77-temp
8687 F77SZ=8
8688 setup_f77() {
8689         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8690                 error "error writing to $F77_TMP"
8691 }
8692
8693 test_77a() { # bug 10889
8694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8695         $GSS && skip_env "could not run with gss"
8696
8697         [ ! -f $F77_TMP ] && setup_f77
8698         set_checksums 1
8699         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8700         set_checksums 0
8701         rm -f $DIR/$tfile
8702 }
8703 run_test 77a "normal checksum read/write operation"
8704
8705 test_77b() { # bug 10889
8706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8707         $GSS && skip_env "could not run with gss"
8708
8709         [ ! -f $F77_TMP ] && setup_f77
8710         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8711         $LCTL set_param fail_loc=0x80000409
8712         set_checksums 1
8713
8714         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8715                 error "dd error: $?"
8716         $LCTL set_param fail_loc=0
8717
8718         for algo in $CKSUM_TYPES; do
8719                 cancel_lru_locks osc
8720                 set_checksum_type $algo
8721                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8722                 $LCTL set_param fail_loc=0x80000408
8723                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8724                 $LCTL set_param fail_loc=0
8725         done
8726         set_checksums 0
8727         set_checksum_type $ORIG_CSUM_TYPE
8728         rm -f $DIR/$tfile
8729 }
8730 run_test 77b "checksum error on client write, read"
8731
8732 cleanup_77c() {
8733         trap 0
8734         set_checksums 0
8735         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8736         $check_ost &&
8737                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8738         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8739         $check_ost && [ -n "$ost_file_prefix" ] &&
8740                 do_facet ost1 rm -f ${ost_file_prefix}\*
8741 }
8742
8743 test_77c() {
8744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8745         $GSS && skip_env "could not run with gss"
8746         remote_ost_nodsh && skip "remote OST with nodsh"
8747
8748         local bad1
8749         local osc_file_prefix
8750         local osc_file
8751         local check_ost=false
8752         local ost_file_prefix
8753         local ost_file
8754         local orig_cksum
8755         local dump_cksum
8756         local fid
8757
8758         # ensure corruption will occur on first OSS/OST
8759         $LFS setstripe -i 0 $DIR/$tfile
8760
8761         [ ! -f $F77_TMP ] && setup_f77
8762         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8763                 error "dd write error: $?"
8764         fid=$($LFS path2fid $DIR/$tfile)
8765
8766         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8767         then
8768                 check_ost=true
8769                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8770                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8771         else
8772                 echo "OSS do not support bulk pages dump upon error"
8773         fi
8774
8775         osc_file_prefix=$($LCTL get_param -n debug_path)
8776         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8777
8778         trap cleanup_77c EXIT
8779
8780         set_checksums 1
8781         # enable bulk pages dump upon error on Client
8782         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8783         # enable bulk pages dump upon error on OSS
8784         $check_ost &&
8785                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8786
8787         # flush Client cache to allow next read to reach OSS
8788         cancel_lru_locks osc
8789
8790         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8791         $LCTL set_param fail_loc=0x80000408
8792         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8793         $LCTL set_param fail_loc=0
8794
8795         rm -f $DIR/$tfile
8796
8797         # check cksum dump on Client
8798         osc_file=$(ls ${osc_file_prefix}*)
8799         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8800         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8801         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8802         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8803         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8804                      cksum)
8805         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8806         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8807                 error "dump content does not match on Client"
8808
8809         $check_ost || skip "No need to check cksum dump on OSS"
8810
8811         # check cksum dump on OSS
8812         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8813         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8814         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8815         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8816         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8817                 error "dump content does not match on OSS"
8818
8819         cleanup_77c
8820 }
8821 run_test 77c "checksum error on client read with debug"
8822
8823 test_77d() { # bug 10889
8824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8825         $GSS && skip_env "could not run with gss"
8826
8827         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8828         $LCTL set_param fail_loc=0x80000409
8829         set_checksums 1
8830         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8831                 error "direct write: rc=$?"
8832         $LCTL set_param fail_loc=0
8833         set_checksums 0
8834
8835         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8836         $LCTL set_param fail_loc=0x80000408
8837         set_checksums 1
8838         cancel_lru_locks osc
8839         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8840                 error "direct read: rc=$?"
8841         $LCTL set_param fail_loc=0
8842         set_checksums 0
8843 }
8844 run_test 77d "checksum error on OST direct write, read"
8845
8846 test_77f() { # bug 10889
8847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8848         $GSS && skip_env "could not run with gss"
8849
8850         set_checksums 1
8851         for algo in $CKSUM_TYPES; do
8852                 cancel_lru_locks osc
8853                 set_checksum_type $algo
8854                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8855                 $LCTL set_param fail_loc=0x409
8856                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8857                         error "direct write succeeded"
8858                 $LCTL set_param fail_loc=0
8859         done
8860         set_checksum_type $ORIG_CSUM_TYPE
8861         set_checksums 0
8862 }
8863 run_test 77f "repeat checksum error on write (expect error)"
8864
8865 test_77g() { # bug 10889
8866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8867         $GSS && skip_env "could not run with gss"
8868         remote_ost_nodsh && skip "remote OST with nodsh"
8869
8870         [ ! -f $F77_TMP ] && setup_f77
8871
8872         local file=$DIR/$tfile
8873         stack_trap "rm -f $file" EXIT
8874
8875         $LFS setstripe -c 1 -i 0 $file
8876         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8877         do_facet ost1 lctl set_param fail_loc=0x8000021a
8878         set_checksums 1
8879         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8880                 error "write error: rc=$?"
8881         do_facet ost1 lctl set_param fail_loc=0
8882         set_checksums 0
8883
8884         cancel_lru_locks osc
8885         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8886         do_facet ost1 lctl set_param fail_loc=0x8000021b
8887         set_checksums 1
8888         cmp $F77_TMP $file || error "file compare failed"
8889         do_facet ost1 lctl set_param fail_loc=0
8890         set_checksums 0
8891 }
8892 run_test 77g "checksum error on OST write, read"
8893
8894 test_77k() { # LU-10906
8895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8896         $GSS && skip_env "could not run with gss"
8897
8898         local cksum_param="osc.$FSNAME*.checksums"
8899         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8900         local checksum
8901         local i
8902
8903         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8904         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
8905         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
8906
8907         for i in 0 1; do
8908                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8909                         error "failed to set checksum=$i on MGS"
8910                 wait_update $HOSTNAME "$get_checksum" $i
8911                 #remount
8912                 echo "remount client, checksum should be $i"
8913                 remount_client $MOUNT || error "failed to remount client"
8914                 checksum=$(eval $get_checksum)
8915                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8916         done
8917         # remove persistent param to avoid races with checksum mountopt below
8918         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8919                 error "failed to delete checksum on MGS"
8920
8921         for opt in "checksum" "nochecksum"; do
8922                 #remount with mount option
8923                 echo "remount client with option $opt, checksum should be $i"
8924                 umount_client $MOUNT || error "failed to umount client"
8925                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8926                         error "failed to mount client with option '$opt'"
8927                 checksum=$(eval $get_checksum)
8928                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8929                 i=$((i - 1))
8930         done
8931
8932         remount_client $MOUNT || error "failed to remount client"
8933 }
8934 run_test 77k "enable/disable checksum correctly"
8935
8936 test_77l() {
8937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8938         $GSS && skip_env "could not run with gss"
8939
8940         set_checksums 1
8941         stack_trap "set_checksums $ORIG_CSUM" EXIT
8942         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8943
8944         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8945
8946         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8947         for algo in $CKSUM_TYPES; do
8948                 set_checksum_type $algo || error "fail to set checksum type $algo"
8949                 osc_algo=$(get_osc_checksum_type OST0000)
8950                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8951
8952                 # no locks, no reqs to let the connection idle
8953                 cancel_lru_locks osc
8954                 lru_resize_disable osc
8955                 wait_osc_import_state client ost1 IDLE
8956
8957                 # ensure ost1 is connected
8958                 stat $DIR/$tfile >/dev/null || error "can't stat"
8959                 wait_osc_import_state client ost1 FULL
8960
8961                 osc_algo=$(get_osc_checksum_type OST0000)
8962                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8963         done
8964         return 0
8965 }
8966 run_test 77l "preferred checksum type is remembered after reconnected"
8967
8968 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8969 rm -f $F77_TMP
8970 unset F77_TMP
8971
8972 cleanup_test_78() {
8973         trap 0
8974         rm -f $DIR/$tfile
8975 }
8976
8977 test_78() { # bug 10901
8978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8979         remote_ost || skip_env "local OST"
8980
8981         NSEQ=5
8982         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8983         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8984         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8985         echo "MemTotal: $MEMTOTAL"
8986
8987         # reserve 256MB of memory for the kernel and other running processes,
8988         # and then take 1/2 of the remaining memory for the read/write buffers.
8989         if [ $MEMTOTAL -gt 512 ] ;then
8990                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8991         else
8992                 # for those poor memory-starved high-end clusters...
8993                 MEMTOTAL=$((MEMTOTAL / 2))
8994         fi
8995         echo "Mem to use for directio: $MEMTOTAL"
8996
8997         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8998         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8999         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9000         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9001                 head -n1)
9002         echo "Smallest OST: $SMALLESTOST"
9003         [[ $SMALLESTOST -lt 10240 ]] &&
9004                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9005
9006         trap cleanup_test_78 EXIT
9007
9008         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9009                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9010
9011         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9012         echo "File size: $F78SIZE"
9013         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9014         for i in $(seq 1 $NSEQ); do
9015                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9016                 echo directIO rdwr round $i of $NSEQ
9017                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9018         done
9019
9020         cleanup_test_78
9021 }
9022 run_test 78 "handle large O_DIRECT writes correctly ============"
9023
9024 test_79() { # bug 12743
9025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9026
9027         wait_delete_completed
9028
9029         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9030         BKFREE=$(calc_osc_kbytes kbytesfree)
9031         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9032
9033         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9034         DFTOTAL=`echo $STRING | cut -d, -f1`
9035         DFUSED=`echo $STRING  | cut -d, -f2`
9036         DFAVAIL=`echo $STRING | cut -d, -f3`
9037         DFFREE=$(($DFTOTAL - $DFUSED))
9038
9039         ALLOWANCE=$((64 * $OSTCOUNT))
9040
9041         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9042            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9043                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9044         fi
9045         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9046            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9047                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9048         fi
9049         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9050            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9051                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9052         fi
9053 }
9054 run_test 79 "df report consistency check ======================="
9055
9056 test_80() { # bug 10718
9057         remote_ost_nodsh && skip "remote OST with nodsh"
9058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9059
9060         # relax strong synchronous semantics for slow backends like ZFS
9061         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9062                 local soc="obdfilter.*.sync_lock_cancel"
9063                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9064
9065                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9066                 if [ -z "$save" ]; then
9067                         soc="obdfilter.*.sync_on_lock_cancel"
9068                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9069                 fi
9070
9071                 if [ "$save" != "never" ]; then
9072                         local hosts=$(comma_list $(osts_nodes))
9073
9074                         do_nodes $hosts $LCTL set_param $soc=never
9075                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9076                 fi
9077         fi
9078
9079         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9080         sync; sleep 1; sync
9081         local before=$(date +%s)
9082         cancel_lru_locks osc
9083         local after=$(date +%s)
9084         local diff=$((after - before))
9085         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9086
9087         rm -f $DIR/$tfile
9088 }
9089 run_test 80 "Page eviction is equally fast at high offsets too"
9090
9091 test_81a() { # LU-456
9092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9093         remote_ost_nodsh && skip "remote OST with nodsh"
9094
9095         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9096         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9097         do_facet ost1 lctl set_param fail_loc=0x80000228
9098
9099         # write should trigger a retry and success
9100         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9101         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9102         RC=$?
9103         if [ $RC -ne 0 ] ; then
9104                 error "write should success, but failed for $RC"
9105         fi
9106 }
9107 run_test 81a "OST should retry write when get -ENOSPC ==============="
9108
9109 test_81b() { # LU-456
9110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9111         remote_ost_nodsh && skip "remote OST with nodsh"
9112
9113         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9114         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9115         do_facet ost1 lctl set_param fail_loc=0x228
9116
9117         # write should retry several times and return -ENOSPC finally
9118         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9119         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9120         RC=$?
9121         ENOSPC=28
9122         if [ $RC -ne $ENOSPC ] ; then
9123                 error "dd should fail for -ENOSPC, but succeed."
9124         fi
9125 }
9126 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9127
9128 test_99() {
9129         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9130
9131         test_mkdir $DIR/$tdir.cvsroot
9132         chown $RUNAS_ID $DIR/$tdir.cvsroot
9133
9134         cd $TMP
9135         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9136
9137         cd /etc/init.d
9138         # some versions of cvs import exit(1) when asked to import links or
9139         # files they can't read.  ignore those files.
9140         local toignore=$(find . -type l -printf '-I %f\n' -o \
9141                          ! -perm /4 -printf '-I %f\n')
9142         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9143                 $tdir.reposname vtag rtag
9144
9145         cd $DIR
9146         test_mkdir $DIR/$tdir.reposname
9147         chown $RUNAS_ID $DIR/$tdir.reposname
9148         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9149
9150         cd $DIR/$tdir.reposname
9151         $RUNAS touch foo99
9152         $RUNAS cvs add -m 'addmsg' foo99
9153         $RUNAS cvs update
9154         $RUNAS cvs commit -m 'nomsg' foo99
9155         rm -fr $DIR/$tdir.cvsroot
9156 }
9157 run_test 99 "cvs strange file/directory operations"
9158
9159 test_100() {
9160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9161         [[ "$NETTYPE" =~ tcp ]] ||
9162                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9163         remote_ost_nodsh && skip "remote OST with nodsh"
9164         remote_mds_nodsh && skip "remote MDS with nodsh"
9165         remote_servers ||
9166                 skip "useless for local single node setup"
9167
9168         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9169                 [ "$PROT" != "tcp" ] && continue
9170                 RPORT=$(echo $REMOTE | cut -d: -f2)
9171                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9172
9173                 rc=0
9174                 LPORT=`echo $LOCAL | cut -d: -f2`
9175                 if [ $LPORT -ge 1024 ]; then
9176                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9177                         netstat -tna
9178                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9179                 fi
9180         done
9181         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9182 }
9183 run_test 100 "check local port using privileged port ==========="
9184
9185 function get_named_value()
9186 {
9187     local tag
9188
9189     tag=$1
9190     while read ;do
9191         line=$REPLY
9192         case $line in
9193         $tag*)
9194             echo $line | sed "s/^$tag[ ]*//"
9195             break
9196             ;;
9197         esac
9198     done
9199 }
9200
9201 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9202                    awk '/^max_cached_mb/ { print $2 }')
9203
9204 cleanup_101a() {
9205         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9206         trap 0
9207 }
9208
9209 test_101a() {
9210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9211
9212         local s
9213         local discard
9214         local nreads=10000
9215         local cache_limit=32
9216
9217         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9218         trap cleanup_101a EXIT
9219         $LCTL set_param -n llite.*.read_ahead_stats 0
9220         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9221
9222         #
9223         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9224         #
9225         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9226         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9227
9228         discard=0
9229         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9230                 get_named_value 'read but discarded' | cut -d" " -f1); do
9231                         discard=$(($discard + $s))
9232         done
9233         cleanup_101a
9234
9235         $LCTL get_param osc.*-osc*.rpc_stats
9236         $LCTL get_param llite.*.read_ahead_stats
9237
9238         # Discard is generally zero, but sometimes a few random reads line up
9239         # and trigger larger readahead, which is wasted & leads to discards.
9240         if [[ $(($discard)) -gt $nreads ]]; then
9241                 error "too many ($discard) discarded pages"
9242         fi
9243         rm -f $DIR/$tfile || true
9244 }
9245 run_test 101a "check read-ahead for random reads"
9246
9247 setup_test101bc() {
9248         test_mkdir $DIR/$tdir
9249         local ssize=$1
9250         local FILE_LENGTH=$2
9251         STRIPE_OFFSET=0
9252
9253         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9254
9255         local list=$(comma_list $(osts_nodes))
9256         set_osd_param $list '' read_cache_enable 0
9257         set_osd_param $list '' writethrough_cache_enable 0
9258
9259         trap cleanup_test101bc EXIT
9260         # prepare the read-ahead file
9261         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9262
9263         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9264                                 count=$FILE_SIZE_MB 2> /dev/null
9265
9266 }
9267
9268 cleanup_test101bc() {
9269         trap 0
9270         rm -rf $DIR/$tdir
9271         rm -f $DIR/$tfile
9272
9273         local list=$(comma_list $(osts_nodes))
9274         set_osd_param $list '' read_cache_enable 1
9275         set_osd_param $list '' writethrough_cache_enable 1
9276 }
9277
9278 calc_total() {
9279         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9280 }
9281
9282 ra_check_101() {
9283         local READ_SIZE=$1
9284         local STRIPE_SIZE=$2
9285         local FILE_LENGTH=$3
9286         local RA_INC=1048576
9287         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9288         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9289                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9290         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9291                         get_named_value 'read but discarded' |
9292                         cut -d" " -f1 | calc_total)
9293         if [[ $DISCARD -gt $discard_limit ]]; then
9294                 $LCTL get_param llite.*.read_ahead_stats
9295                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9296         else
9297                 echo "Read-ahead success for size ${READ_SIZE}"
9298         fi
9299 }
9300
9301 test_101b() {
9302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9303         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9304
9305         local STRIPE_SIZE=1048576
9306         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9307
9308         if [ $SLOW == "yes" ]; then
9309                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9310         else
9311                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9312         fi
9313
9314         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9315
9316         # prepare the read-ahead file
9317         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9318         cancel_lru_locks osc
9319         for BIDX in 2 4 8 16 32 64 128 256
9320         do
9321                 local BSIZE=$((BIDX*4096))
9322                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9323                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9324                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9325                 $LCTL set_param -n llite.*.read_ahead_stats 0
9326                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9327                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9328                 cancel_lru_locks osc
9329                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9330         done
9331         cleanup_test101bc
9332         true
9333 }
9334 run_test 101b "check stride-io mode read-ahead ================="
9335
9336 test_101c() {
9337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9338
9339         local STRIPE_SIZE=1048576
9340         local FILE_LENGTH=$((STRIPE_SIZE*100))
9341         local nreads=10000
9342         local rsize=65536
9343         local osc_rpc_stats
9344
9345         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9346
9347         cancel_lru_locks osc
9348         $LCTL set_param osc.*.rpc_stats 0
9349         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9350         $LCTL get_param osc.*.rpc_stats
9351         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9352                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9353                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9354                 local size
9355
9356                 if [ $lines -le 20 ]; then
9357                         echo "continue debug"
9358                         continue
9359                 fi
9360                 for size in 1 2 4 8; do
9361                         local rpc=$(echo "$stats" |
9362                                     awk '($1 == "'$size':") {print $2; exit; }')
9363                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9364                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9365                 done
9366                 echo "$osc_rpc_stats check passed!"
9367         done
9368         cleanup_test101bc
9369         true
9370 }
9371 run_test 101c "check stripe_size aligned read-ahead ================="
9372
9373 test_101d() {
9374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9375
9376         local file=$DIR/$tfile
9377         local sz_MB=${FILESIZE_101d:-80}
9378         local ra_MB=${READAHEAD_MB:-40}
9379
9380         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9381         [ $free_MB -lt $sz_MB ] &&
9382                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9383
9384         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9385         $LFS setstripe -c -1 $file || error "setstripe failed"
9386
9387         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9388         echo Cancel LRU locks on lustre client to flush the client cache
9389         cancel_lru_locks osc
9390
9391         echo Disable read-ahead
9392         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9393         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9394         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9395         $LCTL get_param -n llite.*.max_read_ahead_mb
9396
9397         echo "Reading the test file $file with read-ahead disabled"
9398         local sz_KB=$((sz_MB * 1024 / 4))
9399         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9400         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9401         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9402                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9403
9404         echo "Cancel LRU locks on lustre client to flush the client cache"
9405         cancel_lru_locks osc
9406         echo Enable read-ahead with ${ra_MB}MB
9407         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9408
9409         echo "Reading the test file $file with read-ahead enabled"
9410         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9411                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9412
9413         echo "read-ahead disabled time read $raOFF"
9414         echo "read-ahead enabled time read $raON"
9415
9416         rm -f $file
9417         wait_delete_completed
9418
9419         # use awk for this check instead of bash because it handles decimals
9420         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9421                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9422 }
9423 run_test 101d "file read with and without read-ahead enabled"
9424
9425 test_101e() {
9426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9427
9428         local file=$DIR/$tfile
9429         local size_KB=500  #KB
9430         local count=100
9431         local bsize=1024
9432
9433         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9434         local need_KB=$((count * size_KB))
9435         [[ $free_KB -le $need_KB ]] &&
9436                 skip_env "Need free space $need_KB, have $free_KB"
9437
9438         echo "Creating $count ${size_KB}K test files"
9439         for ((i = 0; i < $count; i++)); do
9440                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9441         done
9442
9443         echo "Cancel LRU locks on lustre client to flush the client cache"
9444         cancel_lru_locks $OSC
9445
9446         echo "Reset readahead stats"
9447         $LCTL set_param -n llite.*.read_ahead_stats 0
9448
9449         for ((i = 0; i < $count; i++)); do
9450                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9451         done
9452
9453         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9454                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9455
9456         for ((i = 0; i < $count; i++)); do
9457                 rm -rf $file.$i 2>/dev/null
9458         done
9459
9460         #10000 means 20% reads are missing in readahead
9461         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9462 }
9463 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9464
9465 test_101f() {
9466         which iozone || skip_env "no iozone installed"
9467
9468         local old_debug=$($LCTL get_param debug)
9469         old_debug=${old_debug#*=}
9470         $LCTL set_param debug="reada mmap"
9471
9472         # create a test file
9473         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9474
9475         echo Cancel LRU locks on lustre client to flush the client cache
9476         cancel_lru_locks osc
9477
9478         echo Reset readahead stats
9479         $LCTL set_param -n llite.*.read_ahead_stats 0
9480
9481         echo mmap read the file with small block size
9482         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9483                 > /dev/null 2>&1
9484
9485         echo checking missing pages
9486         $LCTL get_param llite.*.read_ahead_stats
9487         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9488                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9489
9490         $LCTL set_param debug="$old_debug"
9491         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9492         rm -f $DIR/$tfile
9493 }
9494 run_test 101f "check mmap read performance"
9495
9496 test_101g_brw_size_test() {
9497         local mb=$1
9498         local pages=$((mb * 1048576 / PAGE_SIZE))
9499         local file=$DIR/$tfile
9500
9501         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9502                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9503         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9504                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9505                         return 2
9506         done
9507
9508         stack_trap "rm -f $file" EXIT
9509         $LCTL set_param -n osc.*.rpc_stats=0
9510
9511         # 10 RPCs should be enough for the test
9512         local count=10
9513         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9514                 { error "dd write ${mb} MB blocks failed"; return 3; }
9515         cancel_lru_locks osc
9516         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9517                 { error "dd write ${mb} MB blocks failed"; return 4; }
9518
9519         # calculate number of full-sized read and write RPCs
9520         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9521                 sed -n '/pages per rpc/,/^$/p' |
9522                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9523                 END { print reads,writes }'))
9524         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
9525                 return 5
9526         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
9527                 return 6
9528
9529         return 0
9530 }
9531
9532 test_101g() {
9533         remote_ost_nodsh && skip "remote OST with nodsh"
9534
9535         local rpcs
9536         local osts=$(get_facets OST)
9537         local list=$(comma_list $(osts_nodes))
9538         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9539         local brw_size="obdfilter.*.brw_size"
9540
9541         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9542
9543         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9544
9545         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9546                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9547                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9548            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9549                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9550                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9551
9552                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9553                         suffix="M"
9554
9555                 if [[ $orig_mb -lt 16 ]]; then
9556                         save_lustre_params $osts "$brw_size" > $p
9557                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9558                                 error "set 16MB RPC size failed"
9559
9560                         echo "remount client to enable new RPC size"
9561                         remount_client $MOUNT || error "remount_client failed"
9562                 fi
9563
9564                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9565                 # should be able to set brw_size=12, but no rpc_stats for that
9566                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9567         fi
9568
9569         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9570
9571         if [[ $orig_mb -lt 16 ]]; then
9572                 restore_lustre_params < $p
9573                 remount_client $MOUNT || error "remount_client restore failed"
9574         fi
9575
9576         rm -f $p $DIR/$tfile
9577 }
9578 run_test 101g "Big bulk(4/16 MiB) readahead"
9579
9580 test_101h() {
9581         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9582
9583         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9584                 error "dd 70M file failed"
9585         echo Cancel LRU locks on lustre client to flush the client cache
9586         cancel_lru_locks osc
9587
9588         echo "Reset readahead stats"
9589         $LCTL set_param -n llite.*.read_ahead_stats 0
9590
9591         echo "Read 10M of data but cross 64M bundary"
9592         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9593         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9594                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9595         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9596         rm -f $p $DIR/$tfile
9597 }
9598 run_test 101h "Readahead should cover current read window"
9599
9600 test_101i() {
9601         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9602                 error "dd 10M file failed"
9603
9604         local max_per_file_mb=$($LCTL get_param -n \
9605                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9606         cancel_lru_locks osc
9607         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9608         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9609                 error "set max_read_ahead_per_file_mb to 1 failed"
9610
9611         echo "Reset readahead stats"
9612         $LCTL set_param llite.*.read_ahead_stats=0
9613
9614         dd if=$DIR/$tfile of=/dev/null bs=2M
9615
9616         $LCTL get_param llite.*.read_ahead_stats
9617         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9618                      awk '/misses/ { print $2 }')
9619         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9620         rm -f $DIR/$tfile
9621 }
9622 run_test 101i "allow current readahead to exceed reservation"
9623
9624 test_101j() {
9625         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9626                 error "setstripe $DIR/$tfile failed"
9627         local file_size=$((1048576 * 16))
9628         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9629         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9630
9631         echo Disable read-ahead
9632         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9633
9634         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9635         for blk in $PAGE_SIZE 1048576 $file_size; do
9636                 cancel_lru_locks osc
9637                 echo "Reset readahead stats"
9638                 $LCTL set_param -n llite.*.read_ahead_stats=0
9639                 local count=$(($file_size / $blk))
9640                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9641                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9642                              get_named_value 'failed to fast read' |
9643                              cut -d" " -f1 | calc_total)
9644                 $LCTL get_param -n llite.*.read_ahead_stats
9645                 [ $miss -eq $count ] || error "expected $count got $miss"
9646         done
9647
9648         rm -f $p $DIR/$tfile
9649 }
9650 run_test 101j "A complete read block should be submitted when no RA"
9651
9652 setup_test102() {
9653         test_mkdir $DIR/$tdir
9654         chown $RUNAS_ID $DIR/$tdir
9655         STRIPE_SIZE=65536
9656         STRIPE_OFFSET=1
9657         STRIPE_COUNT=$OSTCOUNT
9658         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9659
9660         trap cleanup_test102 EXIT
9661         cd $DIR
9662         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9663         cd $DIR/$tdir
9664         for num in 1 2 3 4; do
9665                 for count in $(seq 1 $STRIPE_COUNT); do
9666                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9667                                 local size=`expr $STRIPE_SIZE \* $num`
9668                                 local file=file"$num-$idx-$count"
9669                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9670                         done
9671                 done
9672         done
9673
9674         cd $DIR
9675         $1 tar cf $TMP/f102.tar $tdir --xattrs
9676 }
9677
9678 cleanup_test102() {
9679         trap 0
9680         rm -f $TMP/f102.tar
9681         rm -rf $DIR/d0.sanity/d102
9682 }
9683
9684 test_102a() {
9685         [ "$UID" != 0 ] && skip "must run as root"
9686         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9687                 skip_env "must have user_xattr"
9688
9689         [ -z "$(which setfattr 2>/dev/null)" ] &&
9690                 skip_env "could not find setfattr"
9691
9692         local testfile=$DIR/$tfile
9693
9694         touch $testfile
9695         echo "set/get xattr..."
9696         setfattr -n trusted.name1 -v value1 $testfile ||
9697                 error "setfattr -n trusted.name1=value1 $testfile failed"
9698         getfattr -n trusted.name1 $testfile 2> /dev/null |
9699           grep "trusted.name1=.value1" ||
9700                 error "$testfile missing trusted.name1=value1"
9701
9702         setfattr -n user.author1 -v author1 $testfile ||
9703                 error "setfattr -n user.author1=author1 $testfile failed"
9704         getfattr -n user.author1 $testfile 2> /dev/null |
9705           grep "user.author1=.author1" ||
9706                 error "$testfile missing trusted.author1=author1"
9707
9708         echo "listxattr..."
9709         setfattr -n trusted.name2 -v value2 $testfile ||
9710                 error "$testfile unable to set trusted.name2"
9711         setfattr -n trusted.name3 -v value3 $testfile ||
9712                 error "$testfile unable to set trusted.name3"
9713         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9714             grep "trusted.name" | wc -l) -eq 3 ] ||
9715                 error "$testfile missing 3 trusted.name xattrs"
9716
9717         setfattr -n user.author2 -v author2 $testfile ||
9718                 error "$testfile unable to set user.author2"
9719         setfattr -n user.author3 -v author3 $testfile ||
9720                 error "$testfile unable to set user.author3"
9721         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9722             grep "user.author" | wc -l) -eq 3 ] ||
9723                 error "$testfile missing 3 user.author xattrs"
9724
9725         echo "remove xattr..."
9726         setfattr -x trusted.name1 $testfile ||
9727                 error "$testfile error deleting trusted.name1"
9728         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9729                 error "$testfile did not delete trusted.name1 xattr"
9730
9731         setfattr -x user.author1 $testfile ||
9732                 error "$testfile error deleting user.author1"
9733         echo "set lustre special xattr ..."
9734         $LFS setstripe -c1 $testfile
9735         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9736                 awk -F "=" '/trusted.lov/ { print $2 }' )
9737         setfattr -n "trusted.lov" -v $lovea $testfile ||
9738                 error "$testfile doesn't ignore setting trusted.lov again"
9739         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9740                 error "$testfile allow setting invalid trusted.lov"
9741         rm -f $testfile
9742 }
9743 run_test 102a "user xattr test =================================="
9744
9745 check_102b_layout() {
9746         local layout="$*"
9747         local testfile=$DIR/$tfile
9748
9749         echo "test layout '$layout'"
9750         $LFS setstripe $layout $testfile || error "setstripe failed"
9751         $LFS getstripe -y $testfile
9752
9753         echo "get/set/list trusted.lov xattr ..." # b=10930
9754         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9755         [[ "$value" =~ "trusted.lov" ]] ||
9756                 error "can't get trusted.lov from $testfile"
9757         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9758                 error "getstripe failed"
9759
9760         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9761
9762         value=$(cut -d= -f2 <<<$value)
9763         # LU-13168: truncated xattr should fail if short lov_user_md header
9764         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9765                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9766         for len in $lens; do
9767                 echo "setfattr $len $testfile.2"
9768                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9769                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9770         done
9771         local stripe_size=$($LFS getstripe -S $testfile.2)
9772         local stripe_count=$($LFS getstripe -c $testfile.2)
9773         [[ $stripe_size -eq 65536 ]] ||
9774                 error "stripe size $stripe_size != 65536"
9775         [[ $stripe_count -eq $stripe_count_orig ]] ||
9776                 error "stripe count $stripe_count != $stripe_count_orig"
9777         rm $testfile $testfile.2
9778 }
9779
9780 test_102b() {
9781         [ -z "$(which setfattr 2>/dev/null)" ] &&
9782                 skip_env "could not find setfattr"
9783         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9784
9785         # check plain layout
9786         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9787
9788         # and also check composite layout
9789         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9790
9791 }
9792 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9793
9794 test_102c() {
9795         [ -z "$(which setfattr 2>/dev/null)" ] &&
9796                 skip_env "could not find setfattr"
9797         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9798
9799         # b10930: get/set/list lustre.lov xattr
9800         echo "get/set/list lustre.lov xattr ..."
9801         test_mkdir $DIR/$tdir
9802         chown $RUNAS_ID $DIR/$tdir
9803         local testfile=$DIR/$tdir/$tfile
9804         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9805                 error "setstripe failed"
9806         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9807                 error "getstripe failed"
9808         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9809         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9810
9811         local testfile2=${testfile}2
9812         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9813                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9814
9815         $RUNAS $MCREATE $testfile2
9816         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9817         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9818         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9819         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9820         [ $stripe_count -eq $STRIPECOUNT ] ||
9821                 error "stripe count $stripe_count != $STRIPECOUNT"
9822 }
9823 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9824
9825 compare_stripe_info1() {
9826         local stripe_index_all_zero=true
9827
9828         for num in 1 2 3 4; do
9829                 for count in $(seq 1 $STRIPE_COUNT); do
9830                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9831                                 local size=$((STRIPE_SIZE * num))
9832                                 local file=file"$num-$offset-$count"
9833                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9834                                 [[ $stripe_size -ne $size ]] &&
9835                                     error "$file: size $stripe_size != $size"
9836                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9837                                 # allow fewer stripes to be created, ORI-601
9838                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9839                                     error "$file: count $stripe_count != $count"
9840                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9841                                 [[ $stripe_index -ne 0 ]] &&
9842                                         stripe_index_all_zero=false
9843                         done
9844                 done
9845         done
9846         $stripe_index_all_zero &&
9847                 error "all files are being extracted starting from OST index 0"
9848         return 0
9849 }
9850
9851 have_xattrs_include() {
9852         tar --help | grep -q xattrs-include &&
9853                 echo --xattrs-include="lustre.*"
9854 }
9855
9856 test_102d() {
9857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9858         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9859
9860         XINC=$(have_xattrs_include)
9861         setup_test102
9862         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9863         cd $DIR/$tdir/$tdir
9864         compare_stripe_info1
9865 }
9866 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9867
9868 test_102f() {
9869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9870         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9871
9872         XINC=$(have_xattrs_include)
9873         setup_test102
9874         test_mkdir $DIR/$tdir.restore
9875         cd $DIR
9876         tar cf - --xattrs $tdir | tar xf - \
9877                 -C $DIR/$tdir.restore --xattrs $XINC
9878         cd $DIR/$tdir.restore/$tdir
9879         compare_stripe_info1
9880 }
9881 run_test 102f "tar copy files, not keep osts"
9882
9883 grow_xattr() {
9884         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9885                 skip "must have user_xattr"
9886         [ -z "$(which setfattr 2>/dev/null)" ] &&
9887                 skip_env "could not find setfattr"
9888         [ -z "$(which getfattr 2>/dev/null)" ] &&
9889                 skip_env "could not find getfattr"
9890
9891         local xsize=${1:-1024}  # in bytes
9892         local file=$DIR/$tfile
9893         local value="$(generate_string $xsize)"
9894         local xbig=trusted.big
9895         local toobig=$2
9896
9897         touch $file
9898         log "save $xbig on $file"
9899         if [ -z "$toobig" ]
9900         then
9901                 setfattr -n $xbig -v $value $file ||
9902                         error "saving $xbig on $file failed"
9903         else
9904                 setfattr -n $xbig -v $value $file &&
9905                         error "saving $xbig on $file succeeded"
9906                 return 0
9907         fi
9908
9909         local orig=$(get_xattr_value $xbig $file)
9910         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9911
9912         local xsml=trusted.sml
9913         log "save $xsml on $file"
9914         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9915
9916         local new=$(get_xattr_value $xbig $file)
9917         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9918
9919         log "grow $xsml on $file"
9920         setfattr -n $xsml -v "$value" $file ||
9921                 error "growing $xsml on $file failed"
9922
9923         new=$(get_xattr_value $xbig $file)
9924         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9925         log "$xbig still valid after growing $xsml"
9926
9927         rm -f $file
9928 }
9929
9930 test_102h() { # bug 15777
9931         grow_xattr 1024
9932 }
9933 run_test 102h "grow xattr from inside inode to external block"
9934
9935 test_102ha() {
9936         large_xattr_enabled || skip_env "ea_inode feature disabled"
9937
9938         echo "setting xattr of max xattr size: $(max_xattr_size)"
9939         grow_xattr $(max_xattr_size)
9940
9941         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9942         echo "This should fail:"
9943         grow_xattr $(($(max_xattr_size) + 10)) 1
9944 }
9945 run_test 102ha "grow xattr from inside inode to external inode"
9946
9947 test_102i() { # bug 17038
9948         [ -z "$(which getfattr 2>/dev/null)" ] &&
9949                 skip "could not find getfattr"
9950
9951         touch $DIR/$tfile
9952         ln -s $DIR/$tfile $DIR/${tfile}link
9953         getfattr -n trusted.lov $DIR/$tfile ||
9954                 error "lgetxattr on $DIR/$tfile failed"
9955         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9956                 grep -i "no such attr" ||
9957                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9958         rm -f $DIR/$tfile $DIR/${tfile}link
9959 }
9960 run_test 102i "lgetxattr test on symbolic link ============"
9961
9962 test_102j() {
9963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9964         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9965
9966         XINC=$(have_xattrs_include)
9967         setup_test102 "$RUNAS"
9968         chown $RUNAS_ID $DIR/$tdir
9969         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9970         cd $DIR/$tdir/$tdir
9971         compare_stripe_info1 "$RUNAS"
9972 }
9973 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9974
9975 test_102k() {
9976         [ -z "$(which setfattr 2>/dev/null)" ] &&
9977                 skip "could not find setfattr"
9978
9979         touch $DIR/$tfile
9980         # b22187 just check that does not crash for regular file.
9981         setfattr -n trusted.lov $DIR/$tfile
9982         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9983         local test_kdir=$DIR/$tdir
9984         test_mkdir $test_kdir
9985         local default_size=$($LFS getstripe -S $test_kdir)
9986         local default_count=$($LFS getstripe -c $test_kdir)
9987         local default_offset=$($LFS getstripe -i $test_kdir)
9988         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
9989                 error 'dir setstripe failed'
9990         setfattr -n trusted.lov $test_kdir
9991         local stripe_size=$($LFS getstripe -S $test_kdir)
9992         local stripe_count=$($LFS getstripe -c $test_kdir)
9993         local stripe_offset=$($LFS getstripe -i $test_kdir)
9994         [ $stripe_size -eq $default_size ] ||
9995                 error "stripe size $stripe_size != $default_size"
9996         [ $stripe_count -eq $default_count ] ||
9997                 error "stripe count $stripe_count != $default_count"
9998         [ $stripe_offset -eq $default_offset ] ||
9999                 error "stripe offset $stripe_offset != $default_offset"
10000         rm -rf $DIR/$tfile $test_kdir
10001 }
10002 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10003
10004 test_102l() {
10005         [ -z "$(which getfattr 2>/dev/null)" ] &&
10006                 skip "could not find getfattr"
10007
10008         # LU-532 trusted. xattr is invisible to non-root
10009         local testfile=$DIR/$tfile
10010
10011         touch $testfile
10012
10013         echo "listxattr as user..."
10014         chown $RUNAS_ID $testfile
10015         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10016             grep -q "trusted" &&
10017                 error "$testfile trusted xattrs are user visible"
10018
10019         return 0;
10020 }
10021 run_test 102l "listxattr size test =================================="
10022
10023 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10024         local path=$DIR/$tfile
10025         touch $path
10026
10027         listxattr_size_check $path || error "listattr_size_check $path failed"
10028 }
10029 run_test 102m "Ensure listxattr fails on small bufffer ========"
10030
10031 cleanup_test102
10032
10033 getxattr() { # getxattr path name
10034         # Return the base64 encoding of the value of xattr name on path.
10035         local path=$1
10036         local name=$2
10037
10038         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10039         # file: $path
10040         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10041         #
10042         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10043
10044         getfattr --absolute-names --encoding=base64 --name=$name $path |
10045                 awk -F= -v name=$name '$1 == name {
10046                         print substr($0, index($0, "=") + 1);
10047         }'
10048 }
10049
10050 test_102n() { # LU-4101 mdt: protect internal xattrs
10051         [ -z "$(which setfattr 2>/dev/null)" ] &&
10052                 skip "could not find setfattr"
10053         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10054         then
10055                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10056         fi
10057
10058         local file0=$DIR/$tfile.0
10059         local file1=$DIR/$tfile.1
10060         local xattr0=$TMP/$tfile.0
10061         local xattr1=$TMP/$tfile.1
10062         local namelist="lov lma lmv link fid version som hsm"
10063         local name
10064         local value
10065
10066         rm -rf $file0 $file1 $xattr0 $xattr1
10067         touch $file0 $file1
10068
10069         # Get 'before' xattrs of $file1.
10070         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10071
10072         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10073                 namelist+=" lfsck_namespace"
10074         for name in $namelist; do
10075                 # Try to copy xattr from $file0 to $file1.
10076                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10077
10078                 setfattr --name=trusted.$name --value="$value" $file1 ||
10079                         error "setxattr 'trusted.$name' failed"
10080
10081                 # Try to set a garbage xattr.
10082                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10083
10084                 if [[ x$name == "xlov" ]]; then
10085                         setfattr --name=trusted.lov --value="$value" $file1 &&
10086                         error "setxattr invalid 'trusted.lov' success"
10087                 else
10088                         setfattr --name=trusted.$name --value="$value" $file1 ||
10089                                 error "setxattr invalid 'trusted.$name' failed"
10090                 fi
10091
10092                 # Try to remove the xattr from $file1. We don't care if this
10093                 # appears to succeed or fail, we just don't want there to be
10094                 # any changes or crashes.
10095                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10096         done
10097
10098         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10099         then
10100                 name="lfsck_ns"
10101                 # Try to copy xattr from $file0 to $file1.
10102                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10103
10104                 setfattr --name=trusted.$name --value="$value" $file1 ||
10105                         error "setxattr 'trusted.$name' failed"
10106
10107                 # Try to set a garbage xattr.
10108                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10109
10110                 setfattr --name=trusted.$name --value="$value" $file1 ||
10111                         error "setxattr 'trusted.$name' failed"
10112
10113                 # Try to remove the xattr from $file1. We don't care if this
10114                 # appears to succeed or fail, we just don't want there to be
10115                 # any changes or crashes.
10116                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10117         fi
10118
10119         # Get 'after' xattrs of file1.
10120         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10121
10122         if ! diff $xattr0 $xattr1; then
10123                 error "before and after xattrs of '$file1' differ"
10124         fi
10125
10126         rm -rf $file0 $file1 $xattr0 $xattr1
10127
10128         return 0
10129 }
10130 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10131
10132 test_102p() { # LU-4703 setxattr did not check ownership
10133         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10134                 skip "MDS needs to be at least 2.5.56"
10135
10136         local testfile=$DIR/$tfile
10137
10138         touch $testfile
10139
10140         echo "setfacl as user..."
10141         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10142         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10143
10144         echo "setfattr as user..."
10145         setfacl -m "u:$RUNAS_ID:---" $testfile
10146         $RUNAS setfattr -x system.posix_acl_access $testfile
10147         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10148 }
10149 run_test 102p "check setxattr(2) correctly fails without permission"
10150
10151 test_102q() {
10152         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10153                 skip "MDS needs to be at least 2.6.92"
10154
10155         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10156 }
10157 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10158
10159 test_102r() {
10160         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10161                 skip "MDS needs to be at least 2.6.93"
10162
10163         touch $DIR/$tfile || error "touch"
10164         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10165         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10166         rm $DIR/$tfile || error "rm"
10167
10168         #normal directory
10169         mkdir -p $DIR/$tdir || error "mkdir"
10170         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10171         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10172         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10173                 error "$testfile error deleting user.author1"
10174         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10175                 grep "user.$(basename $tdir)" &&
10176                 error "$tdir did not delete user.$(basename $tdir)"
10177         rmdir $DIR/$tdir || error "rmdir"
10178
10179         #striped directory
10180         test_mkdir $DIR/$tdir
10181         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10182         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10183         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10184                 error "$testfile error deleting user.author1"
10185         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10186                 grep "user.$(basename $tdir)" &&
10187                 error "$tdir did not delete user.$(basename $tdir)"
10188         rmdir $DIR/$tdir || error "rm striped dir"
10189 }
10190 run_test 102r "set EAs with empty values"
10191
10192 test_102s() {
10193         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10194                 skip "MDS needs to be at least 2.11.52"
10195
10196         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10197
10198         save_lustre_params client "llite.*.xattr_cache" > $save
10199
10200         for cache in 0 1; do
10201                 lctl set_param llite.*.xattr_cache=$cache
10202
10203                 rm -f $DIR/$tfile
10204                 touch $DIR/$tfile || error "touch"
10205                 for prefix in lustre security system trusted user; do
10206                         # Note getxattr() may fail with 'Operation not
10207                         # supported' or 'No such attribute' depending
10208                         # on prefix and cache.
10209                         getfattr -n $prefix.n102s $DIR/$tfile &&
10210                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10211                 done
10212         done
10213
10214         restore_lustre_params < $save
10215 }
10216 run_test 102s "getting nonexistent xattrs should fail"
10217
10218 test_102t() {
10219         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10220                 skip "MDS needs to be at least 2.11.52"
10221
10222         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10223
10224         save_lustre_params client "llite.*.xattr_cache" > $save
10225
10226         for cache in 0 1; do
10227                 lctl set_param llite.*.xattr_cache=$cache
10228
10229                 for buf_size in 0 256; do
10230                         rm -f $DIR/$tfile
10231                         touch $DIR/$tfile || error "touch"
10232                         setfattr -n user.multiop $DIR/$tfile
10233                         $MULTIOP $DIR/$tfile oa$buf_size ||
10234                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10235                 done
10236         done
10237
10238         restore_lustre_params < $save
10239 }
10240 run_test 102t "zero length xattr values handled correctly"
10241
10242 run_acl_subtest()
10243 {
10244     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10245     return $?
10246 }
10247
10248 test_103a() {
10249         [ "$UID" != 0 ] && skip "must run as root"
10250         $GSS && skip_env "could not run under gss"
10251         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10252                 skip_env "must have acl enabled"
10253         [ -z "$(which setfacl 2>/dev/null)" ] &&
10254                 skip_env "could not find setfacl"
10255         remote_mds_nodsh && skip "remote MDS with nodsh"
10256
10257         gpasswd -a daemon bin                           # LU-5641
10258         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10259
10260         declare -a identity_old
10261
10262         for num in $(seq $MDSCOUNT); do
10263                 switch_identity $num true || identity_old[$num]=$?
10264         done
10265
10266         SAVE_UMASK=$(umask)
10267         umask 0022
10268         mkdir -p $DIR/$tdir
10269         cd $DIR/$tdir
10270
10271         echo "performing cp ..."
10272         run_acl_subtest cp || error "run_acl_subtest cp failed"
10273         echo "performing getfacl-noacl..."
10274         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10275         echo "performing misc..."
10276         run_acl_subtest misc || error  "misc test failed"
10277         echo "performing permissions..."
10278         run_acl_subtest permissions || error "permissions failed"
10279         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10280         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10281                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10282                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10283         then
10284                 echo "performing permissions xattr..."
10285                 run_acl_subtest permissions_xattr ||
10286                         error "permissions_xattr failed"
10287         fi
10288         echo "performing setfacl..."
10289         run_acl_subtest setfacl || error  "setfacl test failed"
10290
10291         # inheritance test got from HP
10292         echo "performing inheritance..."
10293         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10294         chmod +x make-tree || error "chmod +x failed"
10295         run_acl_subtest inheritance || error "inheritance test failed"
10296         rm -f make-tree
10297
10298         echo "LU-974 ignore umask when acl is enabled..."
10299         run_acl_subtest 974 || error "LU-974 umask test failed"
10300         if [ $MDSCOUNT -ge 2 ]; then
10301                 run_acl_subtest 974_remote ||
10302                         error "LU-974 umask test failed under remote dir"
10303         fi
10304
10305         echo "LU-2561 newly created file is same size as directory..."
10306         if [ "$mds1_FSTYPE" != "zfs" ]; then
10307                 run_acl_subtest 2561 || error "LU-2561 test failed"
10308         else
10309                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10310         fi
10311
10312         run_acl_subtest 4924 || error "LU-4924 test failed"
10313
10314         cd $SAVE_PWD
10315         umask $SAVE_UMASK
10316
10317         for num in $(seq $MDSCOUNT); do
10318                 if [ "${identity_old[$num]}" = 1 ]; then
10319                         switch_identity $num false || identity_old[$num]=$?
10320                 fi
10321         done
10322 }
10323 run_test 103a "acl test"
10324
10325 test_103b() {
10326         declare -a pids
10327         local U
10328
10329         for U in {0..511}; do
10330                 {
10331                 local O=$(printf "%04o" $U)
10332
10333                 umask $(printf "%04o" $((511 ^ $O)))
10334                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10335                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10336
10337                 (( $S == ($O & 0666) )) ||
10338                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10339
10340                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10341                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10342                 (( $S == ($O & 0666) )) ||
10343                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10344
10345                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10346                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10347                 (( $S == ($O & 0666) )) ||
10348                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10349                 rm -f $DIR/$tfile.[smp]$0
10350                 } &
10351                 local pid=$!
10352
10353                 # limit the concurrently running threads to 64. LU-11878
10354                 local idx=$((U % 64))
10355                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10356                 pids[idx]=$pid
10357         done
10358         wait
10359 }
10360 run_test 103b "umask lfs setstripe"
10361
10362 test_103c() {
10363         mkdir -p $DIR/$tdir
10364         cp -rp $DIR/$tdir $DIR/$tdir.bak
10365
10366         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10367                 error "$DIR/$tdir shouldn't contain default ACL"
10368         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10369                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10370         true
10371 }
10372 run_test 103c "'cp -rp' won't set empty acl"
10373
10374 test_104a() {
10375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10376
10377         touch $DIR/$tfile
10378         lfs df || error "lfs df failed"
10379         lfs df -ih || error "lfs df -ih failed"
10380         lfs df -h $DIR || error "lfs df -h $DIR failed"
10381         lfs df -i $DIR || error "lfs df -i $DIR failed"
10382         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10383         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10384
10385         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10386         lctl --device %$OSC deactivate
10387         lfs df || error "lfs df with deactivated OSC failed"
10388         lctl --device %$OSC activate
10389         # wait the osc back to normal
10390         wait_osc_import_ready client ost
10391
10392         lfs df || error "lfs df with reactivated OSC failed"
10393         rm -f $DIR/$tfile
10394 }
10395 run_test 104a "lfs df [-ih] [path] test ========================="
10396
10397 test_104b() {
10398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10399         [ $RUNAS_ID -eq $UID ] &&
10400                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10401
10402         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10403                         grep "Permission denied" | wc -l)))
10404         if [ $denied_cnt -ne 0 ]; then
10405                 error "lfs check servers test failed"
10406         fi
10407 }
10408 run_test 104b "$RUNAS lfs check servers test ===================="
10409
10410 test_105a() {
10411         # doesn't work on 2.4 kernels
10412         touch $DIR/$tfile
10413         if $(flock_is_enabled); then
10414                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10415         else
10416                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10417         fi
10418         rm -f $DIR/$tfile
10419 }
10420 run_test 105a "flock when mounted without -o flock test ========"
10421
10422 test_105b() {
10423         touch $DIR/$tfile
10424         if $(flock_is_enabled); then
10425                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10426         else
10427                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10428         fi
10429         rm -f $DIR/$tfile
10430 }
10431 run_test 105b "fcntl when mounted without -o flock test ========"
10432
10433 test_105c() {
10434         touch $DIR/$tfile
10435         if $(flock_is_enabled); then
10436                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10437         else
10438                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10439         fi
10440         rm -f $DIR/$tfile
10441 }
10442 run_test 105c "lockf when mounted without -o flock test"
10443
10444 test_105d() { # bug 15924
10445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10446
10447         test_mkdir $DIR/$tdir
10448         flock_is_enabled || skip_env "mount w/o flock enabled"
10449         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10450         $LCTL set_param fail_loc=0x80000315
10451         flocks_test 2 $DIR/$tdir
10452 }
10453 run_test 105d "flock race (should not freeze) ========"
10454
10455 test_105e() { # bug 22660 && 22040
10456         flock_is_enabled || skip_env "mount w/o flock enabled"
10457
10458         touch $DIR/$tfile
10459         flocks_test 3 $DIR/$tfile
10460 }
10461 run_test 105e "Two conflicting flocks from same process"
10462
10463 test_106() { #bug 10921
10464         test_mkdir $DIR/$tdir
10465         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10466         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10467 }
10468 run_test 106 "attempt exec of dir followed by chown of that dir"
10469
10470 test_107() {
10471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10472
10473         CDIR=`pwd`
10474         local file=core
10475
10476         cd $DIR
10477         rm -f $file
10478
10479         local save_pattern=$(sysctl -n kernel.core_pattern)
10480         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10481         sysctl -w kernel.core_pattern=$file
10482         sysctl -w kernel.core_uses_pid=0
10483
10484         ulimit -c unlimited
10485         sleep 60 &
10486         SLEEPPID=$!
10487
10488         sleep 1
10489
10490         kill -s 11 $SLEEPPID
10491         wait $SLEEPPID
10492         if [ -e $file ]; then
10493                 size=`stat -c%s $file`
10494                 [ $size -eq 0 ] && error "Fail to create core file $file"
10495         else
10496                 error "Fail to create core file $file"
10497         fi
10498         rm -f $file
10499         sysctl -w kernel.core_pattern=$save_pattern
10500         sysctl -w kernel.core_uses_pid=$save_uses_pid
10501         cd $CDIR
10502 }
10503 run_test 107 "Coredump on SIG"
10504
10505 test_110() {
10506         test_mkdir $DIR/$tdir
10507         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10508         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10509                 error "mkdir with 256 char should fail, but did not"
10510         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10511                 error "create with 255 char failed"
10512         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10513                 error "create with 256 char should fail, but did not"
10514
10515         ls -l $DIR/$tdir
10516         rm -rf $DIR/$tdir
10517 }
10518 run_test 110 "filename length checking"
10519
10520 #
10521 # Purpose: To verify dynamic thread (OSS) creation.
10522 #
10523 test_115() {
10524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10525         remote_ost_nodsh && skip "remote OST with nodsh"
10526
10527         # Lustre does not stop service threads once they are started.
10528         # Reset number of running threads to default.
10529         stopall
10530         setupall
10531
10532         local OSTIO_pre
10533         local save_params="$TMP/sanity-$TESTNAME.parameters"
10534
10535         # Get ll_ost_io count before I/O
10536         OSTIO_pre=$(do_facet ost1 \
10537                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10538         # Exit if lustre is not running (ll_ost_io not running).
10539         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10540
10541         echo "Starting with $OSTIO_pre threads"
10542         local thread_max=$((OSTIO_pre * 2))
10543         local rpc_in_flight=$((thread_max * 2))
10544         # Number of I/O Process proposed to be started.
10545         local nfiles
10546         local facets=$(get_facets OST)
10547
10548         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10549         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10550
10551         # Set in_flight to $rpc_in_flight
10552         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10553                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10554         nfiles=${rpc_in_flight}
10555         # Set ost thread_max to $thread_max
10556         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10557
10558         # 5 Minutes should be sufficient for max number of OSS
10559         # threads(thread_max) to be created.
10560         local timeout=300
10561
10562         # Start I/O.
10563         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10564         test_mkdir $DIR/$tdir
10565         for i in $(seq $nfiles); do
10566                 local file=$DIR/$tdir/${tfile}-$i
10567                 $LFS setstripe -c -1 -i 0 $file
10568                 ($WTL $file $timeout)&
10569         done
10570
10571         # I/O Started - Wait for thread_started to reach thread_max or report
10572         # error if thread_started is more than thread_max.
10573         echo "Waiting for thread_started to reach thread_max"
10574         local thread_started=0
10575         local end_time=$((SECONDS + timeout))
10576
10577         while [ $SECONDS -le $end_time ] ; do
10578                 echo -n "."
10579                 # Get ost i/o thread_started count.
10580                 thread_started=$(do_facet ost1 \
10581                         "$LCTL get_param \
10582                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10583                 # Break out if thread_started is equal/greater than thread_max
10584                 if [[ $thread_started -ge $thread_max ]]; then
10585                         echo ll_ost_io thread_started $thread_started, \
10586                                 equal/greater than thread_max $thread_max
10587                         break
10588                 fi
10589                 sleep 1
10590         done
10591
10592         # Cleanup - We have the numbers, Kill i/o jobs if running.
10593         jobcount=($(jobs -p))
10594         for i in $(seq 0 $((${#jobcount[@]}-1)))
10595         do
10596                 kill -9 ${jobcount[$i]}
10597                 if [ $? -ne 0 ] ; then
10598                         echo Warning: \
10599                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10600                 fi
10601         done
10602
10603         # Cleanup files left by WTL binary.
10604         for i in $(seq $nfiles); do
10605                 local file=$DIR/$tdir/${tfile}-$i
10606                 rm -rf $file
10607                 if [ $? -ne 0 ] ; then
10608                         echo "Warning: Failed to delete file $file"
10609                 fi
10610         done
10611
10612         restore_lustre_params <$save_params
10613         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10614
10615         # Error out if no new thread has started or Thread started is greater
10616         # than thread max.
10617         if [[ $thread_started -le $OSTIO_pre ||
10618                         $thread_started -gt $thread_max ]]; then
10619                 error "ll_ost_io: thread_started $thread_started" \
10620                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10621                       "No new thread started or thread started greater " \
10622                       "than thread_max."
10623         fi
10624 }
10625 run_test 115 "verify dynamic thread creation===================="
10626
10627 free_min_max () {
10628         wait_delete_completed
10629         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10630         echo "OST kbytes available: ${AVAIL[@]}"
10631         MAXV=${AVAIL[0]}
10632         MAXI=0
10633         MINV=${AVAIL[0]}
10634         MINI=0
10635         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10636                 #echo OST $i: ${AVAIL[i]}kb
10637                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10638                         MAXV=${AVAIL[i]}
10639                         MAXI=$i
10640                 fi
10641                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10642                         MINV=${AVAIL[i]}
10643                         MINI=$i
10644                 fi
10645         done
10646         echo "Min free space: OST $MINI: $MINV"
10647         echo "Max free space: OST $MAXI: $MAXV"
10648 }
10649
10650 test_116a() { # was previously test_116()
10651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10652         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10653         remote_mds_nodsh && skip "remote MDS with nodsh"
10654
10655         echo -n "Free space priority "
10656         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10657                 head -n1
10658         declare -a AVAIL
10659         free_min_max
10660
10661         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10662         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10663         trap simple_cleanup_common EXIT
10664
10665         # Check if we need to generate uneven OSTs
10666         test_mkdir -p $DIR/$tdir/OST${MINI}
10667         local FILL=$((MINV / 4))
10668         local DIFF=$((MAXV - MINV))
10669         local DIFF2=$((DIFF * 100 / MINV))
10670
10671         local threshold=$(do_facet $SINGLEMDS \
10672                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10673         threshold=${threshold%%%}
10674         echo -n "Check for uneven OSTs: "
10675         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10676
10677         if [[ $DIFF2 -gt $threshold ]]; then
10678                 echo "ok"
10679                 echo "Don't need to fill OST$MINI"
10680         else
10681                 # generate uneven OSTs. Write 2% over the QOS threshold value
10682                 echo "no"
10683                 DIFF=$((threshold - DIFF2 + 2))
10684                 DIFF2=$((MINV * DIFF / 100))
10685                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10686                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10687                         error "setstripe failed"
10688                 DIFF=$((DIFF2 / 2048))
10689                 i=0
10690                 while [ $i -lt $DIFF ]; do
10691                         i=$((i + 1))
10692                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10693                                 bs=2M count=1 2>/dev/null
10694                         echo -n .
10695                 done
10696                 echo .
10697                 sync
10698                 sleep_maxage
10699                 free_min_max
10700         fi
10701
10702         DIFF=$((MAXV - MINV))
10703         DIFF2=$((DIFF * 100 / MINV))
10704         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10705         if [ $DIFF2 -gt $threshold ]; then
10706                 echo "ok"
10707         else
10708                 echo "failed - QOS mode won't be used"
10709                 simple_cleanup_common
10710                 skip "QOS imbalance criteria not met"
10711         fi
10712
10713         MINI1=$MINI
10714         MINV1=$MINV
10715         MAXI1=$MAXI
10716         MAXV1=$MAXV
10717
10718         # now fill using QOS
10719         $LFS setstripe -c 1 $DIR/$tdir
10720         FILL=$((FILL / 200))
10721         if [ $FILL -gt 600 ]; then
10722                 FILL=600
10723         fi
10724         echo "writing $FILL files to QOS-assigned OSTs"
10725         i=0
10726         while [ $i -lt $FILL ]; do
10727                 i=$((i + 1))
10728                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10729                         count=1 2>/dev/null
10730                 echo -n .
10731         done
10732         echo "wrote $i 200k files"
10733         sync
10734         sleep_maxage
10735
10736         echo "Note: free space may not be updated, so measurements might be off"
10737         free_min_max
10738         DIFF2=$((MAXV - MINV))
10739         echo "free space delta: orig $DIFF final $DIFF2"
10740         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10741         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10742         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10743         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10744         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10745         if [[ $DIFF -gt 0 ]]; then
10746                 FILL=$((DIFF2 * 100 / DIFF - 100))
10747                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10748         fi
10749
10750         # Figure out which files were written where
10751         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10752                awk '/'$MINI1': / {print $2; exit}')
10753         echo $UUID
10754         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10755         echo "$MINC files created on smaller OST $MINI1"
10756         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10757                awk '/'$MAXI1': / {print $2; exit}')
10758         echo $UUID
10759         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10760         echo "$MAXC files created on larger OST $MAXI1"
10761         if [[ $MINC -gt 0 ]]; then
10762                 FILL=$((MAXC * 100 / MINC - 100))
10763                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10764         fi
10765         [[ $MAXC -gt $MINC ]] ||
10766                 error_ignore LU-9 "stripe QOS didn't balance free space"
10767         simple_cleanup_common
10768 }
10769 run_test 116a "stripe QOS: free space balance ==================="
10770
10771 test_116b() { # LU-2093
10772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10773         remote_mds_nodsh && skip "remote MDS with nodsh"
10774
10775 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10776         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10777                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10778         [ -z "$old_rr" ] && skip "no QOS"
10779         do_facet $SINGLEMDS lctl set_param \
10780                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10781         mkdir -p $DIR/$tdir
10782         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10783         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10784         do_facet $SINGLEMDS lctl set_param fail_loc=0
10785         rm -rf $DIR/$tdir
10786         do_facet $SINGLEMDS lctl set_param \
10787                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10788 }
10789 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10790
10791 test_117() # bug 10891
10792 {
10793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10794
10795         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10796         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10797         lctl set_param fail_loc=0x21e
10798         > $DIR/$tfile || error "truncate failed"
10799         lctl set_param fail_loc=0
10800         echo "Truncate succeeded."
10801         rm -f $DIR/$tfile
10802 }
10803 run_test 117 "verify osd extend =========="
10804
10805 NO_SLOW_RESENDCOUNT=4
10806 export OLD_RESENDCOUNT=""
10807 set_resend_count () {
10808         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10809         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10810         lctl set_param -n $PROC_RESENDCOUNT $1
10811         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10812 }
10813
10814 # for reduce test_118* time (b=14842)
10815 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10816
10817 # Reset async IO behavior after error case
10818 reset_async() {
10819         FILE=$DIR/reset_async
10820
10821         # Ensure all OSCs are cleared
10822         $LFS setstripe -c -1 $FILE
10823         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10824         sync
10825         rm $FILE
10826 }
10827
10828 test_118a() #bug 11710
10829 {
10830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10831
10832         reset_async
10833
10834         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10835         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10836         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10837
10838         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10839                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10840                 return 1;
10841         fi
10842         rm -f $DIR/$tfile
10843 }
10844 run_test 118a "verify O_SYNC works =========="
10845
10846 test_118b()
10847 {
10848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10849         remote_ost_nodsh && skip "remote OST with nodsh"
10850
10851         reset_async
10852
10853         #define OBD_FAIL_SRV_ENOENT 0x217
10854         set_nodes_failloc "$(osts_nodes)" 0x217
10855         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10856         RC=$?
10857         set_nodes_failloc "$(osts_nodes)" 0
10858         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10859         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10860                     grep -c writeback)
10861
10862         if [[ $RC -eq 0 ]]; then
10863                 error "Must return error due to dropped pages, rc=$RC"
10864                 return 1;
10865         fi
10866
10867         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10868                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10869                 return 1;
10870         fi
10871
10872         echo "Dirty pages not leaked on ENOENT"
10873
10874         # Due to the above error the OSC will issue all RPCs syncronously
10875         # until a subsequent RPC completes successfully without error.
10876         $MULTIOP $DIR/$tfile Ow4096yc
10877         rm -f $DIR/$tfile
10878
10879         return 0
10880 }
10881 run_test 118b "Reclaim dirty pages on fatal error =========="
10882
10883 test_118c()
10884 {
10885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10886
10887         # for 118c, restore the original resend count, LU-1940
10888         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10889                                 set_resend_count $OLD_RESENDCOUNT
10890         remote_ost_nodsh && skip "remote OST with nodsh"
10891
10892         reset_async
10893
10894         #define OBD_FAIL_OST_EROFS               0x216
10895         set_nodes_failloc "$(osts_nodes)" 0x216
10896
10897         # multiop should block due to fsync until pages are written
10898         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10899         MULTIPID=$!
10900         sleep 1
10901
10902         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10903                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10904         fi
10905
10906         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10907                     grep -c writeback)
10908         if [[ $WRITEBACK -eq 0 ]]; then
10909                 error "No page in writeback, writeback=$WRITEBACK"
10910         fi
10911
10912         set_nodes_failloc "$(osts_nodes)" 0
10913         wait $MULTIPID
10914         RC=$?
10915         if [[ $RC -ne 0 ]]; then
10916                 error "Multiop fsync failed, rc=$RC"
10917         fi
10918
10919         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10920         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10921                     grep -c writeback)
10922         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10923                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10924         fi
10925
10926         rm -f $DIR/$tfile
10927         echo "Dirty pages flushed via fsync on EROFS"
10928         return 0
10929 }
10930 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10931
10932 # continue to use small resend count to reduce test_118* time (b=14842)
10933 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10934
10935 test_118d()
10936 {
10937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10938         remote_ost_nodsh && skip "remote OST with nodsh"
10939
10940         reset_async
10941
10942         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10943         set_nodes_failloc "$(osts_nodes)" 0x214
10944         # multiop should block due to fsync until pages are written
10945         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10946         MULTIPID=$!
10947         sleep 1
10948
10949         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10950                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10951         fi
10952
10953         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10954                     grep -c writeback)
10955         if [[ $WRITEBACK -eq 0 ]]; then
10956                 error "No page in writeback, writeback=$WRITEBACK"
10957         fi
10958
10959         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10960         set_nodes_failloc "$(osts_nodes)" 0
10961
10962         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10963         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10964                     grep -c writeback)
10965         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10966                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10967         fi
10968
10969         rm -f $DIR/$tfile
10970         echo "Dirty pages gaurenteed flushed via fsync"
10971         return 0
10972 }
10973 run_test 118d "Fsync validation inject a delay of the bulk =========="
10974
10975 test_118f() {
10976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10977
10978         reset_async
10979
10980         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10981         lctl set_param fail_loc=0x8000040a
10982
10983         # Should simulate EINVAL error which is fatal
10984         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10985         RC=$?
10986         if [[ $RC -eq 0 ]]; then
10987                 error "Must return error due to dropped pages, rc=$RC"
10988         fi
10989
10990         lctl set_param fail_loc=0x0
10991
10992         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10993         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10994         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10995                     grep -c writeback)
10996         if [[ $LOCKED -ne 0 ]]; then
10997                 error "Locked pages remain in cache, locked=$LOCKED"
10998         fi
10999
11000         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11001                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11002         fi
11003
11004         rm -f $DIR/$tfile
11005         echo "No pages locked after fsync"
11006
11007         reset_async
11008         return 0
11009 }
11010 run_test 118f "Simulate unrecoverable OSC side error =========="
11011
11012 test_118g() {
11013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11014
11015         reset_async
11016
11017         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11018         lctl set_param fail_loc=0x406
11019
11020         # simulate local -ENOMEM
11021         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11022         RC=$?
11023
11024         lctl set_param fail_loc=0
11025         if [[ $RC -eq 0 ]]; then
11026                 error "Must return error due to dropped pages, rc=$RC"
11027         fi
11028
11029         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11030         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11031         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11032                         grep -c writeback)
11033         if [[ $LOCKED -ne 0 ]]; then
11034                 error "Locked pages remain in cache, locked=$LOCKED"
11035         fi
11036
11037         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11038                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11039         fi
11040
11041         rm -f $DIR/$tfile
11042         echo "No pages locked after fsync"
11043
11044         reset_async
11045         return 0
11046 }
11047 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11048
11049 test_118h() {
11050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11051         remote_ost_nodsh && skip "remote OST with nodsh"
11052
11053         reset_async
11054
11055         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11056         set_nodes_failloc "$(osts_nodes)" 0x20e
11057         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11058         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11059         RC=$?
11060
11061         set_nodes_failloc "$(osts_nodes)" 0
11062         if [[ $RC -eq 0 ]]; then
11063                 error "Must return error due to dropped pages, rc=$RC"
11064         fi
11065
11066         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11067         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11068         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11069                     grep -c writeback)
11070         if [[ $LOCKED -ne 0 ]]; then
11071                 error "Locked pages remain in cache, locked=$LOCKED"
11072         fi
11073
11074         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11075                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11076         fi
11077
11078         rm -f $DIR/$tfile
11079         echo "No pages locked after fsync"
11080
11081         return 0
11082 }
11083 run_test 118h "Verify timeout in handling recoverables errors  =========="
11084
11085 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11086
11087 test_118i() {
11088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11089         remote_ost_nodsh && skip "remote OST with nodsh"
11090
11091         reset_async
11092
11093         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11094         set_nodes_failloc "$(osts_nodes)" 0x20e
11095
11096         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11097         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11098         PID=$!
11099         sleep 5
11100         set_nodes_failloc "$(osts_nodes)" 0
11101
11102         wait $PID
11103         RC=$?
11104         if [[ $RC -ne 0 ]]; then
11105                 error "got error, but should be not, rc=$RC"
11106         fi
11107
11108         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11109         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11110         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11111         if [[ $LOCKED -ne 0 ]]; then
11112                 error "Locked pages remain in cache, locked=$LOCKED"
11113         fi
11114
11115         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11116                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11117         fi
11118
11119         rm -f $DIR/$tfile
11120         echo "No pages locked after fsync"
11121
11122         return 0
11123 }
11124 run_test 118i "Fix error before timeout in recoverable error  =========="
11125
11126 [ "$SLOW" = "no" ] && set_resend_count 4
11127
11128 test_118j() {
11129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11130         remote_ost_nodsh && skip "remote OST with nodsh"
11131
11132         reset_async
11133
11134         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11135         set_nodes_failloc "$(osts_nodes)" 0x220
11136
11137         # return -EIO from OST
11138         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11139         RC=$?
11140         set_nodes_failloc "$(osts_nodes)" 0x0
11141         if [[ $RC -eq 0 ]]; then
11142                 error "Must return error due to dropped pages, rc=$RC"
11143         fi
11144
11145         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11146         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11147         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11148         if [[ $LOCKED -ne 0 ]]; then
11149                 error "Locked pages remain in cache, locked=$LOCKED"
11150         fi
11151
11152         # in recoverable error on OST we want resend and stay until it finished
11153         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11154                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11155         fi
11156
11157         rm -f $DIR/$tfile
11158         echo "No pages locked after fsync"
11159
11160         return 0
11161 }
11162 run_test 118j "Simulate unrecoverable OST side error =========="
11163
11164 test_118k()
11165 {
11166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11167         remote_ost_nodsh && skip "remote OSTs with nodsh"
11168
11169         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11170         set_nodes_failloc "$(osts_nodes)" 0x20e
11171         test_mkdir $DIR/$tdir
11172
11173         for ((i=0;i<10;i++)); do
11174                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11175                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11176                 SLEEPPID=$!
11177                 sleep 0.500s
11178                 kill $SLEEPPID
11179                 wait $SLEEPPID
11180         done
11181
11182         set_nodes_failloc "$(osts_nodes)" 0
11183         rm -rf $DIR/$tdir
11184 }
11185 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11186
11187 test_118l() # LU-646
11188 {
11189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11190
11191         test_mkdir $DIR/$tdir
11192         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11193         rm -rf $DIR/$tdir
11194 }
11195 run_test 118l "fsync dir"
11196
11197 test_118m() # LU-3066
11198 {
11199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11200
11201         test_mkdir $DIR/$tdir
11202         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11203         rm -rf $DIR/$tdir
11204 }
11205 run_test 118m "fdatasync dir ========="
11206
11207 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11208
11209 test_118n()
11210 {
11211         local begin
11212         local end
11213
11214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11215         remote_ost_nodsh && skip "remote OSTs with nodsh"
11216
11217         # Sleep to avoid a cached response.
11218         #define OBD_STATFS_CACHE_SECONDS 1
11219         sleep 2
11220
11221         # Inject a 10 second delay in the OST_STATFS handler.
11222         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11223         set_nodes_failloc "$(osts_nodes)" 0x242
11224
11225         begin=$SECONDS
11226         stat --file-system $MOUNT > /dev/null
11227         end=$SECONDS
11228
11229         set_nodes_failloc "$(osts_nodes)" 0
11230
11231         if ((end - begin > 20)); then
11232             error "statfs took $((end - begin)) seconds, expected 10"
11233         fi
11234 }
11235 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11236
11237 test_119a() # bug 11737
11238 {
11239         BSIZE=$((512 * 1024))
11240         directio write $DIR/$tfile 0 1 $BSIZE
11241         # We ask to read two blocks, which is more than a file size.
11242         # directio will indicate an error when requested and actual
11243         # sizes aren't equeal (a normal situation in this case) and
11244         # print actual read amount.
11245         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11246         if [ "$NOB" != "$BSIZE" ]; then
11247                 error "read $NOB bytes instead of $BSIZE"
11248         fi
11249         rm -f $DIR/$tfile
11250 }
11251 run_test 119a "Short directIO read must return actual read amount"
11252
11253 test_119b() # bug 11737
11254 {
11255         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11256
11257         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11258         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11259         sync
11260         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11261                 error "direct read failed"
11262         rm -f $DIR/$tfile
11263 }
11264 run_test 119b "Sparse directIO read must return actual read amount"
11265
11266 test_119c() # bug 13099
11267 {
11268         BSIZE=1048576
11269         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11270         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11271         rm -f $DIR/$tfile
11272 }
11273 run_test 119c "Testing for direct read hitting hole"
11274
11275 test_119d() # bug 15950
11276 {
11277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11278
11279         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11280         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11281         BSIZE=1048576
11282         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11283         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11284         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11285         lctl set_param fail_loc=0x40d
11286         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11287         pid_dio=$!
11288         sleep 1
11289         cat $DIR/$tfile > /dev/null &
11290         lctl set_param fail_loc=0
11291         pid_reads=$!
11292         wait $pid_dio
11293         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11294         sleep 2
11295         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11296         error "the read rpcs have not completed in 2s"
11297         rm -f $DIR/$tfile
11298         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11299 }
11300 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11301
11302 test_120a() {
11303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11304         remote_mds_nodsh && skip "remote MDS with nodsh"
11305         test_mkdir -i0 -c1 $DIR/$tdir
11306         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11307                 skip_env "no early lock cancel on server"
11308
11309         lru_resize_disable mdc
11310         lru_resize_disable osc
11311         cancel_lru_locks mdc
11312         # asynchronous object destroy at MDT could cause bl ast to client
11313         cancel_lru_locks osc
11314
11315         stat $DIR/$tdir > /dev/null
11316         can1=$(do_facet mds1 \
11317                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11318                awk '/ldlm_cancel/ {print $2}')
11319         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11320                awk '/ldlm_bl_callback/ {print $2}')
11321         test_mkdir -i0 -c1 $DIR/$tdir/d1
11322         can2=$(do_facet mds1 \
11323                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11324                awk '/ldlm_cancel/ {print $2}')
11325         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11326                awk '/ldlm_bl_callback/ {print $2}')
11327         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11328         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11329         lru_resize_enable mdc
11330         lru_resize_enable osc
11331 }
11332 run_test 120a "Early Lock Cancel: mkdir test"
11333
11334 test_120b() {
11335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11336         remote_mds_nodsh && skip "remote MDS with nodsh"
11337         test_mkdir $DIR/$tdir
11338         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11339                 skip_env "no early lock cancel on server"
11340
11341         lru_resize_disable mdc
11342         lru_resize_disable osc
11343         cancel_lru_locks mdc
11344         stat $DIR/$tdir > /dev/null
11345         can1=$(do_facet $SINGLEMDS \
11346                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11347                awk '/ldlm_cancel/ {print $2}')
11348         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11349                awk '/ldlm_bl_callback/ {print $2}')
11350         touch $DIR/$tdir/f1
11351         can2=$(do_facet $SINGLEMDS \
11352                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11353                awk '/ldlm_cancel/ {print $2}')
11354         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11355                awk '/ldlm_bl_callback/ {print $2}')
11356         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11357         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11358         lru_resize_enable mdc
11359         lru_resize_enable osc
11360 }
11361 run_test 120b "Early Lock Cancel: create test"
11362
11363 test_120c() {
11364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11365         remote_mds_nodsh && skip "remote MDS with nodsh"
11366         test_mkdir -i0 -c1 $DIR/$tdir
11367         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11368                 skip "no early lock cancel on server"
11369
11370         lru_resize_disable mdc
11371         lru_resize_disable osc
11372         test_mkdir -i0 -c1 $DIR/$tdir/d1
11373         test_mkdir -i0 -c1 $DIR/$tdir/d2
11374         touch $DIR/$tdir/d1/f1
11375         cancel_lru_locks mdc
11376         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11377         can1=$(do_facet mds1 \
11378                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11379                awk '/ldlm_cancel/ {print $2}')
11380         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11381                awk '/ldlm_bl_callback/ {print $2}')
11382         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11383         can2=$(do_facet mds1 \
11384                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11385                awk '/ldlm_cancel/ {print $2}')
11386         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11387                awk '/ldlm_bl_callback/ {print $2}')
11388         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11389         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11390         lru_resize_enable mdc
11391         lru_resize_enable osc
11392 }
11393 run_test 120c "Early Lock Cancel: link test"
11394
11395 test_120d() {
11396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11397         remote_mds_nodsh && skip "remote MDS with nodsh"
11398         test_mkdir -i0 -c1 $DIR/$tdir
11399         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11400                 skip_env "no early lock cancel on server"
11401
11402         lru_resize_disable mdc
11403         lru_resize_disable osc
11404         touch $DIR/$tdir
11405         cancel_lru_locks mdc
11406         stat $DIR/$tdir > /dev/null
11407         can1=$(do_facet mds1 \
11408                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11409                awk '/ldlm_cancel/ {print $2}')
11410         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11411                awk '/ldlm_bl_callback/ {print $2}')
11412         chmod a+x $DIR/$tdir
11413         can2=$(do_facet mds1 \
11414                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11415                awk '/ldlm_cancel/ {print $2}')
11416         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11417                awk '/ldlm_bl_callback/ {print $2}')
11418         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11419         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11420         lru_resize_enable mdc
11421         lru_resize_enable osc
11422 }
11423 run_test 120d "Early Lock Cancel: setattr test"
11424
11425 test_120e() {
11426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11427         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11428                 skip_env "no early lock cancel on server"
11429         remote_mds_nodsh && skip "remote MDS with nodsh"
11430
11431         local dlmtrace_set=false
11432
11433         test_mkdir -i0 -c1 $DIR/$tdir
11434         lru_resize_disable mdc
11435         lru_resize_disable osc
11436         ! $LCTL get_param debug | grep -q dlmtrace &&
11437                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11438         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11439         cancel_lru_locks mdc
11440         cancel_lru_locks osc
11441         dd if=$DIR/$tdir/f1 of=/dev/null
11442         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11443         # XXX client can not do early lock cancel of OST lock
11444         # during unlink (LU-4206), so cancel osc lock now.
11445         sleep 2
11446         cancel_lru_locks osc
11447         can1=$(do_facet mds1 \
11448                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11449                awk '/ldlm_cancel/ {print $2}')
11450         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11451                awk '/ldlm_bl_callback/ {print $2}')
11452         unlink $DIR/$tdir/f1
11453         sleep 5
11454         can2=$(do_facet mds1 \
11455                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11456                awk '/ldlm_cancel/ {print $2}')
11457         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11458                awk '/ldlm_bl_callback/ {print $2}')
11459         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11460                 $LCTL dk $TMP/cancel.debug.txt
11461         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11462                 $LCTL dk $TMP/blocking.debug.txt
11463         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11464         lru_resize_enable mdc
11465         lru_resize_enable osc
11466 }
11467 run_test 120e "Early Lock Cancel: unlink test"
11468
11469 test_120f() {
11470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11471         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11472                 skip_env "no early lock cancel on server"
11473         remote_mds_nodsh && skip "remote MDS with nodsh"
11474
11475         test_mkdir -i0 -c1 $DIR/$tdir
11476         lru_resize_disable mdc
11477         lru_resize_disable osc
11478         test_mkdir -i0 -c1 $DIR/$tdir/d1
11479         test_mkdir -i0 -c1 $DIR/$tdir/d2
11480         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11481         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11482         cancel_lru_locks mdc
11483         cancel_lru_locks osc
11484         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11485         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11486         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11487         # XXX client can not do early lock cancel of OST lock
11488         # during rename (LU-4206), so cancel osc lock now.
11489         sleep 2
11490         cancel_lru_locks osc
11491         can1=$(do_facet mds1 \
11492                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11493                awk '/ldlm_cancel/ {print $2}')
11494         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11495                awk '/ldlm_bl_callback/ {print $2}')
11496         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11497         sleep 5
11498         can2=$(do_facet mds1 \
11499                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11500                awk '/ldlm_cancel/ {print $2}')
11501         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11502                awk '/ldlm_bl_callback/ {print $2}')
11503         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11504         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11505         lru_resize_enable mdc
11506         lru_resize_enable osc
11507 }
11508 run_test 120f "Early Lock Cancel: rename test"
11509
11510 test_120g() {
11511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11512         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11513                 skip_env "no early lock cancel on server"
11514         remote_mds_nodsh && skip "remote MDS with nodsh"
11515
11516         lru_resize_disable mdc
11517         lru_resize_disable osc
11518         count=10000
11519         echo create $count files
11520         test_mkdir $DIR/$tdir
11521         cancel_lru_locks mdc
11522         cancel_lru_locks osc
11523         t0=$(date +%s)
11524
11525         can0=$(do_facet $SINGLEMDS \
11526                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11527                awk '/ldlm_cancel/ {print $2}')
11528         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11529                awk '/ldlm_bl_callback/ {print $2}')
11530         createmany -o $DIR/$tdir/f $count
11531         sync
11532         can1=$(do_facet $SINGLEMDS \
11533                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11534                awk '/ldlm_cancel/ {print $2}')
11535         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11536                awk '/ldlm_bl_callback/ {print $2}')
11537         t1=$(date +%s)
11538         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11539         echo rm $count files
11540         rm -r $DIR/$tdir
11541         sync
11542         can2=$(do_facet $SINGLEMDS \
11543                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11544                awk '/ldlm_cancel/ {print $2}')
11545         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11546                awk '/ldlm_bl_callback/ {print $2}')
11547         t2=$(date +%s)
11548         echo total: $count removes in $((t2-t1))
11549         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11550         sleep 2
11551         # wait for commitment of removal
11552         lru_resize_enable mdc
11553         lru_resize_enable osc
11554 }
11555 run_test 120g "Early Lock Cancel: performance test"
11556
11557 test_121() { #bug #10589
11558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11559
11560         rm -rf $DIR/$tfile
11561         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11562 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11563         lctl set_param fail_loc=0x310
11564         cancel_lru_locks osc > /dev/null
11565         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11566         lctl set_param fail_loc=0
11567         [[ $reads -eq $writes ]] ||
11568                 error "read $reads blocks, must be $writes blocks"
11569 }
11570 run_test 121 "read cancel race ========="
11571
11572 test_123a_base() { # was test 123, statahead(bug 11401)
11573         local lsx="$1"
11574
11575         SLOWOK=0
11576         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11577                 log "testing UP system. Performance may be lower than expected."
11578                 SLOWOK=1
11579         fi
11580
11581         rm -rf $DIR/$tdir
11582         test_mkdir $DIR/$tdir
11583         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11584         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11585         MULT=10
11586         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11587                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11588
11589                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11590                 lctl set_param -n llite.*.statahead_max 0
11591                 lctl get_param llite.*.statahead_max
11592                 cancel_lru_locks mdc
11593                 cancel_lru_locks osc
11594                 stime=$(date +%s)
11595                 time $lsx $DIR/$tdir | wc -l
11596                 etime=$(date +%s)
11597                 delta=$((etime - stime))
11598                 log "$lsx $i files without statahead: $delta sec"
11599                 lctl set_param llite.*.statahead_max=$max
11600
11601                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11602                         grep "statahead wrong:" | awk '{print $3}')
11603                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11604                 cancel_lru_locks mdc
11605                 cancel_lru_locks osc
11606                 stime=$(date +%s)
11607                 time $lsx $DIR/$tdir | wc -l
11608                 etime=$(date +%s)
11609                 delta_sa=$((etime - stime))
11610                 log "$lsx $i files with statahead: $delta_sa sec"
11611                 lctl get_param -n llite.*.statahead_stats
11612                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11613                         grep "statahead wrong:" | awk '{print $3}')
11614
11615                 [[ $swrong -lt $ewrong ]] &&
11616                         log "statahead was stopped, maybe too many locks held!"
11617                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11618
11619                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11620                         max=$(lctl get_param -n llite.*.statahead_max |
11621                                 head -n 1)
11622                         lctl set_param -n llite.*.statahead_max 0
11623                         lctl get_param llite.*.statahead_max
11624                         cancel_lru_locks mdc
11625                         cancel_lru_locks osc
11626                         stime=$(date +%s)
11627                         time $lsx $DIR/$tdir | wc -l
11628                         etime=$(date +%s)
11629                         delta=$((etime - stime))
11630                         log "$lsx $i files again without statahead: $delta sec"
11631                         lctl set_param llite.*.statahead_max=$max
11632                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11633                                 if [  $SLOWOK -eq 0 ]; then
11634                                         error "$lsx $i files is slower with statahead!"
11635                                 else
11636                                         log "$lsx $i files is slower with statahead!"
11637                                 fi
11638                                 break
11639                         fi
11640                 fi
11641
11642                 [ $delta -gt 20 ] && break
11643                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11644                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11645         done
11646         log "$lsx done"
11647
11648         stime=$(date +%s)
11649         rm -r $DIR/$tdir
11650         sync
11651         etime=$(date +%s)
11652         delta=$((etime - stime))
11653         log "rm -r $DIR/$tdir/: $delta seconds"
11654         log "rm done"
11655         lctl get_param -n llite.*.statahead_stats
11656 }
11657
11658 test_123aa() {
11659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11660
11661         test_123a_base "ls -l"
11662 }
11663 run_test 123aa "verify statahead work"
11664
11665 test_123ab() {
11666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11667
11668         statx_supported || skip_env "Test must be statx() syscall supported"
11669
11670         test_123a_base "$STATX -l"
11671 }
11672 run_test 123ab "verify statahead work by using statx"
11673
11674 test_123ac() {
11675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11676
11677         statx_supported || skip_env "Test must be statx() syscall supported"
11678
11679         local rpcs_before
11680         local rpcs_after
11681         local agl_before
11682         local agl_after
11683
11684         cancel_lru_locks $OSC
11685         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11686         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11687                 awk '/agl.total:/ {print $3}')
11688         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11689         test_123a_base "$STATX --cached=always -D"
11690         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11691                 awk '/agl.total:/ {print $3}')
11692         [ $agl_before -eq $agl_after ] ||
11693                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11694         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11695         [ $rpcs_after -eq $rpcs_before ] ||
11696                 error "$STATX should not send glimpse RPCs to $OSC"
11697 }
11698 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11699
11700 test_123b () { # statahead(bug 15027)
11701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11702
11703         test_mkdir $DIR/$tdir
11704         createmany -o $DIR/$tdir/$tfile-%d 1000
11705
11706         cancel_lru_locks mdc
11707         cancel_lru_locks osc
11708
11709 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11710         lctl set_param fail_loc=0x80000803
11711         ls -lR $DIR/$tdir > /dev/null
11712         log "ls done"
11713         lctl set_param fail_loc=0x0
11714         lctl get_param -n llite.*.statahead_stats
11715         rm -r $DIR/$tdir
11716         sync
11717
11718 }
11719 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11720
11721 test_123c() {
11722         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11723
11724         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11725         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11726         touch $DIR/$tdir.1/{1..3}
11727         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11728
11729         remount_client $MOUNT
11730
11731         $MULTIOP $DIR/$tdir.0 Q
11732
11733         # let statahead to complete
11734         ls -l $DIR/$tdir.0 > /dev/null
11735
11736         testid=$(echo $TESTNAME | tr '_' ' ')
11737         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11738                 error "statahead warning" || true
11739 }
11740 run_test 123c "Can not initialize inode warning on DNE statahead"
11741
11742 test_124a() {
11743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11744         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11745                 skip_env "no lru resize on server"
11746
11747         local NR=2000
11748
11749         test_mkdir $DIR/$tdir
11750
11751         log "create $NR files at $DIR/$tdir"
11752         createmany -o $DIR/$tdir/f $NR ||
11753                 error "failed to create $NR files in $DIR/$tdir"
11754
11755         cancel_lru_locks mdc
11756         ls -l $DIR/$tdir > /dev/null
11757
11758         local NSDIR=""
11759         local LRU_SIZE=0
11760         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11761                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11762                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11763                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11764                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11765                         log "NSDIR=$NSDIR"
11766                         log "NS=$(basename $NSDIR)"
11767                         break
11768                 fi
11769         done
11770
11771         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11772                 skip "Not enough cached locks created!"
11773         fi
11774         log "LRU=$LRU_SIZE"
11775
11776         local SLEEP=30
11777
11778         # We know that lru resize allows one client to hold $LIMIT locks
11779         # for 10h. After that locks begin to be killed by client.
11780         local MAX_HRS=10
11781         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11782         log "LIMIT=$LIMIT"
11783         if [ $LIMIT -lt $LRU_SIZE ]; then
11784                 skip "Limit is too small $LIMIT"
11785         fi
11786
11787         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11788         # killing locks. Some time was spent for creating locks. This means
11789         # that up to the moment of sleep finish we must have killed some of
11790         # them (10-100 locks). This depends on how fast ther were created.
11791         # Many of them were touched in almost the same moment and thus will
11792         # be killed in groups.
11793         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11794
11795         # Use $LRU_SIZE_B here to take into account real number of locks
11796         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11797         local LRU_SIZE_B=$LRU_SIZE
11798         log "LVF=$LVF"
11799         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11800         log "OLD_LVF=$OLD_LVF"
11801         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11802
11803         # Let's make sure that we really have some margin. Client checks
11804         # cached locks every 10 sec.
11805         SLEEP=$((SLEEP+20))
11806         log "Sleep ${SLEEP} sec"
11807         local SEC=0
11808         while ((SEC<$SLEEP)); do
11809                 echo -n "..."
11810                 sleep 5
11811                 SEC=$((SEC+5))
11812                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11813                 echo -n "$LRU_SIZE"
11814         done
11815         echo ""
11816         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11817         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11818
11819         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11820                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11821                 unlinkmany $DIR/$tdir/f $NR
11822                 return
11823         }
11824
11825         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11826         log "unlink $NR files at $DIR/$tdir"
11827         unlinkmany $DIR/$tdir/f $NR
11828 }
11829 run_test 124a "lru resize ======================================="
11830
11831 get_max_pool_limit()
11832 {
11833         local limit=$($LCTL get_param \
11834                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11835         local max=0
11836         for l in $limit; do
11837                 if [[ $l -gt $max ]]; then
11838                         max=$l
11839                 fi
11840         done
11841         echo $max
11842 }
11843
11844 test_124b() {
11845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11846         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11847                 skip_env "no lru resize on server"
11848
11849         LIMIT=$(get_max_pool_limit)
11850
11851         NR=$(($(default_lru_size)*20))
11852         if [[ $NR -gt $LIMIT ]]; then
11853                 log "Limit lock number by $LIMIT locks"
11854                 NR=$LIMIT
11855         fi
11856
11857         IFree=$(mdsrate_inodes_available)
11858         if [ $IFree -lt $NR ]; then
11859                 log "Limit lock number by $IFree inodes"
11860                 NR=$IFree
11861         fi
11862
11863         lru_resize_disable mdc
11864         test_mkdir -p $DIR/$tdir/disable_lru_resize
11865
11866         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11867         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11868         cancel_lru_locks mdc
11869         stime=`date +%s`
11870         PID=""
11871         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11872         PID="$PID $!"
11873         sleep 2
11874         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11875         PID="$PID $!"
11876         sleep 2
11877         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11878         PID="$PID $!"
11879         wait $PID
11880         etime=`date +%s`
11881         nolruresize_delta=$((etime-stime))
11882         log "ls -la time: $nolruresize_delta seconds"
11883         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11884         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11885
11886         lru_resize_enable mdc
11887         test_mkdir -p $DIR/$tdir/enable_lru_resize
11888
11889         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11890         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11891         cancel_lru_locks mdc
11892         stime=`date +%s`
11893         PID=""
11894         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11895         PID="$PID $!"
11896         sleep 2
11897         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11898         PID="$PID $!"
11899         sleep 2
11900         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11901         PID="$PID $!"
11902         wait $PID
11903         etime=`date +%s`
11904         lruresize_delta=$((etime-stime))
11905         log "ls -la time: $lruresize_delta seconds"
11906         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11907
11908         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11909                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11910         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11911                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11912         else
11913                 log "lru resize performs the same with no lru resize"
11914         fi
11915         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11916 }
11917 run_test 124b "lru resize (performance test) ======================="
11918
11919 test_124c() {
11920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11921         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11922                 skip_env "no lru resize on server"
11923
11924         # cache ununsed locks on client
11925         local nr=100
11926         cancel_lru_locks mdc
11927         test_mkdir $DIR/$tdir
11928         createmany -o $DIR/$tdir/f $nr ||
11929                 error "failed to create $nr files in $DIR/$tdir"
11930         ls -l $DIR/$tdir > /dev/null
11931
11932         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11933         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11934         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11935         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11936         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11937
11938         # set lru_max_age to 1 sec
11939         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11940         echo "sleep $((recalc_p * 2)) seconds..."
11941         sleep $((recalc_p * 2))
11942
11943         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11944         # restore lru_max_age
11945         $LCTL set_param -n $nsdir.lru_max_age $max_age
11946         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11947         unlinkmany $DIR/$tdir/f $nr
11948 }
11949 run_test 124c "LRUR cancel very aged locks"
11950
11951 test_124d() {
11952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11953         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11954                 skip_env "no lru resize on server"
11955
11956         # cache ununsed locks on client
11957         local nr=100
11958
11959         lru_resize_disable mdc
11960         stack_trap "lru_resize_enable mdc" EXIT
11961
11962         cancel_lru_locks mdc
11963
11964         # asynchronous object destroy at MDT could cause bl ast to client
11965         test_mkdir $DIR/$tdir
11966         createmany -o $DIR/$tdir/f $nr ||
11967                 error "failed to create $nr files in $DIR/$tdir"
11968         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11969
11970         ls -l $DIR/$tdir > /dev/null
11971
11972         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11973         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11974         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11975         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11976
11977         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11978
11979         # set lru_max_age to 1 sec
11980         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11981         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
11982
11983         echo "sleep $((recalc_p * 2)) seconds..."
11984         sleep $((recalc_p * 2))
11985
11986         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11987
11988         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11989 }
11990 run_test 124d "cancel very aged locks if lru-resize diasbaled"
11991
11992 test_125() { # 13358
11993         $LCTL get_param -n llite.*.client_type | grep -q local ||
11994                 skip "must run as local client"
11995         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
11996                 skip_env "must have acl enabled"
11997         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11998
11999         test_mkdir $DIR/$tdir
12000         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12001         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12002         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12003 }
12004 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12005
12006 test_126() { # bug 12829/13455
12007         $GSS && skip_env "must run as gss disabled"
12008         $LCTL get_param -n llite.*.client_type | grep -q local ||
12009                 skip "must run as local client"
12010         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12011
12012         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12013         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12014         rm -f $DIR/$tfile
12015         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12016 }
12017 run_test 126 "check that the fsgid provided by the client is taken into account"
12018
12019 test_127a() { # bug 15521
12020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12021         local name count samp unit min max sum sumsq
12022
12023         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12024         echo "stats before reset"
12025         $LCTL get_param osc.*.stats
12026         $LCTL set_param osc.*.stats=0
12027         local fsize=$((2048 * 1024))
12028
12029         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12030         cancel_lru_locks osc
12031         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12032
12033         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12034         stack_trap "rm -f $TMP/$tfile.tmp"
12035         while read name count samp unit min max sum sumsq; do
12036                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12037                 [ ! $min ] && error "Missing min value for $name proc entry"
12038                 eval $name=$count || error "Wrong proc format"
12039
12040                 case $name in
12041                 read_bytes|write_bytes)
12042                         [[ "$unit" =~ "bytes" ]] ||
12043                                 error "unit is not 'bytes': $unit"
12044                         (( $min >= 4096 )) || error "min is too small: $min"
12045                         (( $min <= $fsize )) || error "min is too big: $min"
12046                         (( $max >= 4096 )) || error "max is too small: $max"
12047                         (( $max <= $fsize )) || error "max is too big: $max"
12048                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12049                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12050                                 error "sumsquare is too small: $sumsq"
12051                         (( $sumsq <= $fsize * $fsize )) ||
12052                                 error "sumsquare is too big: $sumsq"
12053                         ;;
12054                 ost_read|ost_write)
12055                         [[ "$unit" =~ "usec" ]] ||
12056                                 error "unit is not 'usec': $unit"
12057                         ;;
12058                 *)      ;;
12059                 esac
12060         done < $DIR/$tfile.tmp
12061
12062         #check that we actually got some stats
12063         [ "$read_bytes" ] || error "Missing read_bytes stats"
12064         [ "$write_bytes" ] || error "Missing write_bytes stats"
12065         [ "$read_bytes" != 0 ] || error "no read done"
12066         [ "$write_bytes" != 0 ] || error "no write done"
12067 }
12068 run_test 127a "verify the client stats are sane"
12069
12070 test_127b() { # bug LU-333
12071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12072         local name count samp unit min max sum sumsq
12073
12074         echo "stats before reset"
12075         $LCTL get_param llite.*.stats
12076         $LCTL set_param llite.*.stats=0
12077
12078         # perform 2 reads and writes so MAX is different from SUM.
12079         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12080         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12081         cancel_lru_locks osc
12082         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12083         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12084
12085         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12086         stack_trap "rm -f $TMP/$tfile.tmp"
12087         while read name count samp unit min max sum sumsq; do
12088                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12089                 eval $name=$count || error "Wrong proc format"
12090
12091                 case $name in
12092                 read_bytes|write_bytes)
12093                         [[ "$unit" =~ "bytes" ]] ||
12094                                 error "unit is not 'bytes': $unit"
12095                         (( $count == 2 )) || error "count is not 2: $count"
12096                         (( $min == $PAGE_SIZE )) ||
12097                                 error "min is not $PAGE_SIZE: $min"
12098                         (( $max == $PAGE_SIZE )) ||
12099                                 error "max is not $PAGE_SIZE: $max"
12100                         (( $sum == $PAGE_SIZE * 2 )) ||
12101                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12102                         ;;
12103                 read|write)
12104                         [[ "$unit" =~ "usec" ]] ||
12105                                 error "unit is not 'usec': $unit"
12106                         ;;
12107                 *)      ;;
12108                 esac
12109         done < $TMP/$tfile.tmp
12110
12111         #check that we actually got some stats
12112         [ "$read_bytes" ] || error "Missing read_bytes stats"
12113         [ "$write_bytes" ] || error "Missing write_bytes stats"
12114         [ "$read_bytes" != 0 ] || error "no read done"
12115         [ "$write_bytes" != 0 ] || error "no write done"
12116 }
12117 run_test 127b "verify the llite client stats are sane"
12118
12119 test_127c() { # LU-12394
12120         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12121         local size
12122         local bsize
12123         local reads
12124         local writes
12125         local count
12126
12127         $LCTL set_param llite.*.extents_stats=1
12128         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12129
12130         # Use two stripes so there is enough space in default config
12131         $LFS setstripe -c 2 $DIR/$tfile
12132
12133         # Extent stats start at 0-4K and go in power of two buckets
12134         # LL_HIST_START = 12 --> 2^12 = 4K
12135         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12136         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12137         # small configs
12138         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12139                 do
12140                 # Write and read, 2x each, second time at a non-zero offset
12141                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12142                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12143                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12144                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12145                 rm -f $DIR/$tfile
12146         done
12147
12148         $LCTL get_param llite.*.extents_stats
12149
12150         count=2
12151         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12152                 do
12153                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12154                                 grep -m 1 $bsize)
12155                 reads=$(echo $bucket | awk '{print $5}')
12156                 writes=$(echo $bucket | awk '{print $9}')
12157                 [ "$reads" -eq $count ] ||
12158                         error "$reads reads in < $bsize bucket, expect $count"
12159                 [ "$writes" -eq $count ] ||
12160                         error "$writes writes in < $bsize bucket, expect $count"
12161         done
12162
12163         # Test mmap write and read
12164         $LCTL set_param llite.*.extents_stats=c
12165         size=512
12166         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12167         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12168         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12169
12170         $LCTL get_param llite.*.extents_stats
12171
12172         count=$(((size*1024) / PAGE_SIZE))
12173
12174         bsize=$((2 * PAGE_SIZE / 1024))K
12175
12176         bucket=$($LCTL get_param -n llite.*.extents_stats |
12177                         grep -m 1 $bsize)
12178         reads=$(echo $bucket | awk '{print $5}')
12179         writes=$(echo $bucket | awk '{print $9}')
12180         # mmap writes fault in the page first, creating an additonal read
12181         [ "$reads" -eq $((2 * count)) ] ||
12182                 error "$reads reads in < $bsize bucket, expect $count"
12183         [ "$writes" -eq $count ] ||
12184                 error "$writes writes in < $bsize bucket, expect $count"
12185 }
12186 run_test 127c "test llite extent stats with regular & mmap i/o"
12187
12188 test_128() { # bug 15212
12189         touch $DIR/$tfile
12190         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12191                 find $DIR/$tfile
12192                 find $DIR/$tfile
12193         EOF
12194
12195         result=$(grep error $TMP/$tfile.log)
12196         rm -f $DIR/$tfile $TMP/$tfile.log
12197         [ -z "$result" ] ||
12198                 error "consecutive find's under interactive lfs failed"
12199 }
12200 run_test 128 "interactive lfs for 2 consecutive find's"
12201
12202 set_dir_limits () {
12203         local mntdev
12204         local canondev
12205         local node
12206
12207         local ldproc=/proc/fs/ldiskfs
12208         local facets=$(get_facets MDS)
12209
12210         for facet in ${facets//,/ }; do
12211                 canondev=$(ldiskfs_canon \
12212                            *.$(convert_facet2label $facet).mntdev $facet)
12213                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12214                         ldproc=/sys/fs/ldiskfs
12215                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12216                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12217         done
12218 }
12219
12220 check_mds_dmesg() {
12221         local facets=$(get_facets MDS)
12222         for facet in ${facets//,/ }; do
12223                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12224         done
12225         return 1
12226 }
12227
12228 test_129() {
12229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12230         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12231                 skip "Need MDS version with at least 2.5.56"
12232         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12233                 skip_env "ldiskfs only test"
12234         fi
12235         remote_mds_nodsh && skip "remote MDS with nodsh"
12236
12237         local ENOSPC=28
12238         local has_warning=false
12239
12240         rm -rf $DIR/$tdir
12241         mkdir -p $DIR/$tdir
12242
12243         # block size of mds1
12244         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12245         set_dir_limits $maxsize $((maxsize * 6 / 8))
12246         stack_trap "set_dir_limits 0 0"
12247         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12248         local dirsize=$(stat -c%s "$DIR/$tdir")
12249         local nfiles=0
12250         while (( $dirsize <= $maxsize )); do
12251                 $MCREATE $DIR/$tdir/file_base_$nfiles
12252                 rc=$?
12253                 # check two errors:
12254                 # ENOSPC for ext4 max_dir_size, which has been used since
12255                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12256                 if (( rc == ENOSPC )); then
12257                         set_dir_limits 0 0
12258                         echo "rc=$rc returned as expected after $nfiles files"
12259
12260                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12261                                 error "create failed w/o dir size limit"
12262
12263                         # messages may be rate limited if test is run repeatedly
12264                         check_mds_dmesg '"is approaching max"' ||
12265                                 echo "warning message should be output"
12266                         check_mds_dmesg '"has reached max"' ||
12267                                 echo "reached message should be output"
12268
12269                         dirsize=$(stat -c%s "$DIR/$tdir")
12270
12271                         [[ $dirsize -ge $maxsize ]] && return 0
12272                         error "dirsize $dirsize < $maxsize after $nfiles files"
12273                 elif (( rc != 0 )); then
12274                         break
12275                 fi
12276                 nfiles=$((nfiles + 1))
12277                 dirsize=$(stat -c%s "$DIR/$tdir")
12278         done
12279
12280         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12281 }
12282 run_test 129 "test directory size limit ========================"
12283
12284 OLDIFS="$IFS"
12285 cleanup_130() {
12286         trap 0
12287         IFS="$OLDIFS"
12288 }
12289
12290 test_130a() {
12291         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12292         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12293
12294         trap cleanup_130 EXIT RETURN
12295
12296         local fm_file=$DIR/$tfile
12297         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12298         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12299                 error "dd failed for $fm_file"
12300
12301         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12302         filefrag -ves $fm_file
12303         RC=$?
12304         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12305                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12306         [ $RC != 0 ] && error "filefrag $fm_file failed"
12307
12308         filefrag_op=$(filefrag -ve -k $fm_file |
12309                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12310         lun=$($LFS getstripe -i $fm_file)
12311
12312         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12313         IFS=$'\n'
12314         tot_len=0
12315         for line in $filefrag_op
12316         do
12317                 frag_lun=`echo $line | cut -d: -f5`
12318                 ext_len=`echo $line | cut -d: -f4`
12319                 if (( $frag_lun != $lun )); then
12320                         cleanup_130
12321                         error "FIEMAP on 1-stripe file($fm_file) failed"
12322                         return
12323                 fi
12324                 (( tot_len += ext_len ))
12325         done
12326
12327         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12328                 cleanup_130
12329                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12330                 return
12331         fi
12332
12333         cleanup_130
12334
12335         echo "FIEMAP on single striped file succeeded"
12336 }
12337 run_test 130a "FIEMAP (1-stripe file)"
12338
12339 test_130b() {
12340         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12341
12342         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12343         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12344
12345         trap cleanup_130 EXIT RETURN
12346
12347         local fm_file=$DIR/$tfile
12348         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12349                         error "setstripe on $fm_file"
12350         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12351                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12352
12353         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12354                 error "dd failed on $fm_file"
12355
12356         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12357         filefrag_op=$(filefrag -ve -k $fm_file |
12358                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12359
12360         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12361                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12362
12363         IFS=$'\n'
12364         tot_len=0
12365         num_luns=1
12366         for line in $filefrag_op
12367         do
12368                 frag_lun=$(echo $line | cut -d: -f5 |
12369                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12370                 ext_len=$(echo $line | cut -d: -f4)
12371                 if (( $frag_lun != $last_lun )); then
12372                         if (( tot_len != 1024 )); then
12373                                 cleanup_130
12374                                 error "FIEMAP on $fm_file failed; returned " \
12375                                 "len $tot_len for OST $last_lun instead of 1024"
12376                                 return
12377                         else
12378                                 (( num_luns += 1 ))
12379                                 tot_len=0
12380                         fi
12381                 fi
12382                 (( tot_len += ext_len ))
12383                 last_lun=$frag_lun
12384         done
12385         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12386                 cleanup_130
12387                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12388                         "luns or wrong len for OST $last_lun"
12389                 return
12390         fi
12391
12392         cleanup_130
12393
12394         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12395 }
12396 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12397
12398 test_130c() {
12399         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12400
12401         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12402         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12403
12404         trap cleanup_130 EXIT RETURN
12405
12406         local fm_file=$DIR/$tfile
12407         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12408         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12409                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12410
12411         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12412                         error "dd failed on $fm_file"
12413
12414         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12415         filefrag_op=$(filefrag -ve -k $fm_file |
12416                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12417
12418         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12419                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12420
12421         IFS=$'\n'
12422         tot_len=0
12423         num_luns=1
12424         for line in $filefrag_op
12425         do
12426                 frag_lun=$(echo $line | cut -d: -f5 |
12427                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12428                 ext_len=$(echo $line | cut -d: -f4)
12429                 if (( $frag_lun != $last_lun )); then
12430                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12431                         if (( logical != 512 )); then
12432                                 cleanup_130
12433                                 error "FIEMAP on $fm_file failed; returned " \
12434                                 "logical start for lun $logical instead of 512"
12435                                 return
12436                         fi
12437                         if (( tot_len != 512 )); then
12438                                 cleanup_130
12439                                 error "FIEMAP on $fm_file failed; returned " \
12440                                 "len $tot_len for OST $last_lun instead of 1024"
12441                                 return
12442                         else
12443                                 (( num_luns += 1 ))
12444                                 tot_len=0
12445                         fi
12446                 fi
12447                 (( tot_len += ext_len ))
12448                 last_lun=$frag_lun
12449         done
12450         if (( num_luns != 2 || tot_len != 512 )); then
12451                 cleanup_130
12452                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12453                         "luns or wrong len for OST $last_lun"
12454                 return
12455         fi
12456
12457         cleanup_130
12458
12459         echo "FIEMAP on 2-stripe file with hole succeeded"
12460 }
12461 run_test 130c "FIEMAP (2-stripe file with hole)"
12462
12463 test_130d() {
12464         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12465
12466         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12467         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12468
12469         trap cleanup_130 EXIT RETURN
12470
12471         local fm_file=$DIR/$tfile
12472         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12473                         error "setstripe on $fm_file"
12474         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12475                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12476
12477         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12478         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12479                 error "dd failed on $fm_file"
12480
12481         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12482         filefrag_op=$(filefrag -ve -k $fm_file |
12483                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12484
12485         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12486                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12487
12488         IFS=$'\n'
12489         tot_len=0
12490         num_luns=1
12491         for line in $filefrag_op
12492         do
12493                 frag_lun=$(echo $line | cut -d: -f5 |
12494                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12495                 ext_len=$(echo $line | cut -d: -f4)
12496                 if (( $frag_lun != $last_lun )); then
12497                         if (( tot_len != 1024 )); then
12498                                 cleanup_130
12499                                 error "FIEMAP on $fm_file failed; returned " \
12500                                 "len $tot_len for OST $last_lun instead of 1024"
12501                                 return
12502                         else
12503                                 (( num_luns += 1 ))
12504                                 tot_len=0
12505                         fi
12506                 fi
12507                 (( tot_len += ext_len ))
12508                 last_lun=$frag_lun
12509         done
12510         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12511                 cleanup_130
12512                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12513                         "luns or wrong len for OST $last_lun"
12514                 return
12515         fi
12516
12517         cleanup_130
12518
12519         echo "FIEMAP on N-stripe file succeeded"
12520 }
12521 run_test 130d "FIEMAP (N-stripe file)"
12522
12523 test_130e() {
12524         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12525
12526         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12527         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12528
12529         trap cleanup_130 EXIT RETURN
12530
12531         local fm_file=$DIR/$tfile
12532         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12533         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12534                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12535
12536         NUM_BLKS=512
12537         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12538         for ((i = 0; i < $NUM_BLKS; i++))
12539         do
12540                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12541         done
12542
12543         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12544         filefrag_op=$(filefrag -ve -k $fm_file |
12545                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12546
12547         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12548                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12549
12550         IFS=$'\n'
12551         tot_len=0
12552         num_luns=1
12553         for line in $filefrag_op
12554         do
12555                 frag_lun=$(echo $line | cut -d: -f5 |
12556                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12557                 ext_len=$(echo $line | cut -d: -f4)
12558                 if (( $frag_lun != $last_lun )); then
12559                         if (( tot_len != $EXPECTED_LEN )); then
12560                                 cleanup_130
12561                                 error "FIEMAP on $fm_file failed; returned " \
12562                                 "len $tot_len for OST $last_lun instead " \
12563                                 "of $EXPECTED_LEN"
12564                                 return
12565                         else
12566                                 (( num_luns += 1 ))
12567                                 tot_len=0
12568                         fi
12569                 fi
12570                 (( tot_len += ext_len ))
12571                 last_lun=$frag_lun
12572         done
12573         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12574                 cleanup_130
12575                 error "FIEMAP on $fm_file failed; returned wrong number " \
12576                         "of luns or wrong len for OST $last_lun"
12577                 return
12578         fi
12579
12580         cleanup_130
12581
12582         echo "FIEMAP with continuation calls succeeded"
12583 }
12584 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12585
12586 test_130f() {
12587         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12588         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12589
12590         local fm_file=$DIR/$tfile
12591         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12592                 error "multiop create with lov_delay_create on $fm_file"
12593
12594         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12595         filefrag_extents=$(filefrag -vek $fm_file |
12596                            awk '/extents? found/ { print $2 }')
12597         if [[ "$filefrag_extents" != "0" ]]; then
12598                 error "FIEMAP on $fm_file failed; " \
12599                       "returned $filefrag_extents expected 0"
12600         fi
12601
12602         rm -f $fm_file
12603 }
12604 run_test 130f "FIEMAP (unstriped file)"
12605
12606 # Test for writev/readv
12607 test_131a() {
12608         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12609                 error "writev test failed"
12610         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12611                 error "readv failed"
12612         rm -f $DIR/$tfile
12613 }
12614 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12615
12616 test_131b() {
12617         local fsize=$((524288 + 1048576 + 1572864))
12618         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12619                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12620                         error "append writev test failed"
12621
12622         ((fsize += 1572864 + 1048576))
12623         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12624                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12625                         error "append writev test failed"
12626         rm -f $DIR/$tfile
12627 }
12628 run_test 131b "test append writev"
12629
12630 test_131c() {
12631         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12632         error "NOT PASS"
12633 }
12634 run_test 131c "test read/write on file w/o objects"
12635
12636 test_131d() {
12637         rwv -f $DIR/$tfile -w -n 1 1572864
12638         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12639         if [ "$NOB" != 1572864 ]; then
12640                 error "Short read filed: read $NOB bytes instead of 1572864"
12641         fi
12642         rm -f $DIR/$tfile
12643 }
12644 run_test 131d "test short read"
12645
12646 test_131e() {
12647         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12648         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12649         error "read hitting hole failed"
12650         rm -f $DIR/$tfile
12651 }
12652 run_test 131e "test read hitting hole"
12653
12654 check_stats() {
12655         local facet=$1
12656         local op=$2
12657         local want=${3:-0}
12658         local res
12659
12660         case $facet in
12661         mds*) res=$(do_facet $facet \
12662                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12663                  ;;
12664         ost*) res=$(do_facet $facet \
12665                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12666                  ;;
12667         *) error "Wrong facet '$facet'" ;;
12668         esac
12669         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12670         # if the argument $3 is zero, it means any stat increment is ok.
12671         if [[ $want -gt 0 ]]; then
12672                 local count=$(echo $res | awk '{ print $2 }')
12673                 [[ $count -ne $want ]] &&
12674                         error "The $op counter on $facet is $count, not $want"
12675         fi
12676 }
12677
12678 test_133a() {
12679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12680         remote_ost_nodsh && skip "remote OST with nodsh"
12681         remote_mds_nodsh && skip "remote MDS with nodsh"
12682         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12683                 skip_env "MDS doesn't support rename stats"
12684
12685         local testdir=$DIR/${tdir}/stats_testdir
12686
12687         mkdir -p $DIR/${tdir}
12688
12689         # clear stats.
12690         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12691         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12692
12693         # verify mdt stats first.
12694         mkdir ${testdir} || error "mkdir failed"
12695         check_stats $SINGLEMDS "mkdir" 1
12696         touch ${testdir}/${tfile} || error "touch failed"
12697         check_stats $SINGLEMDS "open" 1
12698         check_stats $SINGLEMDS "close" 1
12699         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12700                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12701                 check_stats $SINGLEMDS "mknod" 2
12702         }
12703         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12704         check_stats $SINGLEMDS "unlink" 1
12705         rm -f ${testdir}/${tfile} || error "file remove failed"
12706         check_stats $SINGLEMDS "unlink" 2
12707
12708         # remove working dir and check mdt stats again.
12709         rmdir ${testdir} || error "rmdir failed"
12710         check_stats $SINGLEMDS "rmdir" 1
12711
12712         local testdir1=$DIR/${tdir}/stats_testdir1
12713         mkdir -p ${testdir}
12714         mkdir -p ${testdir1}
12715         touch ${testdir1}/test1
12716         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12717         check_stats $SINGLEMDS "crossdir_rename" 1
12718
12719         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12720         check_stats $SINGLEMDS "samedir_rename" 1
12721
12722         rm -rf $DIR/${tdir}
12723 }
12724 run_test 133a "Verifying MDT stats ========================================"
12725
12726 test_133b() {
12727         local res
12728
12729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12730         remote_ost_nodsh && skip "remote OST with nodsh"
12731         remote_mds_nodsh && skip "remote MDS with nodsh"
12732
12733         local testdir=$DIR/${tdir}/stats_testdir
12734
12735         mkdir -p ${testdir} || error "mkdir failed"
12736         touch ${testdir}/${tfile} || error "touch failed"
12737         cancel_lru_locks mdc
12738
12739         # clear stats.
12740         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12741         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12742
12743         # extra mdt stats verification.
12744         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12745         check_stats $SINGLEMDS "setattr" 1
12746         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12747         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12748         then            # LU-1740
12749                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12750                 check_stats $SINGLEMDS "getattr" 1
12751         fi
12752         rm -rf $DIR/${tdir}
12753
12754         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12755         # so the check below is not reliable
12756         [ $MDSCOUNT -eq 1 ] || return 0
12757
12758         # Sleep to avoid a cached response.
12759         #define OBD_STATFS_CACHE_SECONDS 1
12760         sleep 2
12761         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12762         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12763         $LFS df || error "lfs failed"
12764         check_stats $SINGLEMDS "statfs" 1
12765
12766         # check aggregated statfs (LU-10018)
12767         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12768                 return 0
12769         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12770                 return 0
12771         sleep 2
12772         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12773         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12774         df $DIR
12775         check_stats $SINGLEMDS "statfs" 1
12776
12777         # We want to check that the client didn't send OST_STATFS to
12778         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12779         # extra care is needed here.
12780         if remote_mds; then
12781                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12782                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12783
12784                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12785                 [ "$res" ] && error "OST got STATFS"
12786         fi
12787
12788         return 0
12789 }
12790 run_test 133b "Verifying extra MDT stats =================================="
12791
12792 test_133c() {
12793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12794         remote_ost_nodsh && skip "remote OST with nodsh"
12795         remote_mds_nodsh && skip "remote MDS with nodsh"
12796
12797         local testdir=$DIR/$tdir/stats_testdir
12798
12799         test_mkdir -p $testdir
12800
12801         # verify obdfilter stats.
12802         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12803         sync
12804         cancel_lru_locks osc
12805         wait_delete_completed
12806
12807         # clear stats.
12808         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12809         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12810
12811         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12812                 error "dd failed"
12813         sync
12814         cancel_lru_locks osc
12815         check_stats ost1 "write" 1
12816
12817         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12818         check_stats ost1 "read" 1
12819
12820         > $testdir/$tfile || error "truncate failed"
12821         check_stats ost1 "punch" 1
12822
12823         rm -f $testdir/$tfile || error "file remove failed"
12824         wait_delete_completed
12825         check_stats ost1 "destroy" 1
12826
12827         rm -rf $DIR/$tdir
12828 }
12829 run_test 133c "Verifying OST stats ========================================"
12830
12831 order_2() {
12832         local value=$1
12833         local orig=$value
12834         local order=1
12835
12836         while [ $value -ge 2 ]; do
12837                 order=$((order*2))
12838                 value=$((value/2))
12839         done
12840
12841         if [ $orig -gt $order ]; then
12842                 order=$((order*2))
12843         fi
12844         echo $order
12845 }
12846
12847 size_in_KMGT() {
12848     local value=$1
12849     local size=('K' 'M' 'G' 'T');
12850     local i=0
12851     local size_string=$value
12852
12853     while [ $value -ge 1024 ]; do
12854         if [ $i -gt 3 ]; then
12855             #T is the biggest unit we get here, if that is bigger,
12856             #just return XXXT
12857             size_string=${value}T
12858             break
12859         fi
12860         value=$((value >> 10))
12861         if [ $value -lt 1024 ]; then
12862             size_string=${value}${size[$i]}
12863             break
12864         fi
12865         i=$((i + 1))
12866     done
12867
12868     echo $size_string
12869 }
12870
12871 get_rename_size() {
12872         local size=$1
12873         local context=${2:-.}
12874         local sample=$(do_facet $SINGLEMDS $LCTL \
12875                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12876                 grep -A1 $context |
12877                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12878         echo $sample
12879 }
12880
12881 test_133d() {
12882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12883         remote_ost_nodsh && skip "remote OST with nodsh"
12884         remote_mds_nodsh && skip "remote MDS with nodsh"
12885         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12886                 skip_env "MDS doesn't support rename stats"
12887
12888         local testdir1=$DIR/${tdir}/stats_testdir1
12889         local testdir2=$DIR/${tdir}/stats_testdir2
12890         mkdir -p $DIR/${tdir}
12891
12892         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12893
12894         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12895         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12896
12897         createmany -o $testdir1/test 512 || error "createmany failed"
12898
12899         # check samedir rename size
12900         mv ${testdir1}/test0 ${testdir1}/test_0
12901
12902         local testdir1_size=$(ls -l $DIR/${tdir} |
12903                 awk '/stats_testdir1/ {print $5}')
12904         local testdir2_size=$(ls -l $DIR/${tdir} |
12905                 awk '/stats_testdir2/ {print $5}')
12906
12907         testdir1_size=$(order_2 $testdir1_size)
12908         testdir2_size=$(order_2 $testdir2_size)
12909
12910         testdir1_size=$(size_in_KMGT $testdir1_size)
12911         testdir2_size=$(size_in_KMGT $testdir2_size)
12912
12913         echo "source rename dir size: ${testdir1_size}"
12914         echo "target rename dir size: ${testdir2_size}"
12915
12916         local cmd="do_facet $SINGLEMDS $LCTL "
12917         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12918
12919         eval $cmd || error "$cmd failed"
12920         local samedir=$($cmd | grep 'same_dir')
12921         local same_sample=$(get_rename_size $testdir1_size)
12922         [ -z "$samedir" ] && error "samedir_rename_size count error"
12923         [[ $same_sample -eq 1 ]] ||
12924                 error "samedir_rename_size error $same_sample"
12925         echo "Check same dir rename stats success"
12926
12927         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12928
12929         # check crossdir rename size
12930         mv ${testdir1}/test_0 ${testdir2}/test_0
12931
12932         testdir1_size=$(ls -l $DIR/${tdir} |
12933                 awk '/stats_testdir1/ {print $5}')
12934         testdir2_size=$(ls -l $DIR/${tdir} |
12935                 awk '/stats_testdir2/ {print $5}')
12936
12937         testdir1_size=$(order_2 $testdir1_size)
12938         testdir2_size=$(order_2 $testdir2_size)
12939
12940         testdir1_size=$(size_in_KMGT $testdir1_size)
12941         testdir2_size=$(size_in_KMGT $testdir2_size)
12942
12943         echo "source rename dir size: ${testdir1_size}"
12944         echo "target rename dir size: ${testdir2_size}"
12945
12946         eval $cmd || error "$cmd failed"
12947         local crossdir=$($cmd | grep 'crossdir')
12948         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12949         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12950         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12951         [[ $src_sample -eq 1 ]] ||
12952                 error "crossdir_rename_size error $src_sample"
12953         [[ $tgt_sample -eq 1 ]] ||
12954                 error "crossdir_rename_size error $tgt_sample"
12955         echo "Check cross dir rename stats success"
12956         rm -rf $DIR/${tdir}
12957 }
12958 run_test 133d "Verifying rename_stats ========================================"
12959
12960 test_133e() {
12961         remote_mds_nodsh && skip "remote MDS with nodsh"
12962         remote_ost_nodsh && skip "remote OST with nodsh"
12963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12964
12965         local testdir=$DIR/${tdir}/stats_testdir
12966         local ctr f0 f1 bs=32768 count=42 sum
12967
12968         mkdir -p ${testdir} || error "mkdir failed"
12969
12970         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12971
12972         for ctr in {write,read}_bytes; do
12973                 sync
12974                 cancel_lru_locks osc
12975
12976                 do_facet ost1 $LCTL set_param -n \
12977                         "obdfilter.*.exports.clear=clear"
12978
12979                 if [ $ctr = write_bytes ]; then
12980                         f0=/dev/zero
12981                         f1=${testdir}/${tfile}
12982                 else
12983                         f0=${testdir}/${tfile}
12984                         f1=/dev/null
12985                 fi
12986
12987                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
12988                         error "dd failed"
12989                 sync
12990                 cancel_lru_locks osc
12991
12992                 sum=$(do_facet ost1 $LCTL get_param \
12993                         "obdfilter.*.exports.*.stats" |
12994                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
12995                                 $1 == ctr { sum += $7 }
12996                                 END { printf("%0.0f", sum) }')
12997
12998                 if ((sum != bs * count)); then
12999                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13000                 fi
13001         done
13002
13003         rm -rf $DIR/${tdir}
13004 }
13005 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13006
13007 test_133f() {
13008         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13009                 skip "too old lustre for get_param -R ($facet_ver)"
13010
13011         # verifying readability.
13012         $LCTL get_param -R '*' &> /dev/null
13013
13014         # Verifing writability with badarea_io.
13015         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13016                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13017                 error "client badarea_io failed"
13018
13019         # remount the FS in case writes/reads /proc break the FS
13020         cleanup || error "failed to unmount"
13021         setup || error "failed to setup"
13022 }
13023 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13024
13025 test_133g() {
13026         remote_mds_nodsh && skip "remote MDS with nodsh"
13027         remote_ost_nodsh && skip "remote OST with nodsh"
13028
13029         local facet
13030         for facet in mds1 ost1; do
13031                 local facet_ver=$(lustre_version_code $facet)
13032                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13033                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13034                 else
13035                         log "$facet: too old lustre for get_param -R"
13036                 fi
13037                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13038                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13039                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13040                                 xargs badarea_io" ||
13041                                         error "$facet badarea_io failed"
13042                 else
13043                         skip_noexit "$facet: too old lustre for get_param -R"
13044                 fi
13045         done
13046
13047         # remount the FS in case writes/reads /proc break the FS
13048         cleanup || error "failed to unmount"
13049         setup || error "failed to setup"
13050 }
13051 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13052
13053 test_133h() {
13054         remote_mds_nodsh && skip "remote MDS with nodsh"
13055         remote_ost_nodsh && skip "remote OST with nodsh"
13056         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13057                 skip "Need MDS version at least 2.9.54"
13058
13059         local facet
13060         for facet in client mds1 ost1; do
13061                 # Get the list of files that are missing the terminating newline
13062                 local plist=$(do_facet $facet
13063                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13064                 local ent
13065                 for ent in $plist; do
13066                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13067                                 awk -v FS='\v' -v RS='\v\v' \
13068                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13069                                         print FILENAME}'" 2>/dev/null)
13070                         [ -z $missing ] || {
13071                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13072                                 error "file does not end with newline: $facet-$ent"
13073                         }
13074                 done
13075         done
13076 }
13077 run_test 133h "Proc files should end with newlines"
13078
13079 test_134a() {
13080         remote_mds_nodsh && skip "remote MDS with nodsh"
13081         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13082                 skip "Need MDS version at least 2.7.54"
13083
13084         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13085         cancel_lru_locks mdc
13086
13087         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13088         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13089         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13090
13091         local nr=1000
13092         createmany -o $DIR/$tdir/f $nr ||
13093                 error "failed to create $nr files in $DIR/$tdir"
13094         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13095
13096         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13097         do_facet mds1 $LCTL set_param fail_loc=0x327
13098         do_facet mds1 $LCTL set_param fail_val=500
13099         touch $DIR/$tdir/m
13100
13101         echo "sleep 10 seconds ..."
13102         sleep 10
13103         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13104
13105         do_facet mds1 $LCTL set_param fail_loc=0
13106         do_facet mds1 $LCTL set_param fail_val=0
13107         [ $lck_cnt -lt $unused ] ||
13108                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13109
13110         rm $DIR/$tdir/m
13111         unlinkmany $DIR/$tdir/f $nr
13112 }
13113 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13114
13115 test_134b() {
13116         remote_mds_nodsh && skip "remote MDS with nodsh"
13117         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13118                 skip "Need MDS version at least 2.7.54"
13119
13120         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13121         cancel_lru_locks mdc
13122
13123         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13124                         ldlm.lock_reclaim_threshold_mb)
13125         # disable reclaim temporarily
13126         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13127
13128         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13129         do_facet mds1 $LCTL set_param fail_loc=0x328
13130         do_facet mds1 $LCTL set_param fail_val=500
13131
13132         $LCTL set_param debug=+trace
13133
13134         local nr=600
13135         createmany -o $DIR/$tdir/f $nr &
13136         local create_pid=$!
13137
13138         echo "Sleep $TIMEOUT seconds ..."
13139         sleep $TIMEOUT
13140         if ! ps -p $create_pid  > /dev/null 2>&1; then
13141                 do_facet mds1 $LCTL set_param fail_loc=0
13142                 do_facet mds1 $LCTL set_param fail_val=0
13143                 do_facet mds1 $LCTL set_param \
13144                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13145                 error "createmany finished incorrectly!"
13146         fi
13147         do_facet mds1 $LCTL set_param fail_loc=0
13148         do_facet mds1 $LCTL set_param fail_val=0
13149         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13150         wait $create_pid || return 1
13151
13152         unlinkmany $DIR/$tdir/f $nr
13153 }
13154 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13155
13156 test_135() {
13157         remote_mds_nodsh && skip "remote MDS with nodsh"
13158         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13159                 skip "Need MDS version at least 2.13.50"
13160         local fname
13161
13162         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13163
13164 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13165         #set only one record at plain llog
13166         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13167
13168         #fill already existed plain llog each 64767
13169         #wrapping whole catalog
13170         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13171
13172         createmany -o $DIR/$tdir/$tfile_ 64700
13173         for (( i = 0; i < 64700; i = i + 2 ))
13174         do
13175                 rm $DIR/$tdir/$tfile_$i &
13176                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13177                 local pid=$!
13178                 wait $pid
13179         done
13180
13181         #waiting osp synchronization
13182         wait_delete_completed
13183 }
13184 run_test 135 "Race catalog processing"
13185
13186 test_136() {
13187         remote_mds_nodsh && skip "remote MDS with nodsh"
13188         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13189                 skip "Need MDS version at least 2.13.50"
13190         local fname
13191
13192         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13193         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13194         #set only one record at plain llog
13195 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13196         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13197
13198         #fill already existed 2 plain llogs each 64767
13199         #wrapping whole catalog
13200         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13201         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13202         wait_delete_completed
13203
13204         createmany -o $DIR/$tdir/$tfile_ 10
13205         sleep 25
13206
13207         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13208         for (( i = 0; i < 10; i = i + 3 ))
13209         do
13210                 rm $DIR/$tdir/$tfile_$i &
13211                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13212                 local pid=$!
13213                 wait $pid
13214                 sleep 7
13215                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13216         done
13217
13218         #waiting osp synchronization
13219         wait_delete_completed
13220 }
13221 run_test 136 "Race catalog processing 2"
13222
13223 test_140() { #bug-17379
13224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13225
13226         test_mkdir $DIR/$tdir
13227         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13228         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13229
13230         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13231         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13232         local i=0
13233         while i=$((i + 1)); do
13234                 test_mkdir $i
13235                 cd $i || error "Changing to $i"
13236                 ln -s ../stat stat || error "Creating stat symlink"
13237                 # Read the symlink until ELOOP present,
13238                 # not LBUGing the system is considered success,
13239                 # we didn't overrun the stack.
13240                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13241                 if [ $ret -ne 0 ]; then
13242                         if [ $ret -eq 40 ]; then
13243                                 break  # -ELOOP
13244                         else
13245                                 error "Open stat symlink"
13246                                         return
13247                         fi
13248                 fi
13249         done
13250         i=$((i - 1))
13251         echo "The symlink depth = $i"
13252         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13253                 error "Invalid symlink depth"
13254
13255         # Test recursive symlink
13256         ln -s symlink_self symlink_self
13257         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13258         echo "open symlink_self returns $ret"
13259         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13260 }
13261 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13262
13263 test_150a() {
13264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13265
13266         local TF="$TMP/$tfile"
13267
13268         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13269         cp $TF $DIR/$tfile
13270         cancel_lru_locks $OSC
13271         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13272         remount_client $MOUNT
13273         df -P $MOUNT
13274         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13275
13276         $TRUNCATE $TF 6000
13277         $TRUNCATE $DIR/$tfile 6000
13278         cancel_lru_locks $OSC
13279         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13280
13281         echo "12345" >>$TF
13282         echo "12345" >>$DIR/$tfile
13283         cancel_lru_locks $OSC
13284         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13285
13286         echo "12345" >>$TF
13287         echo "12345" >>$DIR/$tfile
13288         cancel_lru_locks $OSC
13289         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13290
13291         rm -f $TF
13292         true
13293 }
13294 run_test 150a "truncate/append tests"
13295
13296 test_150b() {
13297         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13298         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13299                 skip "Need OST version at least 2.13.53"
13300         touch $DIR/$tfile
13301         check_fallocate $DIR/$tfile || error "fallocate failed"
13302 }
13303 run_test 150b "Verify fallocate (prealloc) functionality"
13304
13305 test_150c() {
13306         local bytes
13307         local want
13308
13309         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13310         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13311                 skip "Need OST version at least 2.13.53"
13312
13313         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13314         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13315         sync; sync_all_data
13316         cancel_lru_locks $OSC
13317         sleep 5
13318         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13319         want=$((OSTCOUNT * 1048576))
13320
13321         # Must allocate all requested space, not more than 5% extra
13322         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13323                 error "bytes $bytes is not $want"
13324 }
13325 run_test 150c "Verify fallocate Size and Blocks"
13326
13327 test_150d() {
13328         local bytes
13329         local want
13330
13331         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13332         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13333                 skip "Need OST version at least 2.13.53"
13334
13335         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13336         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13337         sync; sync_all_data
13338         cancel_lru_locks $OSC
13339         sleep 5
13340         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13341         want=$((OSTCOUNT * 1048576))
13342
13343         # Must allocate all requested space, not more than 5% extra
13344         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13345                 error "bytes $bytes is not $want"
13346 }
13347 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13348
13349 #LU-2902 roc_hit was not able to read all values from lproc
13350 function roc_hit_init() {
13351         local list=$(comma_list $(osts_nodes))
13352         local dir=$DIR/$tdir-check
13353         local file=$dir/$tfile
13354         local BEFORE
13355         local AFTER
13356         local idx
13357
13358         test_mkdir $dir
13359         #use setstripe to do a write to every ost
13360         for i in $(seq 0 $((OSTCOUNT-1))); do
13361                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13362                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13363                 idx=$(printf %04x $i)
13364                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13365                         awk '$1 == "cache_access" {sum += $7}
13366                                 END { printf("%0.0f", sum) }')
13367
13368                 cancel_lru_locks osc
13369                 cat $file >/dev/null
13370
13371                 AFTER=$(get_osd_param $list *OST*$idx stats |
13372                         awk '$1 == "cache_access" {sum += $7}
13373                                 END { printf("%0.0f", sum) }')
13374
13375                 echo BEFORE:$BEFORE AFTER:$AFTER
13376                 if ! let "AFTER - BEFORE == 4"; then
13377                         rm -rf $dir
13378                         error "roc_hit is not safe to use"
13379                 fi
13380                 rm $file
13381         done
13382
13383         rm -rf $dir
13384 }
13385
13386 function roc_hit() {
13387         local list=$(comma_list $(osts_nodes))
13388         echo $(get_osd_param $list '' stats |
13389                 awk '$1 == "cache_hit" {sum += $7}
13390                         END { printf("%0.0f", sum) }')
13391 }
13392
13393 function set_cache() {
13394         local on=1
13395
13396         if [ "$2" == "off" ]; then
13397                 on=0;
13398         fi
13399         local list=$(comma_list $(osts_nodes))
13400         set_osd_param $list '' $1_cache_enable $on
13401
13402         cancel_lru_locks osc
13403 }
13404
13405 test_151() {
13406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13407         remote_ost_nodsh && skip "remote OST with nodsh"
13408
13409         local CPAGES=3
13410         local list=$(comma_list $(osts_nodes))
13411
13412         # check whether obdfilter is cache capable at all
13413         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13414                 skip "not cache-capable obdfilter"
13415         fi
13416
13417         # check cache is enabled on all obdfilters
13418         if get_osd_param $list '' read_cache_enable | grep 0; then
13419                 skip "oss cache is disabled"
13420         fi
13421
13422         set_osd_param $list '' writethrough_cache_enable 1
13423
13424         # check write cache is enabled on all obdfilters
13425         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13426                 skip "oss write cache is NOT enabled"
13427         fi
13428
13429         roc_hit_init
13430
13431         #define OBD_FAIL_OBD_NO_LRU  0x609
13432         do_nodes $list $LCTL set_param fail_loc=0x609
13433
13434         # pages should be in the case right after write
13435         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13436                 error "dd failed"
13437
13438         local BEFORE=$(roc_hit)
13439         cancel_lru_locks osc
13440         cat $DIR/$tfile >/dev/null
13441         local AFTER=$(roc_hit)
13442
13443         do_nodes $list $LCTL set_param fail_loc=0
13444
13445         if ! let "AFTER - BEFORE == CPAGES"; then
13446                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13447         fi
13448
13449         cancel_lru_locks osc
13450         # invalidates OST cache
13451         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13452         set_osd_param $list '' read_cache_enable 0
13453         cat $DIR/$tfile >/dev/null
13454
13455         # now data shouldn't be found in the cache
13456         BEFORE=$(roc_hit)
13457         cancel_lru_locks osc
13458         cat $DIR/$tfile >/dev/null
13459         AFTER=$(roc_hit)
13460         if let "AFTER - BEFORE != 0"; then
13461                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13462         fi
13463
13464         set_osd_param $list '' read_cache_enable 1
13465         rm -f $DIR/$tfile
13466 }
13467 run_test 151 "test cache on oss and controls ==============================="
13468
13469 test_152() {
13470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13471
13472         local TF="$TMP/$tfile"
13473
13474         # simulate ENOMEM during write
13475 #define OBD_FAIL_OST_NOMEM      0x226
13476         lctl set_param fail_loc=0x80000226
13477         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13478         cp $TF $DIR/$tfile
13479         sync || error "sync failed"
13480         lctl set_param fail_loc=0
13481
13482         # discard client's cache
13483         cancel_lru_locks osc
13484
13485         # simulate ENOMEM during read
13486         lctl set_param fail_loc=0x80000226
13487         cmp $TF $DIR/$tfile || error "cmp failed"
13488         lctl set_param fail_loc=0
13489
13490         rm -f $TF
13491 }
13492 run_test 152 "test read/write with enomem ============================"
13493
13494 test_153() {
13495         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13496 }
13497 run_test 153 "test if fdatasync does not crash ======================="
13498
13499 dot_lustre_fid_permission_check() {
13500         local fid=$1
13501         local ffid=$MOUNT/.lustre/fid/$fid
13502         local test_dir=$2
13503
13504         echo "stat fid $fid"
13505         stat $ffid > /dev/null || error "stat $ffid failed."
13506         echo "touch fid $fid"
13507         touch $ffid || error "touch $ffid failed."
13508         echo "write to fid $fid"
13509         cat /etc/hosts > $ffid || error "write $ffid failed."
13510         echo "read fid $fid"
13511         diff /etc/hosts $ffid || error "read $ffid failed."
13512         echo "append write to fid $fid"
13513         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13514         echo "rename fid $fid"
13515         mv $ffid $test_dir/$tfile.1 &&
13516                 error "rename $ffid to $tfile.1 should fail."
13517         touch $test_dir/$tfile.1
13518         mv $test_dir/$tfile.1 $ffid &&
13519                 error "rename $tfile.1 to $ffid should fail."
13520         rm -f $test_dir/$tfile.1
13521         echo "truncate fid $fid"
13522         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13523         echo "link fid $fid"
13524         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13525         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13526                 echo "setfacl fid $fid"
13527                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13528                 echo "getfacl fid $fid"
13529                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13530         fi
13531         echo "unlink fid $fid"
13532         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13533         echo "mknod fid $fid"
13534         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13535
13536         fid=[0xf00000400:0x1:0x0]
13537         ffid=$MOUNT/.lustre/fid/$fid
13538
13539         echo "stat non-exist fid $fid"
13540         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13541         echo "write to non-exist fid $fid"
13542         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13543         echo "link new fid $fid"
13544         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13545
13546         mkdir -p $test_dir/$tdir
13547         touch $test_dir/$tdir/$tfile
13548         fid=$($LFS path2fid $test_dir/$tdir)
13549         rc=$?
13550         [ $rc -ne 0 ] &&
13551                 error "error: could not get fid for $test_dir/$dir/$tfile."
13552
13553         ffid=$MOUNT/.lustre/fid/$fid
13554
13555         echo "ls $fid"
13556         ls $ffid > /dev/null || error "ls $ffid failed."
13557         echo "touch $fid/$tfile.1"
13558         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13559
13560         echo "touch $MOUNT/.lustre/fid/$tfile"
13561         touch $MOUNT/.lustre/fid/$tfile && \
13562                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13563
13564         echo "setxattr to $MOUNT/.lustre/fid"
13565         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13566
13567         echo "listxattr for $MOUNT/.lustre/fid"
13568         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13569
13570         echo "delxattr from $MOUNT/.lustre/fid"
13571         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13572
13573         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13574         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13575                 error "touch invalid fid should fail."
13576
13577         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13578         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13579                 error "touch non-normal fid should fail."
13580
13581         echo "rename $tdir to $MOUNT/.lustre/fid"
13582         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13583                 error "rename to $MOUNT/.lustre/fid should fail."
13584
13585         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13586         then            # LU-3547
13587                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13588                 local new_obf_mode=777
13589
13590                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13591                 chmod $new_obf_mode $DIR/.lustre/fid ||
13592                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13593
13594                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13595                 [ $obf_mode -eq $new_obf_mode ] ||
13596                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13597
13598                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13599                 chmod $old_obf_mode $DIR/.lustre/fid ||
13600                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13601         fi
13602
13603         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13604         fid=$($LFS path2fid $test_dir/$tfile-2)
13605
13606         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13607         then # LU-5424
13608                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13609                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13610                         error "create lov data thru .lustre failed"
13611         fi
13612         echo "cp /etc/passwd $test_dir/$tfile-2"
13613         cp /etc/passwd $test_dir/$tfile-2 ||
13614                 error "copy to $test_dir/$tfile-2 failed."
13615         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13616         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13617                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13618
13619         rm -rf $test_dir/tfile.lnk
13620         rm -rf $test_dir/$tfile-2
13621 }
13622
13623 test_154A() {
13624         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13625                 skip "Need MDS version at least 2.4.1"
13626
13627         local tf=$DIR/$tfile
13628         touch $tf
13629
13630         local fid=$($LFS path2fid $tf)
13631         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13632
13633         # check that we get the same pathname back
13634         local rootpath
13635         local found
13636         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13637                 echo "$rootpath $fid"
13638                 found=$($LFS fid2path $rootpath "$fid")
13639                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13640                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13641         done
13642
13643         # check wrong root path format
13644         rootpath=$MOUNT"_wrong"
13645         found=$($LFS fid2path $rootpath "$fid")
13646         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13647 }
13648 run_test 154A "lfs path2fid and fid2path basic checks"
13649
13650 test_154B() {
13651         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13652                 skip "Need MDS version at least 2.4.1"
13653
13654         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13655         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13656         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13657         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13658
13659         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13660         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13661
13662         # check that we get the same pathname
13663         echo "PFID: $PFID, name: $name"
13664         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13665         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13666         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13667                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13668
13669         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13670 }
13671 run_test 154B "verify the ll_decode_linkea tool"
13672
13673 test_154a() {
13674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13675         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13676         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13677                 skip "Need MDS version at least 2.2.51"
13678         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13679
13680         cp /etc/hosts $DIR/$tfile
13681
13682         fid=$($LFS path2fid $DIR/$tfile)
13683         rc=$?
13684         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13685
13686         dot_lustre_fid_permission_check "$fid" $DIR ||
13687                 error "dot lustre permission check $fid failed"
13688
13689         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13690
13691         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13692
13693         touch $MOUNT/.lustre/file &&
13694                 error "creation is not allowed under .lustre"
13695
13696         mkdir $MOUNT/.lustre/dir &&
13697                 error "mkdir is not allowed under .lustre"
13698
13699         rm -rf $DIR/$tfile
13700 }
13701 run_test 154a "Open-by-FID"
13702
13703 test_154b() {
13704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13705         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13706         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13707         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13708                 skip "Need MDS version at least 2.2.51"
13709
13710         local remote_dir=$DIR/$tdir/remote_dir
13711         local MDTIDX=1
13712         local rc=0
13713
13714         mkdir -p $DIR/$tdir
13715         $LFS mkdir -i $MDTIDX $remote_dir ||
13716                 error "create remote directory failed"
13717
13718         cp /etc/hosts $remote_dir/$tfile
13719
13720         fid=$($LFS path2fid $remote_dir/$tfile)
13721         rc=$?
13722         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13723
13724         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13725                 error "dot lustre permission check $fid failed"
13726         rm -rf $DIR/$tdir
13727 }
13728 run_test 154b "Open-by-FID for remote directory"
13729
13730 test_154c() {
13731         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13732                 skip "Need MDS version at least 2.4.1"
13733
13734         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13735         local FID1=$($LFS path2fid $DIR/$tfile.1)
13736         local FID2=$($LFS path2fid $DIR/$tfile.2)
13737         local FID3=$($LFS path2fid $DIR/$tfile.3)
13738
13739         local N=1
13740         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13741                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13742                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13743                 local want=FID$N
13744                 [ "$FID" = "${!want}" ] ||
13745                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13746                 N=$((N + 1))
13747         done
13748
13749         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13750         do
13751                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13752                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13753                 N=$((N + 1))
13754         done
13755 }
13756 run_test 154c "lfs path2fid and fid2path multiple arguments"
13757
13758 test_154d() {
13759         remote_mds_nodsh && skip "remote MDS with nodsh"
13760         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13761                 skip "Need MDS version at least 2.5.53"
13762
13763         if remote_mds; then
13764                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13765         else
13766                 nid="0@lo"
13767         fi
13768         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13769         local fd
13770         local cmd
13771
13772         rm -f $DIR/$tfile
13773         touch $DIR/$tfile
13774
13775         local fid=$($LFS path2fid $DIR/$tfile)
13776         # Open the file
13777         fd=$(free_fd)
13778         cmd="exec $fd<$DIR/$tfile"
13779         eval $cmd
13780         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13781         echo "$fid_list" | grep "$fid"
13782         rc=$?
13783
13784         cmd="exec $fd>/dev/null"
13785         eval $cmd
13786         if [ $rc -ne 0 ]; then
13787                 error "FID $fid not found in open files list $fid_list"
13788         fi
13789 }
13790 run_test 154d "Verify open file fid"
13791
13792 test_154e()
13793 {
13794         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13795                 skip "Need MDS version at least 2.6.50"
13796
13797         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13798                 error ".lustre returned by readdir"
13799         fi
13800 }
13801 run_test 154e ".lustre is not returned by readdir"
13802
13803 test_154f() {
13804         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13805
13806         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13807         test_mkdir -p -c1 $DIR/$tdir/d
13808         # test dirs inherit from its stripe
13809         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13810         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13811         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13812         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13813         touch $DIR/f
13814
13815         # get fid of parents
13816         local FID0=$($LFS path2fid $DIR/$tdir/d)
13817         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13818         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13819         local FID3=$($LFS path2fid $DIR)
13820
13821         # check that path2fid --parents returns expected <parent_fid>/name
13822         # 1) test for a directory (single parent)
13823         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13824         [ "$parent" == "$FID0/foo1" ] ||
13825                 error "expected parent: $FID0/foo1, got: $parent"
13826
13827         # 2) test for a file with nlink > 1 (multiple parents)
13828         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13829         echo "$parent" | grep -F "$FID1/$tfile" ||
13830                 error "$FID1/$tfile not returned in parent list"
13831         echo "$parent" | grep -F "$FID2/link" ||
13832                 error "$FID2/link not returned in parent list"
13833
13834         # 3) get parent by fid
13835         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13836         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13837         echo "$parent" | grep -F "$FID1/$tfile" ||
13838                 error "$FID1/$tfile not returned in parent list (by fid)"
13839         echo "$parent" | grep -F "$FID2/link" ||
13840                 error "$FID2/link not returned in parent list (by fid)"
13841
13842         # 4) test for entry in root directory
13843         parent=$($LFS path2fid --parents $DIR/f)
13844         echo "$parent" | grep -F "$FID3/f" ||
13845                 error "$FID3/f not returned in parent list"
13846
13847         # 5) test it on root directory
13848         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13849                 error "$MOUNT should not have parents"
13850
13851         # enable xattr caching and check that linkea is correctly updated
13852         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13853         save_lustre_params client "llite.*.xattr_cache" > $save
13854         lctl set_param llite.*.xattr_cache 1
13855
13856         # 6.1) linkea update on rename
13857         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13858
13859         # get parents by fid
13860         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13861         # foo1 should no longer be returned in parent list
13862         echo "$parent" | grep -F "$FID1" &&
13863                 error "$FID1 should no longer be in parent list"
13864         # the new path should appear
13865         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13866                 error "$FID2/$tfile.moved is not in parent list"
13867
13868         # 6.2) linkea update on unlink
13869         rm -f $DIR/$tdir/d/foo2/link
13870         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13871         # foo2/link should no longer be returned in parent list
13872         echo "$parent" | grep -F "$FID2/link" &&
13873                 error "$FID2/link should no longer be in parent list"
13874         true
13875
13876         rm -f $DIR/f
13877         restore_lustre_params < $save
13878         rm -f $save
13879 }
13880 run_test 154f "get parent fids by reading link ea"
13881
13882 test_154g()
13883 {
13884         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13885         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13886            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13887                 skip "Need MDS version at least 2.6.92"
13888
13889         mkdir -p $DIR/$tdir
13890         llapi_fid_test -d $DIR/$tdir
13891 }
13892 run_test 154g "various llapi FID tests"
13893
13894 test_155_small_load() {
13895     local temp=$TMP/$tfile
13896     local file=$DIR/$tfile
13897
13898     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13899         error "dd of=$temp bs=6096 count=1 failed"
13900     cp $temp $file
13901     cancel_lru_locks $OSC
13902     cmp $temp $file || error "$temp $file differ"
13903
13904     $TRUNCATE $temp 6000
13905     $TRUNCATE $file 6000
13906     cmp $temp $file || error "$temp $file differ (truncate1)"
13907
13908     echo "12345" >>$temp
13909     echo "12345" >>$file
13910     cmp $temp $file || error "$temp $file differ (append1)"
13911
13912     echo "12345" >>$temp
13913     echo "12345" >>$file
13914     cmp $temp $file || error "$temp $file differ (append2)"
13915
13916     rm -f $temp $file
13917     true
13918 }
13919
13920 test_155_big_load() {
13921         remote_ost_nodsh && skip "remote OST with nodsh"
13922
13923         local temp=$TMP/$tfile
13924         local file=$DIR/$tfile
13925
13926         free_min_max
13927         local cache_size=$(do_facet ost$((MAXI+1)) \
13928                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13929         local large_file_size=$((cache_size * 2))
13930
13931         echo "OSS cache size: $cache_size KB"
13932         echo "Large file size: $large_file_size KB"
13933
13934         [ $MAXV -le $large_file_size ] &&
13935                 skip_env "max available OST size needs > $large_file_size KB"
13936
13937         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13938
13939         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13940                 error "dd of=$temp bs=$large_file_size count=1k failed"
13941         cp $temp $file
13942         ls -lh $temp $file
13943         cancel_lru_locks osc
13944         cmp $temp $file || error "$temp $file differ"
13945
13946         rm -f $temp $file
13947         true
13948 }
13949
13950 save_writethrough() {
13951         local facets=$(get_facets OST)
13952
13953         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13954 }
13955
13956 test_155a() {
13957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13958
13959         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13960
13961         save_writethrough $p
13962
13963         set_cache read on
13964         set_cache writethrough on
13965         test_155_small_load
13966         restore_lustre_params < $p
13967         rm -f $p
13968 }
13969 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13970
13971 test_155b() {
13972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13973
13974         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13975
13976         save_writethrough $p
13977
13978         set_cache read on
13979         set_cache writethrough off
13980         test_155_small_load
13981         restore_lustre_params < $p
13982         rm -f $p
13983 }
13984 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
13985
13986 test_155c() {
13987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13988
13989         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13990
13991         save_writethrough $p
13992
13993         set_cache read off
13994         set_cache writethrough on
13995         test_155_small_load
13996         restore_lustre_params < $p
13997         rm -f $p
13998 }
13999 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14000
14001 test_155d() {
14002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14003
14004         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14005
14006         save_writethrough $p
14007
14008         set_cache read off
14009         set_cache writethrough off
14010         test_155_small_load
14011         restore_lustre_params < $p
14012         rm -f $p
14013 }
14014 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14015
14016 test_155e() {
14017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14018
14019         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14020
14021         save_writethrough $p
14022
14023         set_cache read on
14024         set_cache writethrough on
14025         test_155_big_load
14026         restore_lustre_params < $p
14027         rm -f $p
14028 }
14029 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14030
14031 test_155f() {
14032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14033
14034         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14035
14036         save_writethrough $p
14037
14038         set_cache read on
14039         set_cache writethrough off
14040         test_155_big_load
14041         restore_lustre_params < $p
14042         rm -f $p
14043 }
14044 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14045
14046 test_155g() {
14047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14048
14049         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14050
14051         save_writethrough $p
14052
14053         set_cache read off
14054         set_cache writethrough on
14055         test_155_big_load
14056         restore_lustre_params < $p
14057         rm -f $p
14058 }
14059 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14060
14061 test_155h() {
14062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14063
14064         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14065
14066         save_writethrough $p
14067
14068         set_cache read off
14069         set_cache writethrough off
14070         test_155_big_load
14071         restore_lustre_params < $p
14072         rm -f $p
14073 }
14074 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14075
14076 test_156() {
14077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14078         remote_ost_nodsh && skip "remote OST with nodsh"
14079         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14080                 skip "stats not implemented on old servers"
14081         [ "$ost1_FSTYPE" = "zfs" ] &&
14082                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14083
14084         local CPAGES=3
14085         local BEFORE
14086         local AFTER
14087         local file="$DIR/$tfile"
14088         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14089
14090         save_writethrough $p
14091         roc_hit_init
14092
14093         log "Turn on read and write cache"
14094         set_cache read on
14095         set_cache writethrough on
14096
14097         log "Write data and read it back."
14098         log "Read should be satisfied from the cache."
14099         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14100         BEFORE=$(roc_hit)
14101         cancel_lru_locks osc
14102         cat $file >/dev/null
14103         AFTER=$(roc_hit)
14104         if ! let "AFTER - BEFORE == CPAGES"; then
14105                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14106         else
14107                 log "cache hits: before: $BEFORE, after: $AFTER"
14108         fi
14109
14110         log "Read again; it should be satisfied from the cache."
14111         BEFORE=$AFTER
14112         cancel_lru_locks osc
14113         cat $file >/dev/null
14114         AFTER=$(roc_hit)
14115         if ! let "AFTER - BEFORE == CPAGES"; then
14116                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14117         else
14118                 log "cache hits:: before: $BEFORE, after: $AFTER"
14119         fi
14120
14121         log "Turn off the read cache and turn on the write cache"
14122         set_cache read off
14123         set_cache writethrough on
14124
14125         log "Read again; it should be satisfied from the cache."
14126         BEFORE=$(roc_hit)
14127         cancel_lru_locks osc
14128         cat $file >/dev/null
14129         AFTER=$(roc_hit)
14130         if ! let "AFTER - BEFORE == CPAGES"; then
14131                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14132         else
14133                 log "cache hits:: before: $BEFORE, after: $AFTER"
14134         fi
14135
14136         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14137                 # > 2.12.56 uses pagecache if cached
14138                 log "Read again; it should not be satisfied from the cache."
14139                 BEFORE=$AFTER
14140                 cancel_lru_locks osc
14141                 cat $file >/dev/null
14142                 AFTER=$(roc_hit)
14143                 if ! let "AFTER - BEFORE == 0"; then
14144                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14145                 else
14146                         log "cache hits:: before: $BEFORE, after: $AFTER"
14147                 fi
14148         fi
14149
14150         log "Write data and read it back."
14151         log "Read should be satisfied from the cache."
14152         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14153         BEFORE=$(roc_hit)
14154         cancel_lru_locks osc
14155         cat $file >/dev/null
14156         AFTER=$(roc_hit)
14157         if ! let "AFTER - BEFORE == CPAGES"; then
14158                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14159         else
14160                 log "cache hits:: before: $BEFORE, after: $AFTER"
14161         fi
14162
14163         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14164                 # > 2.12.56 uses pagecache if cached
14165                 log "Read again; it should not be satisfied from the cache."
14166                 BEFORE=$AFTER
14167                 cancel_lru_locks osc
14168                 cat $file >/dev/null
14169                 AFTER=$(roc_hit)
14170                 if ! let "AFTER - BEFORE == 0"; then
14171                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14172                 else
14173                         log "cache hits:: before: $BEFORE, after: $AFTER"
14174                 fi
14175         fi
14176
14177         log "Turn off read and write cache"
14178         set_cache read off
14179         set_cache writethrough off
14180
14181         log "Write data and read it back"
14182         log "It should not be satisfied from the cache."
14183         rm -f $file
14184         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14185         cancel_lru_locks osc
14186         BEFORE=$(roc_hit)
14187         cat $file >/dev/null
14188         AFTER=$(roc_hit)
14189         if ! let "AFTER - BEFORE == 0"; then
14190                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14191         else
14192                 log "cache hits:: before: $BEFORE, after: $AFTER"
14193         fi
14194
14195         log "Turn on the read cache and turn off the write cache"
14196         set_cache read on
14197         set_cache writethrough off
14198
14199         log "Write data and read it back"
14200         log "It should not be satisfied from the cache."
14201         rm -f $file
14202         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14203         BEFORE=$(roc_hit)
14204         cancel_lru_locks osc
14205         cat $file >/dev/null
14206         AFTER=$(roc_hit)
14207         if ! let "AFTER - BEFORE == 0"; then
14208                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14209         else
14210                 log "cache hits:: before: $BEFORE, after: $AFTER"
14211         fi
14212
14213         log "Read again; it should be satisfied from the cache."
14214         BEFORE=$(roc_hit)
14215         cancel_lru_locks osc
14216         cat $file >/dev/null
14217         AFTER=$(roc_hit)
14218         if ! let "AFTER - BEFORE == CPAGES"; then
14219                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14220         else
14221                 log "cache hits:: before: $BEFORE, after: $AFTER"
14222         fi
14223
14224         restore_lustre_params < $p
14225         rm -f $p $file
14226 }
14227 run_test 156 "Verification of tunables"
14228
14229 test_160a() {
14230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14231         remote_mds_nodsh && skip "remote MDS with nodsh"
14232         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14233                 skip "Need MDS version at least 2.2.0"
14234
14235         changelog_register || error "changelog_register failed"
14236         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14237         changelog_users $SINGLEMDS | grep -q $cl_user ||
14238                 error "User $cl_user not found in changelog_users"
14239
14240         # change something
14241         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14242         changelog_clear 0 || error "changelog_clear failed"
14243         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14244         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14245         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14246         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14247         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14248         rm $DIR/$tdir/pics/desktop.jpg
14249
14250         changelog_dump | tail -10
14251
14252         echo "verifying changelog mask"
14253         changelog_chmask "-MKDIR"
14254         changelog_chmask "-CLOSE"
14255
14256         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14257         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14258
14259         changelog_chmask "+MKDIR"
14260         changelog_chmask "+CLOSE"
14261
14262         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14263         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14264
14265         changelog_dump | tail -10
14266         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14267         CLOSES=$(changelog_dump | grep -c "CLOSE")
14268         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14269         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14270
14271         # verify contents
14272         echo "verifying target fid"
14273         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14274         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14275         [ "$fidc" == "$fidf" ] ||
14276                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14277         echo "verifying parent fid"
14278         # The FID returned from the Changelog may be the directory shard on
14279         # a different MDT, and not the FID returned by path2fid on the parent.
14280         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14281         # since this is what will matter when recreating this file in the tree.
14282         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14283         local pathp=$($LFS fid2path $MOUNT "$fidp")
14284         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14285                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14286
14287         echo "getting records for $cl_user"
14288         changelog_users $SINGLEMDS
14289         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14290         local nclr=3
14291         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14292                 error "changelog_clear failed"
14293         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14294         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14295         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14296                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14297
14298         local min0_rec=$(changelog_users $SINGLEMDS |
14299                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14300         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14301                           awk '{ print $1; exit; }')
14302
14303         changelog_dump | tail -n 5
14304         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14305         [ $first_rec == $((min0_rec + 1)) ] ||
14306                 error "first index should be $min0_rec + 1 not $first_rec"
14307
14308         # LU-3446 changelog index reset on MDT restart
14309         local cur_rec1=$(changelog_users $SINGLEMDS |
14310                          awk '/^current.index:/ { print $NF }')
14311         changelog_clear 0 ||
14312                 error "clear all changelog records for $cl_user failed"
14313         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14314         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14315                 error "Fail to start $SINGLEMDS"
14316         local cur_rec2=$(changelog_users $SINGLEMDS |
14317                          awk '/^current.index:/ { print $NF }')
14318         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14319         [ $cur_rec1 == $cur_rec2 ] ||
14320                 error "current index should be $cur_rec1 not $cur_rec2"
14321
14322         echo "verifying users from this test are deregistered"
14323         changelog_deregister || error "changelog_deregister failed"
14324         changelog_users $SINGLEMDS | grep -q $cl_user &&
14325                 error "User '$cl_user' still in changelog_users"
14326
14327         # lctl get_param -n mdd.*.changelog_users
14328         # current index: 144
14329         # ID    index (idle seconds)
14330         # cl3   144 (2)
14331         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14332                 # this is the normal case where all users were deregistered
14333                 # make sure no new records are added when no users are present
14334                 local last_rec1=$(changelog_users $SINGLEMDS |
14335                                   awk '/^current.index:/ { print $NF }')
14336                 touch $DIR/$tdir/chloe
14337                 local last_rec2=$(changelog_users $SINGLEMDS |
14338                                   awk '/^current.index:/ { print $NF }')
14339                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14340                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14341         else
14342                 # any changelog users must be leftovers from a previous test
14343                 changelog_users $SINGLEMDS
14344                 echo "other changelog users; can't verify off"
14345         fi
14346 }
14347 run_test 160a "changelog sanity"
14348
14349 test_160b() { # LU-3587
14350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14351         remote_mds_nodsh && skip "remote MDS with nodsh"
14352         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14353                 skip "Need MDS version at least 2.2.0"
14354
14355         changelog_register || error "changelog_register failed"
14356         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14357         changelog_users $SINGLEMDS | grep -q $cl_user ||
14358                 error "User '$cl_user' not found in changelog_users"
14359
14360         local longname1=$(str_repeat a 255)
14361         local longname2=$(str_repeat b 255)
14362
14363         cd $DIR
14364         echo "creating very long named file"
14365         touch $longname1 || error "create of '$longname1' failed"
14366         echo "renaming very long named file"
14367         mv $longname1 $longname2
14368
14369         changelog_dump | grep RENME | tail -n 5
14370         rm -f $longname2
14371 }
14372 run_test 160b "Verify that very long rename doesn't crash in changelog"
14373
14374 test_160c() {
14375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14376         remote_mds_nodsh && skip "remote MDS with nodsh"
14377
14378         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14379                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14380                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14381                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14382
14383         local rc=0
14384
14385         # Registration step
14386         changelog_register || error "changelog_register failed"
14387
14388         rm -rf $DIR/$tdir
14389         mkdir -p $DIR/$tdir
14390         $MCREATE $DIR/$tdir/foo_160c
14391         changelog_chmask "-TRUNC"
14392         $TRUNCATE $DIR/$tdir/foo_160c 200
14393         changelog_chmask "+TRUNC"
14394         $TRUNCATE $DIR/$tdir/foo_160c 199
14395         changelog_dump | tail -n 5
14396         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14397         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14398 }
14399 run_test 160c "verify that changelog log catch the truncate event"
14400
14401 test_160d() {
14402         remote_mds_nodsh && skip "remote MDS with nodsh"
14403         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14405         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14406                 skip "Need MDS version at least 2.7.60"
14407
14408         # Registration step
14409         changelog_register || error "changelog_register failed"
14410
14411         mkdir -p $DIR/$tdir/migrate_dir
14412         changelog_clear 0 || error "changelog_clear failed"
14413
14414         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14415         changelog_dump | tail -n 5
14416         local migrates=$(changelog_dump | grep -c "MIGRT")
14417         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14418 }
14419 run_test 160d "verify that changelog log catch the migrate event"
14420
14421 test_160e() {
14422         remote_mds_nodsh && skip "remote MDS with nodsh"
14423
14424         # Create a user
14425         changelog_register || error "changelog_register failed"
14426
14427         # Delete a future user (expect fail)
14428         local MDT0=$(facet_svc $SINGLEMDS)
14429         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14430         local rc=$?
14431
14432         if [ $rc -eq 0 ]; then
14433                 error "Deleted non-existant user cl77"
14434         elif [ $rc -ne 2 ]; then
14435                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14436         fi
14437
14438         # Clear to a bad index (1 billion should be safe)
14439         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14440         rc=$?
14441
14442         if [ $rc -eq 0 ]; then
14443                 error "Successfully cleared to invalid CL index"
14444         elif [ $rc -ne 22 ]; then
14445                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14446         fi
14447 }
14448 run_test 160e "changelog negative testing (should return errors)"
14449
14450 test_160f() {
14451         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14452         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14453                 skip "Need MDS version at least 2.10.56"
14454
14455         local mdts=$(comma_list $(mdts_nodes))
14456
14457         # Create a user
14458         changelog_register || error "first changelog_register failed"
14459         changelog_register || error "second changelog_register failed"
14460         local cl_users
14461         declare -A cl_user1
14462         declare -A cl_user2
14463         local user_rec1
14464         local user_rec2
14465         local i
14466
14467         # generate some changelog records to accumulate on each MDT
14468         # use fnv1a because created files should be evenly distributed
14469         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14470                 error "test_mkdir $tdir failed"
14471         log "$(date +%s): creating first files"
14472         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14473                 error "create $DIR/$tdir/$tfile failed"
14474
14475         # check changelogs have been generated
14476         local start=$SECONDS
14477         local idle_time=$((MDSCOUNT * 5 + 5))
14478         local nbcl=$(changelog_dump | wc -l)
14479         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14480
14481         for param in "changelog_max_idle_time=$idle_time" \
14482                      "changelog_gc=1" \
14483                      "changelog_min_gc_interval=2" \
14484                      "changelog_min_free_cat_entries=3"; do
14485                 local MDT0=$(facet_svc $SINGLEMDS)
14486                 local var="${param%=*}"
14487                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14488
14489                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14490                 do_nodes $mdts $LCTL set_param mdd.*.$param
14491         done
14492
14493         # force cl_user2 to be idle (1st part), but also cancel the
14494         # cl_user1 records so that it is not evicted later in the test.
14495         local sleep1=$((idle_time / 2))
14496         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14497         sleep $sleep1
14498
14499         # simulate changelog catalog almost full
14500         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14501         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14502
14503         for i in $(seq $MDSCOUNT); do
14504                 cl_users=(${CL_USERS[mds$i]})
14505                 cl_user1[mds$i]="${cl_users[0]}"
14506                 cl_user2[mds$i]="${cl_users[1]}"
14507
14508                 [ -n "${cl_user1[mds$i]}" ] ||
14509                         error "mds$i: no user registered"
14510                 [ -n "${cl_user2[mds$i]}" ] ||
14511                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14512
14513                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14514                 [ -n "$user_rec1" ] ||
14515                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14516                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14517                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14518                 [ -n "$user_rec2" ] ||
14519                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14520                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14521                      "$user_rec1 + 2 == $user_rec2"
14522                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14523                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14524                               "$user_rec1 + 2, but is $user_rec2"
14525                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14526                 [ -n "$user_rec2" ] ||
14527                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14528                 [ $user_rec1 == $user_rec2 ] ||
14529                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14530                               "$user_rec1, but is $user_rec2"
14531         done
14532
14533         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14534         local sleep2=$((idle_time - (SECONDS - start) + 1))
14535         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14536         sleep $sleep2
14537
14538         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14539         # cl_user1 should be OK because it recently processed records.
14540         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14541         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14542                 error "create $DIR/$tdir/${tfile}b failed"
14543
14544         # ensure gc thread is done
14545         for i in $(mdts_nodes); do
14546                 wait_update $i \
14547                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14548                         error "$i: GC-thread not done"
14549         done
14550
14551         local first_rec
14552         for i in $(seq $MDSCOUNT); do
14553                 # check cl_user1 still registered
14554                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14555                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14556                 # check cl_user2 unregistered
14557                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14558                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14559
14560                 # check changelogs are present and starting at $user_rec1 + 1
14561                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14562                 [ -n "$user_rec1" ] ||
14563                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14564                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14565                             awk '{ print $1; exit; }')
14566
14567                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14568                 [ $((user_rec1 + 1)) == $first_rec ] ||
14569                         error "mds$i: first index should be $user_rec1 + 1, " \
14570                               "but is $first_rec"
14571         done
14572 }
14573 run_test 160f "changelog garbage collect (timestamped users)"
14574
14575 test_160g() {
14576         remote_mds_nodsh && skip "remote MDS with nodsh"
14577         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14578                 skip "Need MDS version at least 2.10.56"
14579
14580         local mdts=$(comma_list $(mdts_nodes))
14581
14582         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14583         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14584
14585         # Create a user
14586         changelog_register || error "first changelog_register failed"
14587         changelog_register || error "second changelog_register failed"
14588         local cl_users
14589         declare -A cl_user1
14590         declare -A cl_user2
14591         local user_rec1
14592         local user_rec2
14593         local i
14594
14595         # generate some changelog records to accumulate on each MDT
14596         # use fnv1a because created files should be evenly distributed
14597         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14598                 error "mkdir $tdir failed"
14599         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14600                 error "create $DIR/$tdir/$tfile failed"
14601
14602         # check changelogs have been generated
14603         local nbcl=$(changelog_dump | wc -l)
14604         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14605
14606         # reduce the max_idle_indexes value to make sure we exceed it
14607         max_ndx=$((nbcl / 2 - 1))
14608
14609         for param in "changelog_max_idle_indexes=$max_ndx" \
14610                      "changelog_gc=1" \
14611                      "changelog_min_gc_interval=2" \
14612                      "changelog_min_free_cat_entries=3"; do
14613                 local MDT0=$(facet_svc $SINGLEMDS)
14614                 local var="${param%=*}"
14615                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14616
14617                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14618                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14619                         error "unable to set mdd.*.$param"
14620         done
14621
14622         # simulate changelog catalog almost full
14623         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14624         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14625
14626         for i in $(seq $MDSCOUNT); do
14627                 cl_users=(${CL_USERS[mds$i]})
14628                 cl_user1[mds$i]="${cl_users[0]}"
14629                 cl_user2[mds$i]="${cl_users[1]}"
14630
14631                 [ -n "${cl_user1[mds$i]}" ] ||
14632                         error "mds$i: no user registered"
14633                 [ -n "${cl_user2[mds$i]}" ] ||
14634                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14635
14636                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14637                 [ -n "$user_rec1" ] ||
14638                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14639                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14640                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14641                 [ -n "$user_rec2" ] ||
14642                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14643                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14644                      "$user_rec1 + 2 == $user_rec2"
14645                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14646                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14647                               "$user_rec1 + 2, but is $user_rec2"
14648                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14649                 [ -n "$user_rec2" ] ||
14650                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14651                 [ $user_rec1 == $user_rec2 ] ||
14652                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14653                               "$user_rec1, but is $user_rec2"
14654         done
14655
14656         # ensure we are past the previous changelog_min_gc_interval set above
14657         sleep 2
14658
14659         # generate one more changelog to trigger fail_loc
14660         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14661                 error "create $DIR/$tdir/${tfile}bis failed"
14662
14663         # ensure gc thread is done
14664         for i in $(mdts_nodes); do
14665                 wait_update $i \
14666                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14667                         error "$i: GC-thread not done"
14668         done
14669
14670         local first_rec
14671         for i in $(seq $MDSCOUNT); do
14672                 # check cl_user1 still registered
14673                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14674                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14675                 # check cl_user2 unregistered
14676                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14677                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14678
14679                 # check changelogs are present and starting at $user_rec1 + 1
14680                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14681                 [ -n "$user_rec1" ] ||
14682                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14683                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14684                             awk '{ print $1; exit; }')
14685
14686                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14687                 [ $((user_rec1 + 1)) == $first_rec ] ||
14688                         error "mds$i: first index should be $user_rec1 + 1, " \
14689                               "but is $first_rec"
14690         done
14691 }
14692 run_test 160g "changelog garbage collect (old users)"
14693
14694 test_160h() {
14695         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14696         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14697                 skip "Need MDS version at least 2.10.56"
14698
14699         local mdts=$(comma_list $(mdts_nodes))
14700
14701         # Create a user
14702         changelog_register || error "first changelog_register failed"
14703         changelog_register || error "second changelog_register failed"
14704         local cl_users
14705         declare -A cl_user1
14706         declare -A cl_user2
14707         local user_rec1
14708         local user_rec2
14709         local i
14710
14711         # generate some changelog records to accumulate on each MDT
14712         # use fnv1a because created files should be evenly distributed
14713         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14714                 error "test_mkdir $tdir failed"
14715         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14716                 error "create $DIR/$tdir/$tfile failed"
14717
14718         # check changelogs have been generated
14719         local nbcl=$(changelog_dump | wc -l)
14720         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14721
14722         for param in "changelog_max_idle_time=10" \
14723                      "changelog_gc=1" \
14724                      "changelog_min_gc_interval=2"; do
14725                 local MDT0=$(facet_svc $SINGLEMDS)
14726                 local var="${param%=*}"
14727                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14728
14729                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14730                 do_nodes $mdts $LCTL set_param mdd.*.$param
14731         done
14732
14733         # force cl_user2 to be idle (1st part)
14734         sleep 9
14735
14736         for i in $(seq $MDSCOUNT); do
14737                 cl_users=(${CL_USERS[mds$i]})
14738                 cl_user1[mds$i]="${cl_users[0]}"
14739                 cl_user2[mds$i]="${cl_users[1]}"
14740
14741                 [ -n "${cl_user1[mds$i]}" ] ||
14742                         error "mds$i: no user registered"
14743                 [ -n "${cl_user2[mds$i]}" ] ||
14744                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14745
14746                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14747                 [ -n "$user_rec1" ] ||
14748                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14749                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14750                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14751                 [ -n "$user_rec2" ] ||
14752                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14753                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14754                      "$user_rec1 + 2 == $user_rec2"
14755                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14756                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14757                               "$user_rec1 + 2, but is $user_rec2"
14758                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14759                 [ -n "$user_rec2" ] ||
14760                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14761                 [ $user_rec1 == $user_rec2 ] ||
14762                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14763                               "$user_rec1, but is $user_rec2"
14764         done
14765
14766         # force cl_user2 to be idle (2nd part) and to reach
14767         # changelog_max_idle_time
14768         sleep 2
14769
14770         # force each GC-thread start and block then
14771         # one per MDT/MDD, set fail_val accordingly
14772         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14773         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14774
14775         # generate more changelogs to trigger fail_loc
14776         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14777                 error "create $DIR/$tdir/${tfile}bis failed"
14778
14779         # stop MDT to stop GC-thread, should be done in back-ground as it will
14780         # block waiting for the thread to be released and exit
14781         declare -A stop_pids
14782         for i in $(seq $MDSCOUNT); do
14783                 stop mds$i &
14784                 stop_pids[mds$i]=$!
14785         done
14786
14787         for i in $(mdts_nodes); do
14788                 local facet
14789                 local nb=0
14790                 local facets=$(facets_up_on_host $i)
14791
14792                 for facet in ${facets//,/ }; do
14793                         if [[ $facet == mds* ]]; then
14794                                 nb=$((nb + 1))
14795                         fi
14796                 done
14797                 # ensure each MDS's gc threads are still present and all in "R"
14798                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14799                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14800                         error "$i: expected $nb GC-thread"
14801                 wait_update $i \
14802                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14803                         "R" 20 ||
14804                         error "$i: GC-thread not found in R-state"
14805                 # check umounts of each MDT on MDS have reached kthread_stop()
14806                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14807                         error "$i: expected $nb umount"
14808                 wait_update $i \
14809                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14810                         error "$i: umount not found in D-state"
14811         done
14812
14813         # release all GC-threads
14814         do_nodes $mdts $LCTL set_param fail_loc=0
14815
14816         # wait for MDT stop to complete
14817         for i in $(seq $MDSCOUNT); do
14818                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14819         done
14820
14821         # XXX
14822         # may try to check if any orphan changelog records are present
14823         # via ldiskfs/zfs and llog_reader...
14824
14825         # re-start/mount MDTs
14826         for i in $(seq $MDSCOUNT); do
14827                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14828                         error "Fail to start mds$i"
14829         done
14830
14831         local first_rec
14832         for i in $(seq $MDSCOUNT); do
14833                 # check cl_user1 still registered
14834                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14835                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14836                 # check cl_user2 unregistered
14837                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14838                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14839
14840                 # check changelogs are present and starting at $user_rec1 + 1
14841                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14842                 [ -n "$user_rec1" ] ||
14843                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14844                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14845                             awk '{ print $1; exit; }')
14846
14847                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14848                 [ $((user_rec1 + 1)) == $first_rec ] ||
14849                         error "mds$i: first index should be $user_rec1 + 1, " \
14850                               "but is $first_rec"
14851         done
14852 }
14853 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14854               "during mount"
14855
14856 test_160i() {
14857
14858         local mdts=$(comma_list $(mdts_nodes))
14859
14860         changelog_register || error "first changelog_register failed"
14861
14862         # generate some changelog records to accumulate on each MDT
14863         # use fnv1a because created files should be evenly distributed
14864         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14865                 error "mkdir $tdir failed"
14866         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14867                 error "create $DIR/$tdir/$tfile failed"
14868
14869         # check changelogs have been generated
14870         local nbcl=$(changelog_dump | wc -l)
14871         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14872
14873         # simulate race between register and unregister
14874         # XXX as fail_loc is set per-MDS, with DNE configs the race
14875         # simulation will only occur for one MDT per MDS and for the
14876         # others the normal race scenario will take place
14877         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14878         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14879         do_nodes $mdts $LCTL set_param fail_val=1
14880
14881         # unregister 1st user
14882         changelog_deregister &
14883         local pid1=$!
14884         # wait some time for deregister work to reach race rdv
14885         sleep 2
14886         # register 2nd user
14887         changelog_register || error "2nd user register failed"
14888
14889         wait $pid1 || error "1st user deregister failed"
14890
14891         local i
14892         local last_rec
14893         declare -A LAST_REC
14894         for i in $(seq $MDSCOUNT); do
14895                 if changelog_users mds$i | grep "^cl"; then
14896                         # make sure new records are added with one user present
14897                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14898                                           awk '/^current.index:/ { print $NF }')
14899                 else
14900                         error "mds$i has no user registered"
14901                 fi
14902         done
14903
14904         # generate more changelog records to accumulate on each MDT
14905         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14906                 error "create $DIR/$tdir/${tfile}bis failed"
14907
14908         for i in $(seq $MDSCOUNT); do
14909                 last_rec=$(changelog_users $SINGLEMDS |
14910                            awk '/^current.index:/ { print $NF }')
14911                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14912                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14913                         error "changelogs are off on mds$i"
14914         done
14915 }
14916 run_test 160i "changelog user register/unregister race"
14917
14918 test_160j() {
14919         remote_mds_nodsh && skip "remote MDS with nodsh"
14920         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14921                 skip "Need MDS version at least 2.12.56"
14922
14923         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14924         stack_trap "umount $MOUNT2" EXIT
14925
14926         changelog_register || error "first changelog_register failed"
14927         stack_trap "changelog_deregister" EXIT
14928
14929         # generate some changelog
14930         # use fnv1a because created files should be evenly distributed
14931         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14932                 error "mkdir $tdir failed"
14933         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14934                 error "create $DIR/$tdir/${tfile}bis failed"
14935
14936         # open the changelog device
14937         exec 3>/dev/changelog-$FSNAME-MDT0000
14938         stack_trap "exec 3>&-" EXIT
14939         exec 4</dev/changelog-$FSNAME-MDT0000
14940         stack_trap "exec 4<&-" EXIT
14941
14942         # umount the first lustre mount
14943         umount $MOUNT
14944         stack_trap "mount_client $MOUNT" EXIT
14945
14946         # read changelog
14947         cat <&4 >/dev/null || error "read changelog failed"
14948
14949         # clear changelog
14950         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14951         changelog_users $SINGLEMDS | grep -q $cl_user ||
14952                 error "User $cl_user not found in changelog_users"
14953
14954         printf 'clear:'$cl_user':0' >&3
14955 }
14956 run_test 160j "client can be umounted  while its chanangelog is being used"
14957
14958 test_160k() {
14959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14960         remote_mds_nodsh && skip "remote MDS with nodsh"
14961
14962         mkdir -p $DIR/$tdir/1/1
14963
14964         changelog_register || error "changelog_register failed"
14965         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14966
14967         changelog_users $SINGLEMDS | grep -q $cl_user ||
14968                 error "User '$cl_user' not found in changelog_users"
14969 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14970         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
14971         rmdir $DIR/$tdir/1/1 & sleep 1
14972         mkdir $DIR/$tdir/2
14973         touch $DIR/$tdir/2/2
14974         rm -rf $DIR/$tdir/2
14975
14976         wait
14977         sleep 4
14978
14979         changelog_dump | grep rmdir || error "rmdir not recorded"
14980
14981         rm -rf $DIR/$tdir
14982         changelog_deregister
14983 }
14984 run_test 160k "Verify that changelog records are not lost"
14985
14986 # Verifies that a file passed as a parameter has recently had an operation
14987 # performed on it that has generated an MTIME changelog which contains the
14988 # correct parent FID. As files might reside on a different MDT from the
14989 # parent directory in DNE configurations, the FIDs are translated to paths
14990 # before being compared, which should be identical
14991 compare_mtime_changelog() {
14992         local file="${1}"
14993         local mdtidx
14994         local mtime
14995         local cl_fid
14996         local pdir
14997         local dir
14998
14999         mdtidx=$($LFS getstripe --mdt-index $file)
15000         mdtidx=$(printf "%04x" $mdtidx)
15001
15002         # Obtain the parent FID from the MTIME changelog
15003         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15004         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15005
15006         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15007         [ -z "$cl_fid" ] && error "parent FID not present"
15008
15009         # Verify that the path for the parent FID is the same as the path for
15010         # the test directory
15011         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15012
15013         dir=$(dirname $1)
15014
15015         [[ "${pdir%/}" == "$dir" ]] ||
15016                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15017 }
15018
15019 test_160l() {
15020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15021
15022         remote_mds_nodsh && skip "remote MDS with nodsh"
15023         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15024                 skip "Need MDS version at least 2.13.55"
15025
15026         local cl_user
15027
15028         changelog_register || error "changelog_register failed"
15029         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15030
15031         changelog_users $SINGLEMDS | grep -q $cl_user ||
15032                 error "User '$cl_user' not found in changelog_users"
15033
15034         # Clear some types so that MTIME changelogs are generated
15035         changelog_chmask "-CREAT"
15036         changelog_chmask "-CLOSE"
15037
15038         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15039
15040         # Test CL_MTIME during setattr
15041         touch $DIR/$tdir/$tfile
15042         compare_mtime_changelog $DIR/$tdir/$tfile
15043
15044         # Test CL_MTIME during close
15045         dd if=/dev/urandom of=$DIR/$tdir/${tfile}_2 bs=1M count=64 ||
15046                 error "cannot create file $DIR/$tdir/${tfile}_2"
15047         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15048 }
15049 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15050
15051 test_161a() {
15052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15053
15054         test_mkdir -c1 $DIR/$tdir
15055         cp /etc/hosts $DIR/$tdir/$tfile
15056         test_mkdir -c1 $DIR/$tdir/foo1
15057         test_mkdir -c1 $DIR/$tdir/foo2
15058         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15059         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15060         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15061         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15062         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15063         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15064                 $LFS fid2path $DIR $FID
15065                 error "bad link ea"
15066         fi
15067         # middle
15068         rm $DIR/$tdir/foo2/zachary
15069         # last
15070         rm $DIR/$tdir/foo2/thor
15071         # first
15072         rm $DIR/$tdir/$tfile
15073         # rename
15074         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15075         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15076                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15077         rm $DIR/$tdir/foo2/maggie
15078
15079         # overflow the EA
15080         local longname=$tfile.avg_len_is_thirty_two_
15081         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15082                 error_noexit 'failed to unlink many hardlinks'" EXIT
15083         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15084                 error "failed to hardlink many files"
15085         links=$($LFS fid2path $DIR $FID | wc -l)
15086         echo -n "${links}/1000 links in link EA"
15087         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15088 }
15089 run_test 161a "link ea sanity"
15090
15091 test_161b() {
15092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15093         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15094
15095         local MDTIDX=1
15096         local remote_dir=$DIR/$tdir/remote_dir
15097
15098         mkdir -p $DIR/$tdir
15099         $LFS mkdir -i $MDTIDX $remote_dir ||
15100                 error "create remote directory failed"
15101
15102         cp /etc/hosts $remote_dir/$tfile
15103         mkdir -p $remote_dir/foo1
15104         mkdir -p $remote_dir/foo2
15105         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15106         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15107         ln $remote_dir/$tfile $remote_dir/foo1/luna
15108         ln $remote_dir/$tfile $remote_dir/foo2/thor
15109
15110         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15111                      tr -d ']')
15112         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15113                 $LFS fid2path $DIR $FID
15114                 error "bad link ea"
15115         fi
15116         # middle
15117         rm $remote_dir/foo2/zachary
15118         # last
15119         rm $remote_dir/foo2/thor
15120         # first
15121         rm $remote_dir/$tfile
15122         # rename
15123         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15124         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15125         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15126                 $LFS fid2path $DIR $FID
15127                 error "bad link rename"
15128         fi
15129         rm $remote_dir/foo2/maggie
15130
15131         # overflow the EA
15132         local longname=filename_avg_len_is_thirty_two_
15133         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15134                 error "failed to hardlink many files"
15135         links=$($LFS fid2path $DIR $FID | wc -l)
15136         echo -n "${links}/1000 links in link EA"
15137         [[ ${links} -gt 60 ]] ||
15138                 error "expected at least 60 links in link EA"
15139         unlinkmany $remote_dir/foo2/$longname 1000 ||
15140         error "failed to unlink many hardlinks"
15141 }
15142 run_test 161b "link ea sanity under remote directory"
15143
15144 test_161c() {
15145         remote_mds_nodsh && skip "remote MDS with nodsh"
15146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15147         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15148                 skip "Need MDS version at least 2.1.5"
15149
15150         # define CLF_RENAME_LAST 0x0001
15151         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15152         changelog_register || error "changelog_register failed"
15153
15154         rm -rf $DIR/$tdir
15155         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15156         touch $DIR/$tdir/foo_161c
15157         touch $DIR/$tdir/bar_161c
15158         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15159         changelog_dump | grep RENME | tail -n 5
15160         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15161         changelog_clear 0 || error "changelog_clear failed"
15162         if [ x$flags != "x0x1" ]; then
15163                 error "flag $flags is not 0x1"
15164         fi
15165
15166         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15167         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15168         touch $DIR/$tdir/foo_161c
15169         touch $DIR/$tdir/bar_161c
15170         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15171         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15172         changelog_dump | grep RENME | tail -n 5
15173         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15174         changelog_clear 0 || error "changelog_clear failed"
15175         if [ x$flags != "x0x0" ]; then
15176                 error "flag $flags is not 0x0"
15177         fi
15178         echo "rename overwrite a target having nlink > 1," \
15179                 "changelog record has flags of $flags"
15180
15181         # rename doesn't overwrite a target (changelog flag 0x0)
15182         touch $DIR/$tdir/foo_161c
15183         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15184         changelog_dump | grep RENME | tail -n 5
15185         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15186         changelog_clear 0 || error "changelog_clear failed"
15187         if [ x$flags != "x0x0" ]; then
15188                 error "flag $flags is not 0x0"
15189         fi
15190         echo "rename doesn't overwrite a target," \
15191                 "changelog record has flags of $flags"
15192
15193         # define CLF_UNLINK_LAST 0x0001
15194         # unlink a file having nlink = 1 (changelog flag 0x1)
15195         rm -f $DIR/$tdir/foo2_161c
15196         changelog_dump | grep UNLNK | tail -n 5
15197         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15198         changelog_clear 0 || error "changelog_clear failed"
15199         if [ x$flags != "x0x1" ]; then
15200                 error "flag $flags is not 0x1"
15201         fi
15202         echo "unlink a file having nlink = 1," \
15203                 "changelog record has flags of $flags"
15204
15205         # unlink a file having nlink > 1 (changelog flag 0x0)
15206         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15207         rm -f $DIR/$tdir/foobar_161c
15208         changelog_dump | grep UNLNK | tail -n 5
15209         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15210         changelog_clear 0 || error "changelog_clear failed"
15211         if [ x$flags != "x0x0" ]; then
15212                 error "flag $flags is not 0x0"
15213         fi
15214         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15215 }
15216 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15217
15218 test_161d() {
15219         remote_mds_nodsh && skip "remote MDS with nodsh"
15220         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15221
15222         local pid
15223         local fid
15224
15225         changelog_register || error "changelog_register failed"
15226
15227         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15228         # interfer with $MOUNT/.lustre/fid/ access
15229         mkdir $DIR/$tdir
15230         [[ $? -eq 0 ]] || error "mkdir failed"
15231
15232         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15233         $LCTL set_param fail_loc=0x8000140c
15234         # 5s pause
15235         $LCTL set_param fail_val=5
15236
15237         # create file
15238         echo foofoo > $DIR/$tdir/$tfile &
15239         pid=$!
15240
15241         # wait for create to be delayed
15242         sleep 2
15243
15244         ps -p $pid
15245         [[ $? -eq 0 ]] || error "create should be blocked"
15246
15247         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15248         stack_trap "rm -f $tempfile"
15249         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15250         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15251         # some delay may occur during ChangeLog publishing and file read just
15252         # above, that could allow file write to happen finally
15253         [[ -s $tempfile ]] && echo "file should be empty"
15254
15255         $LCTL set_param fail_loc=0
15256
15257         wait $pid
15258         [[ $? -eq 0 ]] || error "create failed"
15259 }
15260 run_test 161d "create with concurrent .lustre/fid access"
15261
15262 check_path() {
15263         local expected="$1"
15264         shift
15265         local fid="$2"
15266
15267         local path
15268         path=$($LFS fid2path "$@")
15269         local rc=$?
15270
15271         if [ $rc -ne 0 ]; then
15272                 error "path looked up of '$expected' failed: rc=$rc"
15273         elif [ "$path" != "$expected" ]; then
15274                 error "path looked up '$path' instead of '$expected'"
15275         else
15276                 echo "FID '$fid' resolves to path '$path' as expected"
15277         fi
15278 }
15279
15280 test_162a() { # was test_162
15281         test_mkdir -p -c1 $DIR/$tdir/d2
15282         touch $DIR/$tdir/d2/$tfile
15283         touch $DIR/$tdir/d2/x1
15284         touch $DIR/$tdir/d2/x2
15285         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15286         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15287         # regular file
15288         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15289         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15290
15291         # softlink
15292         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15293         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15294         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15295
15296         # softlink to wrong file
15297         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15298         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15299         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15300
15301         # hardlink
15302         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15303         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15304         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15305         # fid2path dir/fsname should both work
15306         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15307         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15308
15309         # hardlink count: check that there are 2 links
15310         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15311         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15312
15313         # hardlink indexing: remove the first link
15314         rm $DIR/$tdir/d2/p/q/r/hlink
15315         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15316 }
15317 run_test 162a "path lookup sanity"
15318
15319 test_162b() {
15320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15321         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15322
15323         mkdir $DIR/$tdir
15324         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15325                                 error "create striped dir failed"
15326
15327         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15328                                         tail -n 1 | awk '{print $2}')
15329         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15330
15331         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15332         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15333
15334         # regular file
15335         for ((i=0;i<5;i++)); do
15336                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15337                         error "get fid for f$i failed"
15338                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15339
15340                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15341                         error "get fid for d$i failed"
15342                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15343         done
15344
15345         return 0
15346 }
15347 run_test 162b "striped directory path lookup sanity"
15348
15349 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15350 test_162c() {
15351         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15352                 skip "Need MDS version at least 2.7.51"
15353
15354         local lpath=$tdir.local
15355         local rpath=$tdir.remote
15356
15357         test_mkdir $DIR/$lpath
15358         test_mkdir $DIR/$rpath
15359
15360         for ((i = 0; i <= 101; i++)); do
15361                 lpath="$lpath/$i"
15362                 mkdir $DIR/$lpath
15363                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15364                         error "get fid for local directory $DIR/$lpath failed"
15365                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15366
15367                 rpath="$rpath/$i"
15368                 test_mkdir $DIR/$rpath
15369                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15370                         error "get fid for remote directory $DIR/$rpath failed"
15371                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15372         done
15373
15374         return 0
15375 }
15376 run_test 162c "fid2path works with paths 100 or more directories deep"
15377
15378 oalr_event_count() {
15379         local event="${1}"
15380         local trace="${2}"
15381
15382         awk -v name="${FSNAME}-OST0000" \
15383             -v event="${event}" \
15384             '$1 == "TRACE" && $2 == event && $3 == name' \
15385             "${trace}" |
15386         wc -l
15387 }
15388
15389 oalr_expect_event_count() {
15390         local event="${1}"
15391         local trace="${2}"
15392         local expect="${3}"
15393         local count
15394
15395         count=$(oalr_event_count "${event}" "${trace}")
15396         if ((count == expect)); then
15397                 return 0
15398         fi
15399
15400         error_noexit "${event} event count was '${count}', expected ${expect}"
15401         cat "${trace}" >&2
15402         exit 1
15403 }
15404
15405 cleanup_165() {
15406         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15407         stop ost1
15408         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15409 }
15410
15411 setup_165() {
15412         sync # Flush previous IOs so we can count log entries.
15413         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15414         stack_trap cleanup_165 EXIT
15415 }
15416
15417 test_165a() {
15418         local trace="/tmp/${tfile}.trace"
15419         local rc
15420         local count
15421
15422         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15423         setup_165
15424         sleep 5
15425
15426         do_facet ost1 ofd_access_log_reader --list
15427         stop ost1
15428
15429         do_facet ost1 killall -TERM ofd_access_log_reader
15430         wait
15431         rc=$?
15432
15433         if ((rc != 0)); then
15434                 error "ofd_access_log_reader exited with rc = '${rc}'"
15435         fi
15436
15437         # Parse trace file for discovery events:
15438         oalr_expect_event_count alr_log_add "${trace}" 1
15439         oalr_expect_event_count alr_log_eof "${trace}" 1
15440         oalr_expect_event_count alr_log_free "${trace}" 1
15441 }
15442 run_test 165a "ofd access log discovery"
15443
15444 test_165b() {
15445         local trace="/tmp/${tfile}.trace"
15446         local file="${DIR}/${tfile}"
15447         local pfid1
15448         local pfid2
15449         local -a entry
15450         local rc
15451         local count
15452         local size
15453         local flags
15454
15455         setup_165
15456
15457         lfs setstripe -c 1 -i 0 "${file}"
15458         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15459         do_facet ost1 ofd_access_log_reader --list
15460
15461         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15462         sleep 5
15463         do_facet ost1 killall -TERM ofd_access_log_reader
15464         wait
15465         rc=$?
15466
15467         if ((rc != 0)); then
15468                 error "ofd_access_log_reader exited with rc = '${rc}'"
15469         fi
15470
15471         oalr_expect_event_count alr_log_entry "${trace}" 1
15472
15473         pfid1=$($LFS path2fid "${file}")
15474
15475         # 1     2             3   4    5     6   7    8    9     10
15476         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15477         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15478
15479         echo "entry = '${entry[*]}'" >&2
15480
15481         pfid2=${entry[4]}
15482         if [[ "${pfid1}" != "${pfid2}" ]]; then
15483                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15484         fi
15485
15486         size=${entry[8]}
15487         if ((size != 1048576)); then
15488                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15489         fi
15490
15491         flags=${entry[10]}
15492         if [[ "${flags}" != "w" ]]; then
15493                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15494         fi
15495
15496         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15497         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c || error "cannot read '${file}'"
15498         sleep 5
15499         do_facet ost1 killall -TERM ofd_access_log_reader
15500         wait
15501         rc=$?
15502
15503         if ((rc != 0)); then
15504                 error "ofd_access_log_reader exited with rc = '${rc}'"
15505         fi
15506
15507         oalr_expect_event_count alr_log_entry "${trace}" 1
15508
15509         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15510         echo "entry = '${entry[*]}'" >&2
15511
15512         pfid2=${entry[4]}
15513         if [[ "${pfid1}" != "${pfid2}" ]]; then
15514                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15515         fi
15516
15517         size=${entry[8]}
15518         if ((size != 524288)); then
15519                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15520         fi
15521
15522         flags=${entry[10]}
15523         if [[ "${flags}" != "r" ]]; then
15524                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15525         fi
15526 }
15527 run_test 165b "ofd access log entries are produced and consumed"
15528
15529 test_165c() {
15530         local file="${DIR}/${tdir}/${tfile}"
15531         test_mkdir "${DIR}/${tdir}"
15532
15533         setup_165
15534
15535         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15536
15537         # 4096 / 64 = 64. Create twice as many entries.
15538         for ((i = 0; i < 128; i++)); do
15539                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c || error "cannot create file"
15540         done
15541
15542         sync
15543         do_facet ost1 ofd_access_log_reader --list
15544         unlinkmany  "${file}-%d" 128
15545 }
15546 run_test 165c "full ofd access logs do not block IOs"
15547
15548 oal_peek_entry_count() {
15549         do_facet ost1 ofd_access_log_reader --list | awk '$1 == "_entry_count:" { print $2; }'
15550 }
15551
15552 oal_expect_entry_count() {
15553         local entry_count=$(oal_peek_entry_count)
15554         local expect="$1"
15555
15556         if ((entry_count == expect)); then
15557                 return 0
15558         fi
15559
15560         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15561         do_facet ost1 ofd_access_log_reader --list >&2
15562         exit 1
15563 }
15564
15565 test_165d() {
15566         local trace="/tmp/${tfile}.trace"
15567         local file="${DIR}/${tdir}/${tfile}"
15568         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15569         local entry_count
15570         test_mkdir "${DIR}/${tdir}"
15571
15572         setup_165
15573         lfs setstripe -c 1 -i 0 "${file}"
15574
15575         do_facet ost1 lctl set_param "${param}=rw"
15576         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15577         oal_expect_entry_count 1
15578
15579         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15580         oal_expect_entry_count 2
15581
15582         do_facet ost1 lctl set_param "${param}=r"
15583         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15584         oal_expect_entry_count 2
15585
15586         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15587         oal_expect_entry_count 3
15588
15589         do_facet ost1 lctl set_param "${param}=w"
15590         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15591         oal_expect_entry_count 4
15592
15593         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15594         oal_expect_entry_count 4
15595
15596         do_facet ost1 lctl set_param "${param}=0"
15597         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15598         oal_expect_entry_count 4
15599
15600         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15601         oal_expect_entry_count 4
15602 }
15603 run_test 165d "ofd_access_log mask works"
15604
15605 test_169() {
15606         # do directio so as not to populate the page cache
15607         log "creating a 10 Mb file"
15608         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15609         log "starting reads"
15610         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15611         log "truncating the file"
15612         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15613         log "killing dd"
15614         kill %+ || true # reads might have finished
15615         echo "wait until dd is finished"
15616         wait
15617         log "removing the temporary file"
15618         rm -rf $DIR/$tfile || error "tmp file removal failed"
15619 }
15620 run_test 169 "parallel read and truncate should not deadlock"
15621
15622 test_170() {
15623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15624
15625         $LCTL clear     # bug 18514
15626         $LCTL debug_daemon start $TMP/${tfile}_log_good
15627         touch $DIR/$tfile
15628         $LCTL debug_daemon stop
15629         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15630                 error "sed failed to read log_good"
15631
15632         $LCTL debug_daemon start $TMP/${tfile}_log_good
15633         rm -rf $DIR/$tfile
15634         $LCTL debug_daemon stop
15635
15636         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15637                error "lctl df log_bad failed"
15638
15639         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15640         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15641
15642         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15643         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15644
15645         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15646                 error "bad_line good_line1 good_line2 are empty"
15647
15648         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15649         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15650         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15651
15652         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15653         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15654         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15655
15656         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15657                 error "bad_line_new good_line_new are empty"
15658
15659         local expected_good=$((good_line1 + good_line2*2))
15660
15661         rm -f $TMP/${tfile}*
15662         # LU-231, short malformed line may not be counted into bad lines
15663         if [ $bad_line -ne $bad_line_new ] &&
15664                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15665                 error "expected $bad_line bad lines, but got $bad_line_new"
15666                 return 1
15667         fi
15668
15669         if [ $expected_good -ne $good_line_new ]; then
15670                 error "expected $expected_good good lines, but got $good_line_new"
15671                 return 2
15672         fi
15673         true
15674 }
15675 run_test 170 "test lctl df to handle corrupted log ====================="
15676
15677 test_171() { # bug20592
15678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15679
15680         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15681         $LCTL set_param fail_loc=0x50e
15682         $LCTL set_param fail_val=3000
15683         multiop_bg_pause $DIR/$tfile O_s || true
15684         local MULTIPID=$!
15685         kill -USR1 $MULTIPID
15686         # cause log dump
15687         sleep 3
15688         wait $MULTIPID
15689         if dmesg | grep "recursive fault"; then
15690                 error "caught a recursive fault"
15691         fi
15692         $LCTL set_param fail_loc=0
15693         true
15694 }
15695 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15696
15697 # it would be good to share it with obdfilter-survey/iokit-libecho code
15698 setup_obdecho_osc () {
15699         local rc=0
15700         local ost_nid=$1
15701         local obdfilter_name=$2
15702         echo "Creating new osc for $obdfilter_name on $ost_nid"
15703         # make sure we can find loopback nid
15704         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15705
15706         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15707                            ${obdfilter_name}_osc_UUID || rc=2; }
15708         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15709                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15710         return $rc
15711 }
15712
15713 cleanup_obdecho_osc () {
15714         local obdfilter_name=$1
15715         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15716         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15717         return 0
15718 }
15719
15720 obdecho_test() {
15721         local OBD=$1
15722         local node=$2
15723         local pages=${3:-64}
15724         local rc=0
15725         local id
15726
15727         local count=10
15728         local obd_size=$(get_obd_size $node $OBD)
15729         local page_size=$(get_page_size $node)
15730         if [[ -n "$obd_size" ]]; then
15731                 local new_count=$((obd_size / (pages * page_size / 1024)))
15732                 [[ $new_count -ge $count ]] || count=$new_count
15733         fi
15734
15735         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15736         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15737                            rc=2; }
15738         if [ $rc -eq 0 ]; then
15739             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15740             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15741         fi
15742         echo "New object id is $id"
15743         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15744                            rc=4; }
15745         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15746                            "test_brw $count w v $pages $id" || rc=4; }
15747         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15748                            rc=4; }
15749         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15750                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15751         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15752                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15753         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15754         return $rc
15755 }
15756
15757 test_180a() {
15758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15759
15760         if ! module_loaded obdecho; then
15761                 load_module obdecho/obdecho &&
15762                         stack_trap "rmmod obdecho" EXIT ||
15763                         error "unable to load obdecho on client"
15764         fi
15765
15766         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15767         local host=$($LCTL get_param -n osc.$osc.import |
15768                      awk '/current_connection:/ { print $2 }' )
15769         local target=$($LCTL get_param -n osc.$osc.import |
15770                        awk '/target:/ { print $2 }' )
15771         target=${target%_UUID}
15772
15773         if [ -n "$target" ]; then
15774                 setup_obdecho_osc $host $target &&
15775                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15776                         { error "obdecho setup failed with $?"; return; }
15777
15778                 obdecho_test ${target}_osc client ||
15779                         error "obdecho_test failed on ${target}_osc"
15780         else
15781                 $LCTL get_param osc.$osc.import
15782                 error "there is no osc.$osc.import target"
15783         fi
15784 }
15785 run_test 180a "test obdecho on osc"
15786
15787 test_180b() {
15788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15789         remote_ost_nodsh && skip "remote OST with nodsh"
15790
15791         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15792                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15793                 error "failed to load module obdecho"
15794
15795         local target=$(do_facet ost1 $LCTL dl |
15796                        awk '/obdfilter/ { print $4; exit; }')
15797
15798         if [ -n "$target" ]; then
15799                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15800         else
15801                 do_facet ost1 $LCTL dl
15802                 error "there is no obdfilter target on ost1"
15803         fi
15804 }
15805 run_test 180b "test obdecho directly on obdfilter"
15806
15807 test_180c() { # LU-2598
15808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15809         remote_ost_nodsh && skip "remote OST with nodsh"
15810         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15811                 skip "Need MDS version at least 2.4.0"
15812
15813         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15814                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15815                 error "failed to load module obdecho"
15816
15817         local target=$(do_facet ost1 $LCTL dl |
15818                        awk '/obdfilter/ { print $4; exit; }')
15819
15820         if [ -n "$target" ]; then
15821                 local pages=16384 # 64MB bulk I/O RPC size
15822
15823                 obdecho_test "$target" ost1 "$pages" ||
15824                         error "obdecho_test with pages=$pages failed with $?"
15825         else
15826                 do_facet ost1 $LCTL dl
15827                 error "there is no obdfilter target on ost1"
15828         fi
15829 }
15830 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15831
15832 test_181() { # bug 22177
15833         test_mkdir $DIR/$tdir
15834         # create enough files to index the directory
15835         createmany -o $DIR/$tdir/foobar 4000
15836         # print attributes for debug purpose
15837         lsattr -d .
15838         # open dir
15839         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15840         MULTIPID=$!
15841         # remove the files & current working dir
15842         unlinkmany $DIR/$tdir/foobar 4000
15843         rmdir $DIR/$tdir
15844         kill -USR1 $MULTIPID
15845         wait $MULTIPID
15846         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15847         return 0
15848 }
15849 run_test 181 "Test open-unlinked dir ========================"
15850
15851 test_182() {
15852         local fcount=1000
15853         local tcount=10
15854
15855         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15856
15857         $LCTL set_param mdc.*.rpc_stats=clear
15858
15859         for (( i = 0; i < $tcount; i++ )) ; do
15860                 mkdir $DIR/$tdir/$i
15861         done
15862
15863         for (( i = 0; i < $tcount; i++ )) ; do
15864                 createmany -o $DIR/$tdir/$i/f- $fcount &
15865         done
15866         wait
15867
15868         for (( i = 0; i < $tcount; i++ )) ; do
15869                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15870         done
15871         wait
15872
15873         $LCTL get_param mdc.*.rpc_stats
15874
15875         rm -rf $DIR/$tdir
15876 }
15877 run_test 182 "Test parallel modify metadata operations ================"
15878
15879 test_183() { # LU-2275
15880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15881         remote_mds_nodsh && skip "remote MDS with nodsh"
15882         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15883                 skip "Need MDS version at least 2.3.56"
15884
15885         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15886         echo aaa > $DIR/$tdir/$tfile
15887
15888 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
15889         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
15890
15891         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
15892         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
15893
15894         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15895
15896         # Flush negative dentry cache
15897         touch $DIR/$tdir/$tfile
15898
15899         # We are not checking for any leaked references here, they'll
15900         # become evident next time we do cleanup with module unload.
15901         rm -rf $DIR/$tdir
15902 }
15903 run_test 183 "No crash or request leak in case of strange dispositions ========"
15904
15905 # test suite 184 is for LU-2016, LU-2017
15906 test_184a() {
15907         check_swap_layouts_support
15908
15909         dir0=$DIR/$tdir/$testnum
15910         test_mkdir -p -c1 $dir0
15911         ref1=/etc/passwd
15912         ref2=/etc/group
15913         file1=$dir0/f1
15914         file2=$dir0/f2
15915         $LFS setstripe -c1 $file1
15916         cp $ref1 $file1
15917         $LFS setstripe -c2 $file2
15918         cp $ref2 $file2
15919         gen1=$($LFS getstripe -g $file1)
15920         gen2=$($LFS getstripe -g $file2)
15921
15922         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
15923         gen=$($LFS getstripe -g $file1)
15924         [[ $gen1 != $gen ]] ||
15925                 "Layout generation on $file1 does not change"
15926         gen=$($LFS getstripe -g $file2)
15927         [[ $gen2 != $gen ]] ||
15928                 "Layout generation on $file2 does not change"
15929
15930         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
15931         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15932
15933         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
15934 }
15935 run_test 184a "Basic layout swap"
15936
15937 test_184b() {
15938         check_swap_layouts_support
15939
15940         dir0=$DIR/$tdir/$testnum
15941         mkdir -p $dir0 || error "creating dir $dir0"
15942         file1=$dir0/f1
15943         file2=$dir0/f2
15944         file3=$dir0/f3
15945         dir1=$dir0/d1
15946         dir2=$dir0/d2
15947         mkdir $dir1 $dir2
15948         $LFS setstripe -c1 $file1
15949         $LFS setstripe -c2 $file2
15950         $LFS setstripe -c1 $file3
15951         chown $RUNAS_ID $file3
15952         gen1=$($LFS getstripe -g $file1)
15953         gen2=$($LFS getstripe -g $file2)
15954
15955         $LFS swap_layouts $dir1 $dir2 &&
15956                 error "swap of directories layouts should fail"
15957         $LFS swap_layouts $dir1 $file1 &&
15958                 error "swap of directory and file layouts should fail"
15959         $RUNAS $LFS swap_layouts $file1 $file2 &&
15960                 error "swap of file we cannot write should fail"
15961         $LFS swap_layouts $file1 $file3 &&
15962                 error "swap of file with different owner should fail"
15963         /bin/true # to clear error code
15964 }
15965 run_test 184b "Forbidden layout swap (will generate errors)"
15966
15967 test_184c() {
15968         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
15969         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
15970         check_swap_layouts_support
15971         check_swap_layout_no_dom $DIR
15972
15973         local dir0=$DIR/$tdir/$testnum
15974         mkdir -p $dir0 || error "creating dir $dir0"
15975
15976         local ref1=$dir0/ref1
15977         local ref2=$dir0/ref2
15978         local file1=$dir0/file1
15979         local file2=$dir0/file2
15980         # create a file large enough for the concurrent test
15981         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
15982         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
15983         echo "ref file size: ref1($(stat -c %s $ref1))," \
15984              "ref2($(stat -c %s $ref2))"
15985
15986         cp $ref2 $file2
15987         dd if=$ref1 of=$file1 bs=16k &
15988         local DD_PID=$!
15989
15990         # Make sure dd starts to copy file
15991         while [ ! -f $file1 ]; do sleep 0.1; done
15992
15993         $LFS swap_layouts $file1 $file2
15994         local rc=$?
15995         wait $DD_PID
15996         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
15997         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
15998
15999         # how many bytes copied before swapping layout
16000         local copied=$(stat -c %s $file2)
16001         local remaining=$(stat -c %s $ref1)
16002         remaining=$((remaining - copied))
16003         echo "Copied $copied bytes before swapping layout..."
16004
16005         cmp -n $copied $file1 $ref2 | grep differ &&
16006                 error "Content mismatch [0, $copied) of ref2 and file1"
16007         cmp -n $copied $file2 $ref1 ||
16008                 error "Content mismatch [0, $copied) of ref1 and file2"
16009         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16010                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16011
16012         # clean up
16013         rm -f $ref1 $ref2 $file1 $file2
16014 }
16015 run_test 184c "Concurrent write and layout swap"
16016
16017 test_184d() {
16018         check_swap_layouts_support
16019         check_swap_layout_no_dom $DIR
16020         [ -z "$(which getfattr 2>/dev/null)" ] &&
16021                 skip_env "no getfattr command"
16022
16023         local file1=$DIR/$tdir/$tfile-1
16024         local file2=$DIR/$tdir/$tfile-2
16025         local file3=$DIR/$tdir/$tfile-3
16026         local lovea1
16027         local lovea2
16028
16029         mkdir -p $DIR/$tdir
16030         touch $file1 || error "create $file1 failed"
16031         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16032                 error "create $file2 failed"
16033         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16034                 error "create $file3 failed"
16035         lovea1=$(get_layout_param $file1)
16036
16037         $LFS swap_layouts $file2 $file3 ||
16038                 error "swap $file2 $file3 layouts failed"
16039         $LFS swap_layouts $file1 $file2 ||
16040                 error "swap $file1 $file2 layouts failed"
16041
16042         lovea2=$(get_layout_param $file2)
16043         echo "$lovea1"
16044         echo "$lovea2"
16045         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16046
16047         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16048         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16049 }
16050 run_test 184d "allow stripeless layouts swap"
16051
16052 test_184e() {
16053         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16054                 skip "Need MDS version at least 2.6.94"
16055         check_swap_layouts_support
16056         check_swap_layout_no_dom $DIR
16057         [ -z "$(which getfattr 2>/dev/null)" ] &&
16058                 skip_env "no getfattr command"
16059
16060         local file1=$DIR/$tdir/$tfile-1
16061         local file2=$DIR/$tdir/$tfile-2
16062         local file3=$DIR/$tdir/$tfile-3
16063         local lovea
16064
16065         mkdir -p $DIR/$tdir
16066         touch $file1 || error "create $file1 failed"
16067         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16068                 error "create $file2 failed"
16069         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16070                 error "create $file3 failed"
16071
16072         $LFS swap_layouts $file1 $file2 ||
16073                 error "swap $file1 $file2 layouts failed"
16074
16075         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16076         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16077
16078         echo 123 > $file1 || error "Should be able to write into $file1"
16079
16080         $LFS swap_layouts $file1 $file3 ||
16081                 error "swap $file1 $file3 layouts failed"
16082
16083         echo 123 > $file1 || error "Should be able to write into $file1"
16084
16085         rm -rf $file1 $file2 $file3
16086 }
16087 run_test 184e "Recreate layout after stripeless layout swaps"
16088
16089 test_184f() {
16090         # Create a file with name longer than sizeof(struct stat) ==
16091         # 144 to see if we can get chars from the file name to appear
16092         # in the returned striping. Note that 'f' == 0x66.
16093         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16094
16095         mkdir -p $DIR/$tdir
16096         mcreate $DIR/$tdir/$file
16097         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16098                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16099         fi
16100 }
16101 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16102
16103 test_185() { # LU-2441
16104         # LU-3553 - no volatile file support in old servers
16105         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16106                 skip "Need MDS version at least 2.3.60"
16107
16108         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16109         touch $DIR/$tdir/spoo
16110         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16111         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16112                 error "cannot create/write a volatile file"
16113         [ "$FILESET" == "" ] &&
16114         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16115                 error "FID is still valid after close"
16116
16117         multiop_bg_pause $DIR/$tdir vVw4096_c
16118         local multi_pid=$!
16119
16120         local OLD_IFS=$IFS
16121         IFS=":"
16122         local fidv=($fid)
16123         IFS=$OLD_IFS
16124         # assume that the next FID for this client is sequential, since stdout
16125         # is unfortunately eaten by multiop_bg_pause
16126         local n=$((${fidv[1]} + 1))
16127         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16128         if [ "$FILESET" == "" ]; then
16129                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16130                         error "FID is missing before close"
16131         fi
16132         kill -USR1 $multi_pid
16133         # 1 second delay, so if mtime change we will see it
16134         sleep 1
16135         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16136         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16137 }
16138 run_test 185 "Volatile file support"
16139
16140 function create_check_volatile() {
16141         local idx=$1
16142         local tgt
16143
16144         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16145         local PID=$!
16146         sleep 1
16147         local FID=$(cat /tmp/${tfile}.fid)
16148         [ "$FID" == "" ] && error "can't get FID for volatile"
16149         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16150         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16151         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16152         kill -USR1 $PID
16153         wait
16154         sleep 1
16155         cancel_lru_locks mdc # flush opencache
16156         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16157         return 0
16158 }
16159
16160 test_185a(){
16161         # LU-12516 - volatile creation via .lustre
16162         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16163                 skip "Need MDS version at least 2.3.55"
16164
16165         create_check_volatile 0
16166         [ $MDSCOUNT -lt 2 ] && return 0
16167
16168         # DNE case
16169         create_check_volatile 1
16170
16171         return 0
16172 }
16173 run_test 185a "Volatile file creation in .lustre/fid/"
16174
16175 test_187a() {
16176         remote_mds_nodsh && skip "remote MDS with nodsh"
16177         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16178                 skip "Need MDS version at least 2.3.0"
16179
16180         local dir0=$DIR/$tdir/$testnum
16181         mkdir -p $dir0 || error "creating dir $dir0"
16182
16183         local file=$dir0/file1
16184         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16185         local dv1=$($LFS data_version $file)
16186         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16187         local dv2=$($LFS data_version $file)
16188         [[ $dv1 != $dv2 ]] ||
16189                 error "data version did not change on write $dv1 == $dv2"
16190
16191         # clean up
16192         rm -f $file1
16193 }
16194 run_test 187a "Test data version change"
16195
16196 test_187b() {
16197         remote_mds_nodsh && skip "remote MDS with nodsh"
16198         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16199                 skip "Need MDS version at least 2.3.0"
16200
16201         local dir0=$DIR/$tdir/$testnum
16202         mkdir -p $dir0 || error "creating dir $dir0"
16203
16204         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16205         [[ ${DV[0]} != ${DV[1]} ]] ||
16206                 error "data version did not change on write"\
16207                       " ${DV[0]} == ${DV[1]}"
16208
16209         # clean up
16210         rm -f $file1
16211 }
16212 run_test 187b "Test data version change on volatile file"
16213
16214 test_200() {
16215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16216         remote_mgs_nodsh && skip "remote MGS with nodsh"
16217         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16218
16219         local POOL=${POOL:-cea1}
16220         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16221         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16222         # Pool OST targets
16223         local first_ost=0
16224         local last_ost=$(($OSTCOUNT - 1))
16225         local ost_step=2
16226         local ost_list=$(seq $first_ost $ost_step $last_ost)
16227         local ost_range="$first_ost $last_ost $ost_step"
16228         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16229         local file_dir=$POOL_ROOT/file_tst
16230         local subdir=$test_path/subdir
16231         local rc=0
16232
16233         while : ; do
16234                 # former test_200a test_200b
16235                 pool_add $POOL                          || { rc=$? ; break; }
16236                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16237                 # former test_200c test_200d
16238                 mkdir -p $test_path
16239                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16240                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16241                 mkdir -p $subdir
16242                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16243                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16244                                                         || { rc=$? ; break; }
16245                 # former test_200e test_200f
16246                 local files=$((OSTCOUNT*3))
16247                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16248                                                         || { rc=$? ; break; }
16249                 pool_create_files $POOL $file_dir $files "$ost_list" \
16250                                                         || { rc=$? ; break; }
16251                 # former test_200g test_200h
16252                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16253                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16254
16255                 # former test_201a test_201b test_201c
16256                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16257
16258                 local f=$test_path/$tfile
16259                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16260                 pool_remove $POOL $f                    || { rc=$? ; break; }
16261                 break
16262         done
16263
16264         destroy_test_pools
16265
16266         return $rc
16267 }
16268 run_test 200 "OST pools"
16269
16270 # usage: default_attr <count | size | offset>
16271 default_attr() {
16272         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16273 }
16274
16275 # usage: check_default_stripe_attr
16276 check_default_stripe_attr() {
16277         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16278         case $1 in
16279         --stripe-count|-c)
16280                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16281         --stripe-size|-S)
16282                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16283         --stripe-index|-i)
16284                 EXPECTED=-1;;
16285         *)
16286                 error "unknown getstripe attr '$1'"
16287         esac
16288
16289         [ $ACTUAL == $EXPECTED ] ||
16290                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16291 }
16292
16293 test_204a() {
16294         test_mkdir $DIR/$tdir
16295         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16296
16297         check_default_stripe_attr --stripe-count
16298         check_default_stripe_attr --stripe-size
16299         check_default_stripe_attr --stripe-index
16300 }
16301 run_test 204a "Print default stripe attributes"
16302
16303 test_204b() {
16304         test_mkdir $DIR/$tdir
16305         $LFS setstripe --stripe-count 1 $DIR/$tdir
16306
16307         check_default_stripe_attr --stripe-size
16308         check_default_stripe_attr --stripe-index
16309 }
16310 run_test 204b "Print default stripe size and offset"
16311
16312 test_204c() {
16313         test_mkdir $DIR/$tdir
16314         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16315
16316         check_default_stripe_attr --stripe-count
16317         check_default_stripe_attr --stripe-index
16318 }
16319 run_test 204c "Print default stripe count and offset"
16320
16321 test_204d() {
16322         test_mkdir $DIR/$tdir
16323         $LFS setstripe --stripe-index 0 $DIR/$tdir
16324
16325         check_default_stripe_attr --stripe-count
16326         check_default_stripe_attr --stripe-size
16327 }
16328 run_test 204d "Print default stripe count and size"
16329
16330 test_204e() {
16331         test_mkdir $DIR/$tdir
16332         $LFS setstripe -d $DIR/$tdir
16333
16334         check_default_stripe_attr --stripe-count --raw
16335         check_default_stripe_attr --stripe-size --raw
16336         check_default_stripe_attr --stripe-index --raw
16337 }
16338 run_test 204e "Print raw stripe attributes"
16339
16340 test_204f() {
16341         test_mkdir $DIR/$tdir
16342         $LFS setstripe --stripe-count 1 $DIR/$tdir
16343
16344         check_default_stripe_attr --stripe-size --raw
16345         check_default_stripe_attr --stripe-index --raw
16346 }
16347 run_test 204f "Print raw stripe size and offset"
16348
16349 test_204g() {
16350         test_mkdir $DIR/$tdir
16351         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16352
16353         check_default_stripe_attr --stripe-count --raw
16354         check_default_stripe_attr --stripe-index --raw
16355 }
16356 run_test 204g "Print raw stripe count and offset"
16357
16358 test_204h() {
16359         test_mkdir $DIR/$tdir
16360         $LFS setstripe --stripe-index 0 $DIR/$tdir
16361
16362         check_default_stripe_attr --stripe-count --raw
16363         check_default_stripe_attr --stripe-size --raw
16364 }
16365 run_test 204h "Print raw stripe count and size"
16366
16367 # Figure out which job scheduler is being used, if any,
16368 # or use a fake one
16369 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16370         JOBENV=SLURM_JOB_ID
16371 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16372         JOBENV=LSB_JOBID
16373 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16374         JOBENV=PBS_JOBID
16375 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16376         JOBENV=LOADL_STEP_ID
16377 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16378         JOBENV=JOB_ID
16379 else
16380         $LCTL list_param jobid_name > /dev/null 2>&1
16381         if [ $? -eq 0 ]; then
16382                 JOBENV=nodelocal
16383         else
16384                 JOBENV=FAKE_JOBID
16385         fi
16386 fi
16387 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16388
16389 verify_jobstats() {
16390         local cmd=($1)
16391         shift
16392         local facets="$@"
16393
16394 # we don't really need to clear the stats for this test to work, since each
16395 # command has a unique jobid, but it makes debugging easier if needed.
16396 #       for facet in $facets; do
16397 #               local dev=$(convert_facet2label $facet)
16398 #               # clear old jobstats
16399 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16400 #       done
16401
16402         # use a new JobID for each test, or we might see an old one
16403         [ "$JOBENV" = "FAKE_JOBID" ] &&
16404                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16405
16406         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16407
16408         [ "$JOBENV" = "nodelocal" ] && {
16409                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16410                 $LCTL set_param jobid_name=$FAKE_JOBID
16411                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16412         }
16413
16414         log "Test: ${cmd[*]}"
16415         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16416
16417         if [ $JOBENV = "FAKE_JOBID" ]; then
16418                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16419         else
16420                 ${cmd[*]}
16421         fi
16422
16423         # all files are created on OST0000
16424         for facet in $facets; do
16425                 local stats="*.$(convert_facet2label $facet).job_stats"
16426
16427                 # strip out libtool wrappers for in-tree executables
16428                 if [ $(do_facet $facet lctl get_param $stats |
16429                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16430                         do_facet $facet lctl get_param $stats
16431                         error "No jobstats for $JOBVAL found on $facet::$stats"
16432                 fi
16433         done
16434 }
16435
16436 jobstats_set() {
16437         local new_jobenv=$1
16438
16439         set_persistent_param_and_check client "jobid_var" \
16440                 "$FSNAME.sys.jobid_var" $new_jobenv
16441 }
16442
16443 test_205a() { # Job stats
16444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16445         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16446                 skip "Need MDS version with at least 2.7.1"
16447         remote_mgs_nodsh && skip "remote MGS with nodsh"
16448         remote_mds_nodsh && skip "remote MDS with nodsh"
16449         remote_ost_nodsh && skip "remote OST with nodsh"
16450         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16451                 skip "Server doesn't support jobstats"
16452         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16453
16454         local old_jobenv=$($LCTL get_param -n jobid_var)
16455         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16456
16457         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16458                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16459         else
16460                 stack_trap "do_facet mgs $PERM_CMD \
16461                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16462         fi
16463         changelog_register
16464
16465         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16466                                 mdt.*.job_cleanup_interval | head -n 1)
16467         local new_interval=5
16468         do_facet $SINGLEMDS \
16469                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16470         stack_trap "do_facet $SINGLEMDS \
16471                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16472         local start=$SECONDS
16473
16474         local cmd
16475         # mkdir
16476         cmd="mkdir $DIR/$tdir"
16477         verify_jobstats "$cmd" "$SINGLEMDS"
16478         # rmdir
16479         cmd="rmdir $DIR/$tdir"
16480         verify_jobstats "$cmd" "$SINGLEMDS"
16481         # mkdir on secondary MDT
16482         if [ $MDSCOUNT -gt 1 ]; then
16483                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16484                 verify_jobstats "$cmd" "mds2"
16485         fi
16486         # mknod
16487         cmd="mknod $DIR/$tfile c 1 3"
16488         verify_jobstats "$cmd" "$SINGLEMDS"
16489         # unlink
16490         cmd="rm -f $DIR/$tfile"
16491         verify_jobstats "$cmd" "$SINGLEMDS"
16492         # create all files on OST0000 so verify_jobstats can find OST stats
16493         # open & close
16494         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16495         verify_jobstats "$cmd" "$SINGLEMDS"
16496         # setattr
16497         cmd="touch $DIR/$tfile"
16498         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16499         # write
16500         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16501         verify_jobstats "$cmd" "ost1"
16502         # read
16503         cancel_lru_locks osc
16504         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16505         verify_jobstats "$cmd" "ost1"
16506         # truncate
16507         cmd="$TRUNCATE $DIR/$tfile 0"
16508         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16509         # rename
16510         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16511         verify_jobstats "$cmd" "$SINGLEMDS"
16512         # jobstats expiry - sleep until old stats should be expired
16513         local left=$((new_interval + 5 - (SECONDS - start)))
16514         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16515                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16516                         "0" $left
16517         cmd="mkdir $DIR/$tdir.expire"
16518         verify_jobstats "$cmd" "$SINGLEMDS"
16519         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16520             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16521
16522         # Ensure that jobid are present in changelog (if supported by MDS)
16523         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16524                 changelog_dump | tail -10
16525                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16526                 [ $jobids -eq 9 ] ||
16527                         error "Wrong changelog jobid count $jobids != 9"
16528
16529                 # LU-5862
16530                 JOBENV="disable"
16531                 jobstats_set $JOBENV
16532                 touch $DIR/$tfile
16533                 changelog_dump | grep $tfile
16534                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16535                 [ $jobids -eq 0 ] ||
16536                         error "Unexpected jobids when jobid_var=$JOBENV"
16537         fi
16538
16539         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
16540         JOBENV="JOBCOMPLEX"
16541         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16542
16543         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16544 }
16545 run_test 205a "Verify job stats"
16546
16547 # LU-13117, LU-13597
16548 test_205b() {
16549         job_stats="mdt.*.job_stats"
16550         $LCTL set_param $job_stats=clear
16551         $LCTL set_param jobid_var=USER jobid_name="%e.%u"
16552         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16553         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16554                 grep "job_id:.*foolish" &&
16555                         error "Unexpected jobid found"
16556         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16557                 grep "open:.*min.*max.*sum" ||
16558                         error "wrong job_stats format found"
16559 }
16560 run_test 205b "Verify job stats jobid and output format"
16561
16562 # LU-13733
16563 test_205c() {
16564         $LCTL set_param llite.*.stats=0
16565         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16566         $LCTL get_param llite.*.stats
16567         $LCTL get_param llite.*.stats | grep \
16568                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16569                         error "wrong client stats format found"
16570 }
16571 run_test 205c "Verify client stats format"
16572
16573 # LU-1480, LU-1773 and LU-1657
16574 test_206() {
16575         mkdir -p $DIR/$tdir
16576         $LFS setstripe -c -1 $DIR/$tdir
16577 #define OBD_FAIL_LOV_INIT 0x1403
16578         $LCTL set_param fail_loc=0xa0001403
16579         $LCTL set_param fail_val=1
16580         touch $DIR/$tdir/$tfile || true
16581 }
16582 run_test 206 "fail lov_init_raid0() doesn't lbug"
16583
16584 test_207a() {
16585         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16586         local fsz=`stat -c %s $DIR/$tfile`
16587         cancel_lru_locks mdc
16588
16589         # do not return layout in getattr intent
16590 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16591         $LCTL set_param fail_loc=0x170
16592         local sz=`stat -c %s $DIR/$tfile`
16593
16594         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16595
16596         rm -rf $DIR/$tfile
16597 }
16598 run_test 207a "can refresh layout at glimpse"
16599
16600 test_207b() {
16601         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16602         local cksum=`md5sum $DIR/$tfile`
16603         local fsz=`stat -c %s $DIR/$tfile`
16604         cancel_lru_locks mdc
16605         cancel_lru_locks osc
16606
16607         # do not return layout in getattr intent
16608 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16609         $LCTL set_param fail_loc=0x171
16610
16611         # it will refresh layout after the file is opened but before read issues
16612         echo checksum is "$cksum"
16613         echo "$cksum" |md5sum -c --quiet || error "file differs"
16614
16615         rm -rf $DIR/$tfile
16616 }
16617 run_test 207b "can refresh layout at open"
16618
16619 test_208() {
16620         # FIXME: in this test suite, only RD lease is used. This is okay
16621         # for now as only exclusive open is supported. After generic lease
16622         # is done, this test suite should be revised. - Jinshan
16623
16624         remote_mds_nodsh && skip "remote MDS with nodsh"
16625         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16626                 skip "Need MDS version at least 2.4.52"
16627
16628         echo "==== test 1: verify get lease work"
16629         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16630
16631         echo "==== test 2: verify lease can be broken by upcoming open"
16632         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16633         local PID=$!
16634         sleep 1
16635
16636         $MULTIOP $DIR/$tfile oO_RDONLY:c
16637         kill -USR1 $PID && wait $PID || error "break lease error"
16638
16639         echo "==== test 3: verify lease can't be granted if an open already exists"
16640         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16641         local PID=$!
16642         sleep 1
16643
16644         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16645         kill -USR1 $PID && wait $PID || error "open file error"
16646
16647         echo "==== test 4: lease can sustain over recovery"
16648         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16649         PID=$!
16650         sleep 1
16651
16652         fail mds1
16653
16654         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16655
16656         echo "==== test 5: lease broken can't be regained by replay"
16657         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16658         PID=$!
16659         sleep 1
16660
16661         # open file to break lease and then recovery
16662         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16663         fail mds1
16664
16665         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16666
16667         rm -f $DIR/$tfile
16668 }
16669 run_test 208 "Exclusive open"
16670
16671 test_209() {
16672         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16673                 skip_env "must have disp_stripe"
16674
16675         touch $DIR/$tfile
16676         sync; sleep 5; sync;
16677
16678         echo 3 > /proc/sys/vm/drop_caches
16679         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16680                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16681         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16682
16683         # open/close 500 times
16684         for i in $(seq 500); do
16685                 cat $DIR/$tfile
16686         done
16687
16688         echo 3 > /proc/sys/vm/drop_caches
16689         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16690                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16691         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16692
16693         echo "before: $req_before, after: $req_after"
16694         [ $((req_after - req_before)) -ge 300 ] &&
16695                 error "open/close requests are not freed"
16696         return 0
16697 }
16698 run_test 209 "read-only open/close requests should be freed promptly"
16699
16700 test_210() {
16701         local pid
16702
16703         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16704         pid=$!
16705         sleep 1
16706
16707         $LFS getstripe $DIR/$tfile
16708         kill -USR1 $pid
16709         wait $pid || error "multiop failed"
16710
16711         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16712         pid=$!
16713         sleep 1
16714
16715         $LFS getstripe $DIR/$tfile
16716         kill -USR1 $pid
16717         wait $pid || error "multiop failed"
16718 }
16719 run_test 210 "lfs getstripe does not break leases"
16720
16721 test_212() {
16722         size=`date +%s`
16723         size=$((size % 8192 + 1))
16724         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16725         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16726         rm -f $DIR/f212 $DIR/f212.xyz
16727 }
16728 run_test 212 "Sendfile test ============================================"
16729
16730 test_213() {
16731         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16732         cancel_lru_locks osc
16733         lctl set_param fail_loc=0x8000040f
16734         # generate a read lock
16735         cat $DIR/$tfile > /dev/null
16736         # write to the file, it will try to cancel the above read lock.
16737         cat /etc/hosts >> $DIR/$tfile
16738 }
16739 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16740
16741 test_214() { # for bug 20133
16742         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16743         for (( i=0; i < 340; i++ )) ; do
16744                 touch $DIR/$tdir/d214c/a$i
16745         done
16746
16747         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16748         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16749         ls $DIR/d214c || error "ls $DIR/d214c failed"
16750         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16751         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16752 }
16753 run_test 214 "hash-indexed directory test - bug 20133"
16754
16755 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16756 create_lnet_proc_files() {
16757         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16758 }
16759
16760 # counterpart of create_lnet_proc_files
16761 remove_lnet_proc_files() {
16762         rm -f $TMP/lnet_$1.sys
16763 }
16764
16765 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16766 # 3rd arg as regexp for body
16767 check_lnet_proc_stats() {
16768         local l=$(cat "$TMP/lnet_$1" |wc -l)
16769         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16770
16771         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16772 }
16773
16774 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16775 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16776 # optional and can be regexp for 2nd line (lnet.routes case)
16777 check_lnet_proc_entry() {
16778         local blp=2          # blp stands for 'position of 1st line of body'
16779         [ -z "$5" ] || blp=3 # lnet.routes case
16780
16781         local l=$(cat "$TMP/lnet_$1" |wc -l)
16782         # subtracting one from $blp because the body can be empty
16783         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16784
16785         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16786                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16787
16788         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16789                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16790
16791         # bail out if any unexpected line happened
16792         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16793         [ "$?" != 0 ] || error "$2 misformatted"
16794 }
16795
16796 test_215() { # for bugs 18102, 21079, 21517
16797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16798
16799         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16800         local P='[1-9][0-9]*'           # positive numeric
16801         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16802         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16803         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16804         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16805
16806         local L1 # regexp for 1st line
16807         local L2 # regexp for 2nd line (optional)
16808         local BR # regexp for the rest (body)
16809
16810         # lnet.stats should look as 11 space-separated non-negative numerics
16811         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16812         create_lnet_proc_files "stats"
16813         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16814         remove_lnet_proc_files "stats"
16815
16816         # lnet.routes should look like this:
16817         # Routing disabled/enabled
16818         # net hops priority state router
16819         # where net is a string like tcp0, hops > 0, priority >= 0,
16820         # state is up/down,
16821         # router is a string like 192.168.1.1@tcp2
16822         L1="^Routing (disabled|enabled)$"
16823         L2="^net +hops +priority +state +router$"
16824         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16825         create_lnet_proc_files "routes"
16826         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16827         remove_lnet_proc_files "routes"
16828
16829         # lnet.routers should look like this:
16830         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16831         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16832         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16833         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16834         L1="^ref +rtr_ref +alive +router$"
16835         BR="^$P +$P +(up|down) +$NID$"
16836         create_lnet_proc_files "routers"
16837         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16838         remove_lnet_proc_files "routers"
16839
16840         # lnet.peers should look like this:
16841         # nid refs state last max rtr min tx min queue
16842         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16843         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16844         # numeric (0 or >0 or <0), queue >= 0.
16845         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16846         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16847         create_lnet_proc_files "peers"
16848         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16849         remove_lnet_proc_files "peers"
16850
16851         # lnet.buffers  should look like this:
16852         # pages count credits min
16853         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16854         L1="^pages +count +credits +min$"
16855         BR="^ +$N +$N +$I +$I$"
16856         create_lnet_proc_files "buffers"
16857         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16858         remove_lnet_proc_files "buffers"
16859
16860         # lnet.nis should look like this:
16861         # nid status alive refs peer rtr max tx min
16862         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16863         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16864         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16865         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16866         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16867         create_lnet_proc_files "nis"
16868         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16869         remove_lnet_proc_files "nis"
16870
16871         # can we successfully write to lnet.stats?
16872         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
16873 }
16874 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
16875
16876 test_216() { # bug 20317
16877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16878         remote_ost_nodsh && skip "remote OST with nodsh"
16879
16880         local node
16881         local facets=$(get_facets OST)
16882         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16883
16884         save_lustre_params client "osc.*.contention_seconds" > $p
16885         save_lustre_params $facets \
16886                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
16887         save_lustre_params $facets \
16888                 "ldlm.namespaces.filter-*.contended_locks" >> $p
16889         save_lustre_params $facets \
16890                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
16891         clear_stats osc.*.osc_stats
16892
16893         # agressive lockless i/o settings
16894         do_nodes $(comma_list $(osts_nodes)) \
16895                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
16896                         ldlm.namespaces.filter-*.contended_locks=0 \
16897                         ldlm.namespaces.filter-*.contention_seconds=60"
16898         lctl set_param -n osc.*.contention_seconds=60
16899
16900         $DIRECTIO write $DIR/$tfile 0 10 4096
16901         $CHECKSTAT -s 40960 $DIR/$tfile
16902
16903         # disable lockless i/o
16904         do_nodes $(comma_list $(osts_nodes)) \
16905                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
16906                         ldlm.namespaces.filter-*.contended_locks=32 \
16907                         ldlm.namespaces.filter-*.contention_seconds=0"
16908         lctl set_param -n osc.*.contention_seconds=0
16909         clear_stats osc.*.osc_stats
16910
16911         dd if=/dev/zero of=$DIR/$tfile count=0
16912         $CHECKSTAT -s 0 $DIR/$tfile
16913
16914         restore_lustre_params <$p
16915         rm -f $p
16916         rm $DIR/$tfile
16917 }
16918 run_test 216 "check lockless direct write updates file size and kms correctly"
16919
16920 test_217() { # bug 22430
16921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16922
16923         local node
16924         local nid
16925
16926         for node in $(nodes_list); do
16927                 nid=$(host_nids_address $node $NETTYPE)
16928                 if [[ $nid = *-* ]] ; then
16929                         echo "lctl ping $(h2nettype $nid)"
16930                         lctl ping $(h2nettype $nid)
16931                 else
16932                         echo "skipping $node (no hyphen detected)"
16933                 fi
16934         done
16935 }
16936 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
16937
16938 test_218() {
16939        # do directio so as not to populate the page cache
16940        log "creating a 10 Mb file"
16941        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
16942        log "starting reads"
16943        dd if=$DIR/$tfile of=/dev/null bs=4096 &
16944        log "truncating the file"
16945        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
16946        log "killing dd"
16947        kill %+ || true # reads might have finished
16948        echo "wait until dd is finished"
16949        wait
16950        log "removing the temporary file"
16951        rm -rf $DIR/$tfile || error "tmp file removal failed"
16952 }
16953 run_test 218 "parallel read and truncate should not deadlock"
16954
16955 test_219() {
16956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16957
16958         # write one partial page
16959         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
16960         # set no grant so vvp_io_commit_write will do sync write
16961         $LCTL set_param fail_loc=0x411
16962         # write a full page at the end of file
16963         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
16964
16965         $LCTL set_param fail_loc=0
16966         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
16967         $LCTL set_param fail_loc=0x411
16968         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
16969
16970         # LU-4201
16971         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
16972         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
16973 }
16974 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
16975
16976 test_220() { #LU-325
16977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16978         remote_ost_nodsh && skip "remote OST with nodsh"
16979         remote_mds_nodsh && skip "remote MDS with nodsh"
16980         remote_mgs_nodsh && skip "remote MGS with nodsh"
16981
16982         local OSTIDX=0
16983
16984         # create on MDT0000 so the last_id and next_id are correct
16985         mkdir $DIR/$tdir
16986         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
16987         OST=${OST%_UUID}
16988
16989         # on the mdt's osc
16990         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
16991         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
16992                         osp.$mdtosc_proc1.prealloc_last_id)
16993         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
16994                         osp.$mdtosc_proc1.prealloc_next_id)
16995
16996         $LFS df -i
16997
16998         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
16999         #define OBD_FAIL_OST_ENOINO              0x229
17000         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17001         create_pool $FSNAME.$TESTNAME || return 1
17002         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17003
17004         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17005
17006         MDSOBJS=$((last_id - next_id))
17007         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17008
17009         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17010         echo "OST still has $count kbytes free"
17011
17012         echo "create $MDSOBJS files @next_id..."
17013         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17014
17015         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17016                         osp.$mdtosc_proc1.prealloc_last_id)
17017         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17018                         osp.$mdtosc_proc1.prealloc_next_id)
17019
17020         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17021         $LFS df -i
17022
17023         echo "cleanup..."
17024
17025         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17026         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17027
17028         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17029                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17030         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17031                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17032         echo "unlink $MDSOBJS files @$next_id..."
17033         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17034 }
17035 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17036
17037 test_221() {
17038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17039
17040         dd if=`which date` of=$MOUNT/date oflag=sync
17041         chmod +x $MOUNT/date
17042
17043         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17044         $LCTL set_param fail_loc=0x80001401
17045
17046         $MOUNT/date > /dev/null
17047         rm -f $MOUNT/date
17048 }
17049 run_test 221 "make sure fault and truncate race to not cause OOM"
17050
17051 test_222a () {
17052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17053
17054         rm -rf $DIR/$tdir
17055         test_mkdir $DIR/$tdir
17056         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17057         createmany -o $DIR/$tdir/$tfile 10
17058         cancel_lru_locks mdc
17059         cancel_lru_locks osc
17060         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17061         $LCTL set_param fail_loc=0x31a
17062         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17063         $LCTL set_param fail_loc=0
17064         rm -r $DIR/$tdir
17065 }
17066 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17067
17068 test_222b () {
17069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17070
17071         rm -rf $DIR/$tdir
17072         test_mkdir $DIR/$tdir
17073         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17074         createmany -o $DIR/$tdir/$tfile 10
17075         cancel_lru_locks mdc
17076         cancel_lru_locks osc
17077         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17078         $LCTL set_param fail_loc=0x31a
17079         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17080         $LCTL set_param fail_loc=0
17081 }
17082 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17083
17084 test_223 () {
17085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17086
17087         rm -rf $DIR/$tdir
17088         test_mkdir $DIR/$tdir
17089         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17090         createmany -o $DIR/$tdir/$tfile 10
17091         cancel_lru_locks mdc
17092         cancel_lru_locks osc
17093         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17094         $LCTL set_param fail_loc=0x31b
17095         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17096         $LCTL set_param fail_loc=0
17097         rm -r $DIR/$tdir
17098 }
17099 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17100
17101 test_224a() { # LU-1039, MRP-303
17102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17103
17104         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17105         $LCTL set_param fail_loc=0x508
17106         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17107         $LCTL set_param fail_loc=0
17108         df $DIR
17109 }
17110 run_test 224a "Don't panic on bulk IO failure"
17111
17112 test_224b() { # LU-1039, MRP-303
17113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17114
17115         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17116         cancel_lru_locks osc
17117         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17118         $LCTL set_param fail_loc=0x515
17119         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17120         $LCTL set_param fail_loc=0
17121         df $DIR
17122 }
17123 run_test 224b "Don't panic on bulk IO failure"
17124
17125 test_224c() { # LU-6441
17126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17127         remote_mds_nodsh && skip "remote MDS with nodsh"
17128
17129         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17130         save_writethrough $p
17131         set_cache writethrough on
17132
17133         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17134         local at_max=$($LCTL get_param -n at_max)
17135         local timeout=$($LCTL get_param -n timeout)
17136         local test_at="at_max"
17137         local param_at="$FSNAME.sys.at_max"
17138         local test_timeout="timeout"
17139         local param_timeout="$FSNAME.sys.timeout"
17140
17141         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17142
17143         set_persistent_param_and_check client "$test_at" "$param_at" 0
17144         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17145
17146         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17147         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17148         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17149         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17150         sync
17151         do_facet ost1 "$LCTL set_param fail_loc=0"
17152
17153         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17154         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17155                 $timeout
17156
17157         $LCTL set_param -n $pages_per_rpc
17158         restore_lustre_params < $p
17159         rm -f $p
17160 }
17161 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17162
17163 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17164 test_225a () {
17165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17166         if [ -z ${MDSSURVEY} ]; then
17167                 skip_env "mds-survey not found"
17168         fi
17169         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17170                 skip "Need MDS version at least 2.2.51"
17171
17172         local mds=$(facet_host $SINGLEMDS)
17173         local target=$(do_nodes $mds 'lctl dl' |
17174                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17175
17176         local cmd1="file_count=1000 thrhi=4"
17177         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17178         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17179         local cmd="$cmd1 $cmd2 $cmd3"
17180
17181         rm -f ${TMP}/mds_survey*
17182         echo + $cmd
17183         eval $cmd || error "mds-survey with zero-stripe failed"
17184         cat ${TMP}/mds_survey*
17185         rm -f ${TMP}/mds_survey*
17186 }
17187 run_test 225a "Metadata survey sanity with zero-stripe"
17188
17189 test_225b () {
17190         if [ -z ${MDSSURVEY} ]; then
17191                 skip_env "mds-survey not found"
17192         fi
17193         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17194                 skip "Need MDS version at least 2.2.51"
17195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17196         remote_mds_nodsh && skip "remote MDS with nodsh"
17197         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17198                 skip_env "Need to mount OST to test"
17199         fi
17200
17201         local mds=$(facet_host $SINGLEMDS)
17202         local target=$(do_nodes $mds 'lctl dl' |
17203                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17204
17205         local cmd1="file_count=1000 thrhi=4"
17206         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17207         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17208         local cmd="$cmd1 $cmd2 $cmd3"
17209
17210         rm -f ${TMP}/mds_survey*
17211         echo + $cmd
17212         eval $cmd || error "mds-survey with stripe_count failed"
17213         cat ${TMP}/mds_survey*
17214         rm -f ${TMP}/mds_survey*
17215 }
17216 run_test 225b "Metadata survey sanity with stripe_count = 1"
17217
17218 mcreate_path2fid () {
17219         local mode=$1
17220         local major=$2
17221         local minor=$3
17222         local name=$4
17223         local desc=$5
17224         local path=$DIR/$tdir/$name
17225         local fid
17226         local rc
17227         local fid_path
17228
17229         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17230                 error "cannot create $desc"
17231
17232         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17233         rc=$?
17234         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17235
17236         fid_path=$($LFS fid2path $MOUNT $fid)
17237         rc=$?
17238         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17239
17240         [ "$path" == "$fid_path" ] ||
17241                 error "fid2path returned $fid_path, expected $path"
17242
17243         echo "pass with $path and $fid"
17244 }
17245
17246 test_226a () {
17247         rm -rf $DIR/$tdir
17248         mkdir -p $DIR/$tdir
17249
17250         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17251         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17252         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17253         mcreate_path2fid 0040666 0 0 dir "directory"
17254         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17255         mcreate_path2fid 0100666 0 0 file "regular file"
17256         mcreate_path2fid 0120666 0 0 link "symbolic link"
17257         mcreate_path2fid 0140666 0 0 sock "socket"
17258 }
17259 run_test 226a "call path2fid and fid2path on files of all type"
17260
17261 test_226b () {
17262         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17263
17264         local MDTIDX=1
17265
17266         rm -rf $DIR/$tdir
17267         mkdir -p $DIR/$tdir
17268         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17269                 error "create remote directory failed"
17270         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17271         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17272                                 "character special file (null)"
17273         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17274                                 "character special file (no device)"
17275         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17276         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17277                                 "block special file (loop)"
17278         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17279         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17280         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17281 }
17282 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17283
17284 test_226c () {
17285         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17286         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17287                 skip "Need MDS version at least 2.13.55"
17288
17289         local submnt=/mnt/submnt
17290         local srcfile=/etc/passwd
17291         local dstfile=$submnt/passwd
17292         local path
17293         local fid
17294
17295         rm -rf $DIR/$tdir
17296         rm -rf $submnt
17297         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17298                 error "create remote directory failed"
17299         mkdir -p $submnt || error "create $submnt failed"
17300         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17301                 error "mount $submnt failed"
17302         stack_trap "umount $submnt" EXIT
17303
17304         cp $srcfile $dstfile
17305         fid=$($LFS path2fid $dstfile)
17306         path=$($LFS fid2path $submnt "$fid")
17307         [ "$path" = "$dstfile" ] ||
17308                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17309 }
17310 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17311
17312 # LU-1299 Executing or running ldd on a truncated executable does not
17313 # cause an out-of-memory condition.
17314 test_227() {
17315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17316         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17317
17318         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17319         chmod +x $MOUNT/date
17320
17321         $MOUNT/date > /dev/null
17322         ldd $MOUNT/date > /dev/null
17323         rm -f $MOUNT/date
17324 }
17325 run_test 227 "running truncated executable does not cause OOM"
17326
17327 # LU-1512 try to reuse idle OI blocks
17328 test_228a() {
17329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17330         remote_mds_nodsh && skip "remote MDS with nodsh"
17331         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17332
17333         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17334         local myDIR=$DIR/$tdir
17335
17336         mkdir -p $myDIR
17337         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17338         $LCTL set_param fail_loc=0x80001002
17339         createmany -o $myDIR/t- 10000
17340         $LCTL set_param fail_loc=0
17341         # The guard is current the largest FID holder
17342         touch $myDIR/guard
17343         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17344                     tr -d '[')
17345         local IDX=$(($SEQ % 64))
17346
17347         do_facet $SINGLEMDS sync
17348         # Make sure journal flushed.
17349         sleep 6
17350         local blk1=$(do_facet $SINGLEMDS \
17351                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17352                      grep Blockcount | awk '{print $4}')
17353
17354         # Remove old files, some OI blocks will become idle.
17355         unlinkmany $myDIR/t- 10000
17356         # Create new files, idle OI blocks should be reused.
17357         createmany -o $myDIR/t- 2000
17358         do_facet $SINGLEMDS sync
17359         # Make sure journal flushed.
17360         sleep 6
17361         local blk2=$(do_facet $SINGLEMDS \
17362                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17363                      grep Blockcount | awk '{print $4}')
17364
17365         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17366 }
17367 run_test 228a "try to reuse idle OI blocks"
17368
17369 test_228b() {
17370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17371         remote_mds_nodsh && skip "remote MDS with nodsh"
17372         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17373
17374         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17375         local myDIR=$DIR/$tdir
17376
17377         mkdir -p $myDIR
17378         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17379         $LCTL set_param fail_loc=0x80001002
17380         createmany -o $myDIR/t- 10000
17381         $LCTL set_param fail_loc=0
17382         # The guard is current the largest FID holder
17383         touch $myDIR/guard
17384         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17385                     tr -d '[')
17386         local IDX=$(($SEQ % 64))
17387
17388         do_facet $SINGLEMDS sync
17389         # Make sure journal flushed.
17390         sleep 6
17391         local blk1=$(do_facet $SINGLEMDS \
17392                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17393                      grep Blockcount | awk '{print $4}')
17394
17395         # Remove old files, some OI blocks will become idle.
17396         unlinkmany $myDIR/t- 10000
17397
17398         # stop the MDT
17399         stop $SINGLEMDS || error "Fail to stop MDT."
17400         # remount the MDT
17401         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17402
17403         df $MOUNT || error "Fail to df."
17404         # Create new files, idle OI blocks should be reused.
17405         createmany -o $myDIR/t- 2000
17406         do_facet $SINGLEMDS sync
17407         # Make sure journal flushed.
17408         sleep 6
17409         local blk2=$(do_facet $SINGLEMDS \
17410                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17411                      grep Blockcount | awk '{print $4}')
17412
17413         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17414 }
17415 run_test 228b "idle OI blocks can be reused after MDT restart"
17416
17417 #LU-1881
17418 test_228c() {
17419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17420         remote_mds_nodsh && skip "remote MDS with nodsh"
17421         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17422
17423         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17424         local myDIR=$DIR/$tdir
17425
17426         mkdir -p $myDIR
17427         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17428         $LCTL set_param fail_loc=0x80001002
17429         # 20000 files can guarantee there are index nodes in the OI file
17430         createmany -o $myDIR/t- 20000
17431         $LCTL set_param fail_loc=0
17432         # The guard is current the largest FID holder
17433         touch $myDIR/guard
17434         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17435                     tr -d '[')
17436         local IDX=$(($SEQ % 64))
17437
17438         do_facet $SINGLEMDS sync
17439         # Make sure journal flushed.
17440         sleep 6
17441         local blk1=$(do_facet $SINGLEMDS \
17442                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17443                      grep Blockcount | awk '{print $4}')
17444
17445         # Remove old files, some OI blocks will become idle.
17446         unlinkmany $myDIR/t- 20000
17447         rm -f $myDIR/guard
17448         # The OI file should become empty now
17449
17450         # Create new files, idle OI blocks should be reused.
17451         createmany -o $myDIR/t- 2000
17452         do_facet $SINGLEMDS sync
17453         # Make sure journal flushed.
17454         sleep 6
17455         local blk2=$(do_facet $SINGLEMDS \
17456                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17457                      grep Blockcount | awk '{print $4}')
17458
17459         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17460 }
17461 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17462
17463 test_229() { # LU-2482, LU-3448
17464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17465         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17466         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17467                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17468
17469         rm -f $DIR/$tfile
17470
17471         # Create a file with a released layout and stripe count 2.
17472         $MULTIOP $DIR/$tfile H2c ||
17473                 error "failed to create file with released layout"
17474
17475         $LFS getstripe -v $DIR/$tfile
17476
17477         local pattern=$($LFS getstripe -L $DIR/$tfile)
17478         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17479
17480         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17481                 error "getstripe"
17482         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17483         stat $DIR/$tfile || error "failed to stat released file"
17484
17485         chown $RUNAS_ID $DIR/$tfile ||
17486                 error "chown $RUNAS_ID $DIR/$tfile failed"
17487
17488         chgrp $RUNAS_ID $DIR/$tfile ||
17489                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17490
17491         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17492         rm $DIR/$tfile || error "failed to remove released file"
17493 }
17494 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17495
17496 test_230a() {
17497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17498         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17499         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17500                 skip "Need MDS version at least 2.11.52"
17501
17502         local MDTIDX=1
17503
17504         test_mkdir $DIR/$tdir
17505         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17506         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17507         [ $mdt_idx -ne 0 ] &&
17508                 error "create local directory on wrong MDT $mdt_idx"
17509
17510         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17511                         error "create remote directory failed"
17512         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17513         [ $mdt_idx -ne $MDTIDX ] &&
17514                 error "create remote directory on wrong MDT $mdt_idx"
17515
17516         createmany -o $DIR/$tdir/test_230/t- 10 ||
17517                 error "create files on remote directory failed"
17518         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17519         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17520         rm -r $DIR/$tdir || error "unlink remote directory failed"
17521 }
17522 run_test 230a "Create remote directory and files under the remote directory"
17523
17524 test_230b() {
17525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17526         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17527         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17528                 skip "Need MDS version at least 2.11.52"
17529
17530         local MDTIDX=1
17531         local mdt_index
17532         local i
17533         local file
17534         local pid
17535         local stripe_count
17536         local migrate_dir=$DIR/$tdir/migrate_dir
17537         local other_dir=$DIR/$tdir/other_dir
17538
17539         test_mkdir $DIR/$tdir
17540         test_mkdir -i0 -c1 $migrate_dir
17541         test_mkdir -i0 -c1 $other_dir
17542         for ((i=0; i<10; i++)); do
17543                 mkdir -p $migrate_dir/dir_${i}
17544                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17545                         error "create files under remote dir failed $i"
17546         done
17547
17548         cp /etc/passwd $migrate_dir/$tfile
17549         cp /etc/passwd $other_dir/$tfile
17550         chattr +SAD $migrate_dir
17551         chattr +SAD $migrate_dir/$tfile
17552
17553         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17554         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17555         local old_dir_mode=$(stat -c%f $migrate_dir)
17556         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17557
17558         mkdir -p $migrate_dir/dir_default_stripe2
17559         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17560         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17561
17562         mkdir -p $other_dir
17563         ln $migrate_dir/$tfile $other_dir/luna
17564         ln $migrate_dir/$tfile $migrate_dir/sofia
17565         ln $other_dir/$tfile $migrate_dir/david
17566         ln -s $migrate_dir/$tfile $other_dir/zachary
17567         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17568         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17569
17570         local len
17571         local lnktgt
17572
17573         # inline symlink
17574         for len in 58 59 60; do
17575                 lnktgt=$(str_repeat 'l' $len)
17576                 touch $migrate_dir/$lnktgt
17577                 ln -s $lnktgt $migrate_dir/${len}char_ln
17578         done
17579
17580         # PATH_MAX
17581         for len in 4094 4095; do
17582                 lnktgt=$(str_repeat 'l' $len)
17583                 ln -s $lnktgt $migrate_dir/${len}char_ln
17584         done
17585
17586         # NAME_MAX
17587         for len in 254 255; do
17588                 touch $migrate_dir/$(str_repeat 'l' $len)
17589         done
17590
17591         $LFS migrate -m $MDTIDX $migrate_dir ||
17592                 error "fails on migrating remote dir to MDT1"
17593
17594         echo "migratate to MDT1, then checking.."
17595         for ((i = 0; i < 10; i++)); do
17596                 for file in $(find $migrate_dir/dir_${i}); do
17597                         mdt_index=$($LFS getstripe -m $file)
17598                         # broken symlink getstripe will fail
17599                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17600                                 error "$file is not on MDT${MDTIDX}"
17601                 done
17602         done
17603
17604         # the multiple link file should still in MDT0
17605         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17606         [ $mdt_index == 0 ] ||
17607                 error "$file is not on MDT${MDTIDX}"
17608
17609         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17610         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17611                 error " expect $old_dir_flag get $new_dir_flag"
17612
17613         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17614         [ "$old_file_flag" = "$new_file_flag" ] ||
17615                 error " expect $old_file_flag get $new_file_flag"
17616
17617         local new_dir_mode=$(stat -c%f $migrate_dir)
17618         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17619                 error "expect mode $old_dir_mode get $new_dir_mode"
17620
17621         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17622         [ "$old_file_mode" = "$new_file_mode" ] ||
17623                 error "expect mode $old_file_mode get $new_file_mode"
17624
17625         diff /etc/passwd $migrate_dir/$tfile ||
17626                 error "$tfile different after migration"
17627
17628         diff /etc/passwd $other_dir/luna ||
17629                 error "luna different after migration"
17630
17631         diff /etc/passwd $migrate_dir/sofia ||
17632                 error "sofia different after migration"
17633
17634         diff /etc/passwd $migrate_dir/david ||
17635                 error "david different after migration"
17636
17637         diff /etc/passwd $other_dir/zachary ||
17638                 error "zachary different after migration"
17639
17640         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17641                 error "${tfile}_ln different after migration"
17642
17643         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17644                 error "${tfile}_ln_other different after migration"
17645
17646         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17647         [ $stripe_count = 2 ] ||
17648                 error "dir strpe_count $d != 2 after migration."
17649
17650         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17651         [ $stripe_count = 2 ] ||
17652                 error "file strpe_count $d != 2 after migration."
17653
17654         #migrate back to MDT0
17655         MDTIDX=0
17656
17657         $LFS migrate -m $MDTIDX $migrate_dir ||
17658                 error "fails on migrating remote dir to MDT0"
17659
17660         echo "migrate back to MDT0, checking.."
17661         for file in $(find $migrate_dir); do
17662                 mdt_index=$($LFS getstripe -m $file)
17663                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17664                         error "$file is not on MDT${MDTIDX}"
17665         done
17666
17667         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17668         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17669                 error " expect $old_dir_flag get $new_dir_flag"
17670
17671         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17672         [ "$old_file_flag" = "$new_file_flag" ] ||
17673                 error " expect $old_file_flag get $new_file_flag"
17674
17675         local new_dir_mode=$(stat -c%f $migrate_dir)
17676         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17677                 error "expect mode $old_dir_mode get $new_dir_mode"
17678
17679         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17680         [ "$old_file_mode" = "$new_file_mode" ] ||
17681                 error "expect mode $old_file_mode get $new_file_mode"
17682
17683         diff /etc/passwd ${migrate_dir}/$tfile ||
17684                 error "$tfile different after migration"
17685
17686         diff /etc/passwd ${other_dir}/luna ||
17687                 error "luna different after migration"
17688
17689         diff /etc/passwd ${migrate_dir}/sofia ||
17690                 error "sofia different after migration"
17691
17692         diff /etc/passwd ${other_dir}/zachary ||
17693                 error "zachary different after migration"
17694
17695         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17696                 error "${tfile}_ln different after migration"
17697
17698         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17699                 error "${tfile}_ln_other different after migration"
17700
17701         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17702         [ $stripe_count = 2 ] ||
17703                 error "dir strpe_count $d != 2 after migration."
17704
17705         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17706         [ $stripe_count = 2 ] ||
17707                 error "file strpe_count $d != 2 after migration."
17708
17709         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17710 }
17711 run_test 230b "migrate directory"
17712
17713 test_230c() {
17714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17715         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17716         remote_mds_nodsh && skip "remote MDS with nodsh"
17717         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17718                 skip "Need MDS version at least 2.11.52"
17719
17720         local MDTIDX=1
17721         local total=3
17722         local mdt_index
17723         local file
17724         local migrate_dir=$DIR/$tdir/migrate_dir
17725
17726         #If migrating directory fails in the middle, all entries of
17727         #the directory is still accessiable.
17728         test_mkdir $DIR/$tdir
17729         test_mkdir -i0 -c1 $migrate_dir
17730         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17731         stat $migrate_dir
17732         createmany -o $migrate_dir/f $total ||
17733                 error "create files under ${migrate_dir} failed"
17734
17735         # fail after migrating top dir, and this will fail only once, so the
17736         # first sub file migration will fail (currently f3), others succeed.
17737         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17738         do_facet mds1 lctl set_param fail_loc=0x1801
17739         local t=$(ls $migrate_dir | wc -l)
17740         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17741                 error "migrate should fail"
17742         local u=$(ls $migrate_dir | wc -l)
17743         [ "$u" == "$t" ] || error "$u != $t during migration"
17744
17745         # add new dir/file should succeed
17746         mkdir $migrate_dir/dir ||
17747                 error "mkdir failed under migrating directory"
17748         touch $migrate_dir/file ||
17749                 error "create file failed under migrating directory"
17750
17751         # add file with existing name should fail
17752         for file in $migrate_dir/f*; do
17753                 stat $file > /dev/null || error "stat $file failed"
17754                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17755                         error "open(O_CREAT|O_EXCL) $file should fail"
17756                 $MULTIOP $file m && error "create $file should fail"
17757                 touch $DIR/$tdir/remote_dir/$tfile ||
17758                         error "touch $tfile failed"
17759                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17760                         error "link $file should fail"
17761                 mdt_index=$($LFS getstripe -m $file)
17762                 if [ $mdt_index == 0 ]; then
17763                         # file failed to migrate is not allowed to rename to
17764                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17765                                 error "rename to $file should fail"
17766                 else
17767                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17768                                 error "rename to $file failed"
17769                 fi
17770                 echo hello >> $file || error "write $file failed"
17771         done
17772
17773         # resume migration with different options should fail
17774         $LFS migrate -m 0 $migrate_dir &&
17775                 error "migrate -m 0 $migrate_dir should fail"
17776
17777         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17778                 error "migrate -c 2 $migrate_dir should fail"
17779
17780         # resume migration should succeed
17781         $LFS migrate -m $MDTIDX $migrate_dir ||
17782                 error "migrate $migrate_dir failed"
17783
17784         echo "Finish migration, then checking.."
17785         for file in $(find $migrate_dir); do
17786                 mdt_index=$($LFS getstripe -m $file)
17787                 [ $mdt_index == $MDTIDX ] ||
17788                         error "$file is not on MDT${MDTIDX}"
17789         done
17790
17791         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17792 }
17793 run_test 230c "check directory accessiblity if migration failed"
17794
17795 test_230d() {
17796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17797         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17798         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17799                 skip "Need MDS version at least 2.11.52"
17800         # LU-11235
17801         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17802
17803         local migrate_dir=$DIR/$tdir/migrate_dir
17804         local old_index
17805         local new_index
17806         local old_count
17807         local new_count
17808         local new_hash
17809         local mdt_index
17810         local i
17811         local j
17812
17813         old_index=$((RANDOM % MDSCOUNT))
17814         old_count=$((MDSCOUNT - old_index))
17815         new_index=$((RANDOM % MDSCOUNT))
17816         new_count=$((MDSCOUNT - new_index))
17817         new_hash=1 # for all_char
17818
17819         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17820         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17821
17822         test_mkdir $DIR/$tdir
17823         test_mkdir -i $old_index -c $old_count $migrate_dir
17824
17825         for ((i=0; i<100; i++)); do
17826                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17827                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17828                         error "create files under remote dir failed $i"
17829         done
17830
17831         echo -n "Migrate from MDT$old_index "
17832         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17833         echo -n "to MDT$new_index"
17834         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17835         echo
17836
17837         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17838         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17839                 error "migrate remote dir error"
17840
17841         echo "Finish migration, then checking.."
17842         for file in $(find $migrate_dir); do
17843                 mdt_index=$($LFS getstripe -m $file)
17844                 if [ $mdt_index -lt $new_index ] ||
17845                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17846                         error "$file is on MDT$mdt_index"
17847                 fi
17848         done
17849
17850         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17851 }
17852 run_test 230d "check migrate big directory"
17853
17854 test_230e() {
17855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17856         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17857         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17858                 skip "Need MDS version at least 2.11.52"
17859
17860         local i
17861         local j
17862         local a_fid
17863         local b_fid
17864
17865         mkdir -p $DIR/$tdir
17866         mkdir $DIR/$tdir/migrate_dir
17867         mkdir $DIR/$tdir/other_dir
17868         touch $DIR/$tdir/migrate_dir/a
17869         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17870         ls $DIR/$tdir/other_dir
17871
17872         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17873                 error "migrate dir fails"
17874
17875         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17876         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17877
17878         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17879         [ $mdt_index == 0 ] || error "a is not on MDT0"
17880
17881         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
17882                 error "migrate dir fails"
17883
17884         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
17885         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
17886
17887         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17888         [ $mdt_index == 1 ] || error "a is not on MDT1"
17889
17890         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
17891         [ $mdt_index == 1 ] || error "b is not on MDT1"
17892
17893         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17894         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
17895
17896         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
17897
17898         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17899 }
17900 run_test 230e "migrate mulitple local link files"
17901
17902 test_230f() {
17903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17904         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17905         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17906                 skip "Need MDS version at least 2.11.52"
17907
17908         local a_fid
17909         local ln_fid
17910
17911         mkdir -p $DIR/$tdir
17912         mkdir $DIR/$tdir/migrate_dir
17913         $LFS mkdir -i1 $DIR/$tdir/other_dir
17914         touch $DIR/$tdir/migrate_dir/a
17915         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
17916         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
17917         ls $DIR/$tdir/other_dir
17918
17919         # a should be migrated to MDT1, since no other links on MDT0
17920         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17921                 error "#1 migrate dir fails"
17922         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17923         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17924         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17925         [ $mdt_index == 1 ] || error "a is not on MDT1"
17926
17927         # a should stay on MDT1, because it is a mulitple link file
17928         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17929                 error "#2 migrate dir fails"
17930         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17931         [ $mdt_index == 1 ] || error "a is not on MDT1"
17932
17933         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17934                 error "#3 migrate dir fails"
17935
17936         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17937         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
17938         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
17939
17940         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
17941         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
17942
17943         # a should be migrated to MDT0, since no other links on MDT1
17944         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17945                 error "#4 migrate dir fails"
17946         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17947         [ $mdt_index == 0 ] || error "a is not on MDT0"
17948
17949         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17950 }
17951 run_test 230f "migrate mulitple remote link files"
17952
17953 test_230g() {
17954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17955         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17956         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17957                 skip "Need MDS version at least 2.11.52"
17958
17959         mkdir -p $DIR/$tdir/migrate_dir
17960
17961         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
17962                 error "migrating dir to non-exist MDT succeeds"
17963         true
17964 }
17965 run_test 230g "migrate dir to non-exist MDT"
17966
17967 test_230h() {
17968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17969         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17970         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17971                 skip "Need MDS version at least 2.11.52"
17972
17973         local mdt_index
17974
17975         mkdir -p $DIR/$tdir/migrate_dir
17976
17977         $LFS migrate -m1 $DIR &&
17978                 error "migrating mountpoint1 should fail"
17979
17980         $LFS migrate -m1 $DIR/$tdir/.. &&
17981                 error "migrating mountpoint2 should fail"
17982
17983         # same as mv
17984         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
17985                 error "migrating $tdir/migrate_dir/.. should fail"
17986
17987         true
17988 }
17989 run_test 230h "migrate .. and root"
17990
17991 test_230i() {
17992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17993         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17994         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17995                 skip "Need MDS version at least 2.11.52"
17996
17997         mkdir -p $DIR/$tdir/migrate_dir
17998
17999         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18000                 error "migration fails with a tailing slash"
18001
18002         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18003                 error "migration fails with two tailing slashes"
18004 }
18005 run_test 230i "lfs migrate -m tolerates trailing slashes"
18006
18007 test_230j() {
18008         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18009         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18010                 skip "Need MDS version at least 2.11.52"
18011
18012         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18013         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18014                 error "create $tfile failed"
18015         cat /etc/passwd > $DIR/$tdir/$tfile
18016
18017         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18018
18019         cmp /etc/passwd $DIR/$tdir/$tfile ||
18020                 error "DoM file mismatch after migration"
18021 }
18022 run_test 230j "DoM file data not changed after dir migration"
18023
18024 test_230k() {
18025         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18026         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18027                 skip "Need MDS version at least 2.11.56"
18028
18029         local total=20
18030         local files_on_starting_mdt=0
18031
18032         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18033         $LFS getdirstripe $DIR/$tdir
18034         for i in $(seq $total); do
18035                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18036                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18037                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18038         done
18039
18040         echo "$files_on_starting_mdt files on MDT0"
18041
18042         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18043         $LFS getdirstripe $DIR/$tdir
18044
18045         files_on_starting_mdt=0
18046         for i in $(seq $total); do
18047                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18048                         error "file $tfile.$i mismatch after migration"
18049                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18050                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18051         done
18052
18053         echo "$files_on_starting_mdt files on MDT1 after migration"
18054         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18055
18056         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18057         $LFS getdirstripe $DIR/$tdir
18058
18059         files_on_starting_mdt=0
18060         for i in $(seq $total); do
18061                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18062                         error "file $tfile.$i mismatch after 2nd migration"
18063                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18064                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18065         done
18066
18067         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18068         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18069
18070         true
18071 }
18072 run_test 230k "file data not changed after dir migration"
18073
18074 test_230l() {
18075         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18076         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18077                 skip "Need MDS version at least 2.11.56"
18078
18079         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18080         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18081                 error "create files under remote dir failed $i"
18082         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18083 }
18084 run_test 230l "readdir between MDTs won't crash"
18085
18086 test_230m() {
18087         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18088         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18089                 skip "Need MDS version at least 2.11.56"
18090
18091         local MDTIDX=1
18092         local mig_dir=$DIR/$tdir/migrate_dir
18093         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18094         local shortstr="b"
18095         local val
18096
18097         echo "Creating files and dirs with xattrs"
18098         test_mkdir $DIR/$tdir
18099         test_mkdir -i0 -c1 $mig_dir
18100         mkdir $mig_dir/dir
18101         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18102                 error "cannot set xattr attr1 on dir"
18103         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18104                 error "cannot set xattr attr2 on dir"
18105         touch $mig_dir/dir/f0
18106         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18107                 error "cannot set xattr attr1 on file"
18108         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18109                 error "cannot set xattr attr2 on file"
18110         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18111         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18112         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18113         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18114         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18115         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18116         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18117         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18118         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18119
18120         echo "Migrating to MDT1"
18121         $LFS migrate -m $MDTIDX $mig_dir ||
18122                 error "fails on migrating dir to MDT1"
18123
18124         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18125         echo "Checking xattrs"
18126         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18127         [ "$val" = $longstr ] ||
18128                 error "expecting xattr1 $longstr on dir, found $val"
18129         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18130         [ "$val" = $shortstr ] ||
18131                 error "expecting xattr2 $shortstr on dir, found $val"
18132         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18133         [ "$val" = $longstr ] ||
18134                 error "expecting xattr1 $longstr on file, found $val"
18135         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18136         [ "$val" = $shortstr ] ||
18137                 error "expecting xattr2 $shortstr on file, found $val"
18138 }
18139 run_test 230m "xattrs not changed after dir migration"
18140
18141 test_230n() {
18142         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18143         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18144                 skip "Need MDS version at least 2.13.53"
18145
18146         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18147         cat /etc/hosts > $DIR/$tdir/$tfile
18148         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18149         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18150
18151         cmp /etc/hosts $DIR/$tdir/$tfile ||
18152                 error "File data mismatch after migration"
18153 }
18154 run_test 230n "Dir migration with mirrored file"
18155
18156 test_230o() {
18157         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18158         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18159                 skip "Need MDS version at least 2.13.52"
18160
18161         local mdts=$(comma_list $(mdts_nodes))
18162         local timeout=100
18163
18164         local restripe_status
18165         local delta
18166         local i
18167         local j
18168
18169         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18170
18171         # in case "crush" hash type is not set
18172         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18173
18174         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18175                            mdt.*MDT0000.enable_dir_restripe)
18176         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18177         stack_trap "do_nodes $mdts $LCTL set_param \
18178                     mdt.*.enable_dir_restripe=$restripe_status"
18179
18180         mkdir $DIR/$tdir
18181         createmany -m $DIR/$tdir/f 100 ||
18182                 error "create files under remote dir failed $i"
18183         createmany -d $DIR/$tdir/d 100 ||
18184                 error "create dirs under remote dir failed $i"
18185
18186         for i in $(seq 2 $MDSCOUNT); do
18187                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18188                 $LFS setdirstripe -c $i $DIR/$tdir ||
18189                         error "split -c $i $tdir failed"
18190                 wait_update $HOSTNAME \
18191                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18192                         error "dir split not finished"
18193                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18194                         awk '/migrate/ {sum += $2} END { print sum }')
18195                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18196                 # delta is around total_files/stripe_count
18197                 [ $delta -lt $((200 /(i - 1))) ] ||
18198                         error "$delta files migrated"
18199         done
18200 }
18201 run_test 230o "dir split"
18202
18203 test_230p() {
18204         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18205         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18206                 skip "Need MDS version at least 2.13.52"
18207
18208         local mdts=$(comma_list $(mdts_nodes))
18209         local timeout=100
18210
18211         local restripe_status
18212         local delta
18213         local i
18214         local j
18215
18216         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18217
18218         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18219
18220         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18221                            mdt.*MDT0000.enable_dir_restripe)
18222         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18223         stack_trap "do_nodes $mdts $LCTL set_param \
18224                     mdt.*.enable_dir_restripe=$restripe_status"
18225
18226         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18227         createmany -m $DIR/$tdir/f 100 ||
18228                 error "create files under remote dir failed $i"
18229         createmany -d $DIR/$tdir/d 100 ||
18230                 error "create dirs under remote dir failed $i"
18231
18232         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18233                 local mdt_hash="crush"
18234
18235                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18236                 $LFS setdirstripe -c $i $DIR/$tdir ||
18237                         error "split -c $i $tdir failed"
18238                 [ $i -eq 1 ] && mdt_hash="none"
18239                 wait_update $HOSTNAME \
18240                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18241                         error "dir merge not finished"
18242                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18243                         awk '/migrate/ {sum += $2} END { print sum }')
18244                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18245                 # delta is around total_files/stripe_count
18246                 [ $delta -lt $((200 / i)) ] ||
18247                         error "$delta files migrated"
18248         done
18249 }
18250 run_test 230p "dir merge"
18251
18252 test_230q() {
18253         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18254         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18255                 skip "Need MDS version at least 2.13.52"
18256
18257         local mdts=$(comma_list $(mdts_nodes))
18258         local saved_threshold=$(do_facet mds1 \
18259                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18260         local saved_delta=$(do_facet mds1 \
18261                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18262         local threshold=100
18263         local delta=2
18264         local total=0
18265         local stripe_count=0
18266         local stripe_index
18267         local nr_files
18268
18269         stack_trap "do_nodes $mdts $LCTL set_param \
18270                     mdt.*.dir_split_count=$saved_threshold"
18271         stack_trap "do_nodes $mdts $LCTL set_param \
18272                     mdt.*.dir_split_delta=$saved_delta"
18273         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18274         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18275         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18276         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18277         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18278         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18279
18280         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18281         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18282
18283         while [ $stripe_count -lt $MDSCOUNT ]; do
18284                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18285                         error "create sub files failed"
18286                 stat $DIR/$tdir > /dev/null
18287                 total=$((total + threshold * 3 / 2))
18288                 stripe_count=$((stripe_count + delta))
18289                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18290
18291                 wait_update $HOSTNAME \
18292                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18293                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18294
18295                 wait_update $HOSTNAME \
18296                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18297                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18298
18299                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18300                            grep -w $stripe_index | wc -l)
18301                 echo "$nr_files files on MDT$stripe_index after split"
18302                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18303                         error "$nr_files files on MDT$stripe_index after split"
18304
18305                 nr_files=$(ls $DIR/$tdir | wc -w)
18306                 [ $nr_files -eq $total ] ||
18307                         error "total sub files $nr_files != $total"
18308         done
18309 }
18310 run_test 230q "dir auto split"
18311
18312 test_230r() {
18313         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18314         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18315         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18316                 skip "Need MDS version at least 2.13.54"
18317
18318         # maximum amount of local locks:
18319         # parent striped dir - 2 locks
18320         # new stripe in parent to migrate to - 1 lock
18321         # source and target - 2 locks
18322         # Total 5 locks for regular file
18323         mkdir -p $DIR/$tdir
18324         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18325         touch $DIR/$tdir/dir1/eee
18326
18327         # create 4 hardlink for 4 more locks
18328         # Total: 9 locks > RS_MAX_LOCKS (8)
18329         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18330         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18331         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18332         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18333         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18334         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18335         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18336         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18337
18338         cancel_lru_locks mdc
18339
18340         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18341                 error "migrate dir fails"
18342
18343         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18344 }
18345 run_test 230r "migrate with too many local locks"
18346
18347 test_231a()
18348 {
18349         # For simplicity this test assumes that max_pages_per_rpc
18350         # is the same across all OSCs
18351         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18352         local bulk_size=$((max_pages * PAGE_SIZE))
18353         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18354                                        head -n 1)
18355
18356         mkdir -p $DIR/$tdir
18357         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18358                 error "failed to set stripe with -S ${brw_size}M option"
18359
18360         # clear the OSC stats
18361         $LCTL set_param osc.*.stats=0 &>/dev/null
18362         stop_writeback
18363
18364         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18365         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18366                 oflag=direct &>/dev/null || error "dd failed"
18367
18368         sync; sleep 1; sync # just to be safe
18369         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18370         if [ x$nrpcs != "x1" ]; then
18371                 $LCTL get_param osc.*.stats
18372                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18373         fi
18374
18375         start_writeback
18376         # Drop the OSC cache, otherwise we will read from it
18377         cancel_lru_locks osc
18378
18379         # clear the OSC stats
18380         $LCTL set_param osc.*.stats=0 &>/dev/null
18381
18382         # Client reads $bulk_size.
18383         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18384                 iflag=direct &>/dev/null || error "dd failed"
18385
18386         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18387         if [ x$nrpcs != "x1" ]; then
18388                 $LCTL get_param osc.*.stats
18389                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18390         fi
18391 }
18392 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18393
18394 test_231b() {
18395         mkdir -p $DIR/$tdir
18396         local i
18397         for i in {0..1023}; do
18398                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18399                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18400                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18401         done
18402         sync
18403 }
18404 run_test 231b "must not assert on fully utilized OST request buffer"
18405
18406 test_232a() {
18407         mkdir -p $DIR/$tdir
18408         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18409
18410         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18411         do_facet ost1 $LCTL set_param fail_loc=0x31c
18412
18413         # ignore dd failure
18414         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18415
18416         do_facet ost1 $LCTL set_param fail_loc=0
18417         umount_client $MOUNT || error "umount failed"
18418         mount_client $MOUNT || error "mount failed"
18419         stop ost1 || error "cannot stop ost1"
18420         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18421 }
18422 run_test 232a "failed lock should not block umount"
18423
18424 test_232b() {
18425         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18426                 skip "Need MDS version at least 2.10.58"
18427
18428         mkdir -p $DIR/$tdir
18429         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18430         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18431         sync
18432         cancel_lru_locks osc
18433
18434         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18435         do_facet ost1 $LCTL set_param fail_loc=0x31c
18436
18437         # ignore failure
18438         $LFS data_version $DIR/$tdir/$tfile || true
18439
18440         do_facet ost1 $LCTL set_param fail_loc=0
18441         umount_client $MOUNT || error "umount failed"
18442         mount_client $MOUNT || error "mount failed"
18443         stop ost1 || error "cannot stop ost1"
18444         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18445 }
18446 run_test 232b "failed data version lock should not block umount"
18447
18448 test_233a() {
18449         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18450                 skip "Need MDS version at least 2.3.64"
18451         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18452
18453         local fid=$($LFS path2fid $MOUNT)
18454
18455         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18456                 error "cannot access $MOUNT using its FID '$fid'"
18457 }
18458 run_test 233a "checking that OBF of the FS root succeeds"
18459
18460 test_233b() {
18461         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18462                 skip "Need MDS version at least 2.5.90"
18463         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18464
18465         local fid=$($LFS path2fid $MOUNT/.lustre)
18466
18467         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18468                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18469
18470         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18471         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18472                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18473 }
18474 run_test 233b "checking that OBF of the FS .lustre succeeds"
18475
18476 test_234() {
18477         local p="$TMP/sanityN-$TESTNAME.parameters"
18478         save_lustre_params client "llite.*.xattr_cache" > $p
18479         lctl set_param llite.*.xattr_cache 1 ||
18480                 skip_env "xattr cache is not supported"
18481
18482         mkdir -p $DIR/$tdir || error "mkdir failed"
18483         touch $DIR/$tdir/$tfile || error "touch failed"
18484         # OBD_FAIL_LLITE_XATTR_ENOMEM
18485         $LCTL set_param fail_loc=0x1405
18486         getfattr -n user.attr $DIR/$tdir/$tfile &&
18487                 error "getfattr should have failed with ENOMEM"
18488         $LCTL set_param fail_loc=0x0
18489         rm -rf $DIR/$tdir
18490
18491         restore_lustre_params < $p
18492         rm -f $p
18493 }
18494 run_test 234 "xattr cache should not crash on ENOMEM"
18495
18496 test_235() {
18497         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18498                 skip "Need MDS version at least 2.4.52"
18499
18500         flock_deadlock $DIR/$tfile
18501         local RC=$?
18502         case $RC in
18503                 0)
18504                 ;;
18505                 124) error "process hangs on a deadlock"
18506                 ;;
18507                 *) error "error executing flock_deadlock $DIR/$tfile"
18508                 ;;
18509         esac
18510 }
18511 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18512
18513 #LU-2935
18514 test_236() {
18515         check_swap_layouts_support
18516
18517         local ref1=/etc/passwd
18518         local ref2=/etc/group
18519         local file1=$DIR/$tdir/f1
18520         local file2=$DIR/$tdir/f2
18521
18522         test_mkdir -c1 $DIR/$tdir
18523         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18524         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18525         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18526         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18527         local fd=$(free_fd)
18528         local cmd="exec $fd<>$file2"
18529         eval $cmd
18530         rm $file2
18531         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18532                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18533         cmd="exec $fd>&-"
18534         eval $cmd
18535         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18536
18537         #cleanup
18538         rm -rf $DIR/$tdir
18539 }
18540 run_test 236 "Layout swap on open unlinked file"
18541
18542 # LU-4659 linkea consistency
18543 test_238() {
18544         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18545                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18546                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18547                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18548
18549         touch $DIR/$tfile
18550         ln $DIR/$tfile $DIR/$tfile.lnk
18551         touch $DIR/$tfile.new
18552         mv $DIR/$tfile.new $DIR/$tfile
18553         local fid1=$($LFS path2fid $DIR/$tfile)
18554         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18555         local path1=$($LFS fid2path $FSNAME "$fid1")
18556         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18557         local path2=$($LFS fid2path $FSNAME "$fid2")
18558         [ $tfile.lnk == $path2 ] ||
18559                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18560         rm -f $DIR/$tfile*
18561 }
18562 run_test 238 "Verify linkea consistency"
18563
18564 test_239A() { # was test_239
18565         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18566                 skip "Need MDS version at least 2.5.60"
18567
18568         local list=$(comma_list $(mdts_nodes))
18569
18570         mkdir -p $DIR/$tdir
18571         createmany -o $DIR/$tdir/f- 5000
18572         unlinkmany $DIR/$tdir/f- 5000
18573         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18574                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18575         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18576                         osp.*MDT*.sync_in_flight" | calc_sum)
18577         [ "$changes" -eq 0 ] || error "$changes not synced"
18578 }
18579 run_test 239A "osp_sync test"
18580
18581 test_239a() { #LU-5297
18582         remote_mds_nodsh && skip "remote MDS with nodsh"
18583
18584         touch $DIR/$tfile
18585         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18586         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18587         chgrp $RUNAS_GID $DIR/$tfile
18588         wait_delete_completed
18589 }
18590 run_test 239a "process invalid osp sync record correctly"
18591
18592 test_239b() { #LU-5297
18593         remote_mds_nodsh && skip "remote MDS with nodsh"
18594
18595         touch $DIR/$tfile1
18596         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18597         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18598         chgrp $RUNAS_GID $DIR/$tfile1
18599         wait_delete_completed
18600         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18601         touch $DIR/$tfile2
18602         chgrp $RUNAS_GID $DIR/$tfile2
18603         wait_delete_completed
18604 }
18605 run_test 239b "process osp sync record with ENOMEM error correctly"
18606
18607 test_240() {
18608         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18609         remote_mds_nodsh && skip "remote MDS with nodsh"
18610
18611         mkdir -p $DIR/$tdir
18612
18613         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18614                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18615         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18616                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18617
18618         umount_client $MOUNT || error "umount failed"
18619         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18620         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18621         mount_client $MOUNT || error "failed to mount client"
18622
18623         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18624         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18625 }
18626 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18627
18628 test_241_bio() {
18629         local count=$1
18630         local bsize=$2
18631
18632         for LOOP in $(seq $count); do
18633                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18634                 cancel_lru_locks $OSC || true
18635         done
18636 }
18637
18638 test_241_dio() {
18639         local count=$1
18640         local bsize=$2
18641
18642         for LOOP in $(seq $1); do
18643                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18644                         2>/dev/null
18645         done
18646 }
18647
18648 test_241a() { # was test_241
18649         local bsize=$PAGE_SIZE
18650
18651         (( bsize < 40960 )) && bsize=40960
18652         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18653         ls -la $DIR/$tfile
18654         cancel_lru_locks $OSC
18655         test_241_bio 1000 $bsize &
18656         PID=$!
18657         test_241_dio 1000 $bsize
18658         wait $PID
18659 }
18660 run_test 241a "bio vs dio"
18661
18662 test_241b() {
18663         local bsize=$PAGE_SIZE
18664
18665         (( bsize < 40960 )) && bsize=40960
18666         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18667         ls -la $DIR/$tfile
18668         test_241_dio 1000 $bsize &
18669         PID=$!
18670         test_241_dio 1000 $bsize
18671         wait $PID
18672 }
18673 run_test 241b "dio vs dio"
18674
18675 test_242() {
18676         remote_mds_nodsh && skip "remote MDS with nodsh"
18677
18678         mkdir -p $DIR/$tdir
18679         touch $DIR/$tdir/$tfile
18680
18681         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18682         do_facet mds1 lctl set_param fail_loc=0x105
18683         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18684
18685         do_facet mds1 lctl set_param fail_loc=0
18686         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18687 }
18688 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18689
18690 test_243()
18691 {
18692         test_mkdir $DIR/$tdir
18693         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18694 }
18695 run_test 243 "various group lock tests"
18696
18697 test_244a()
18698 {
18699         test_mkdir $DIR/$tdir
18700         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18701         sendfile_grouplock $DIR/$tdir/$tfile || \
18702                 error "sendfile+grouplock failed"
18703         rm -rf $DIR/$tdir
18704 }
18705 run_test 244a "sendfile with group lock tests"
18706
18707 test_244b()
18708 {
18709         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18710
18711         local threads=50
18712         local size=$((1024*1024))
18713
18714         test_mkdir $DIR/$tdir
18715         for i in $(seq 1 $threads); do
18716                 local file=$DIR/$tdir/file_$((i / 10))
18717                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18718                 local pids[$i]=$!
18719         done
18720         for i in $(seq 1 $threads); do
18721                 wait ${pids[$i]}
18722         done
18723 }
18724 run_test 244b "multi-threaded write with group lock"
18725
18726 test_245() {
18727         local flagname="multi_mod_rpcs"
18728         local connect_data_name="max_mod_rpcs"
18729         local out
18730
18731         # check if multiple modify RPCs flag is set
18732         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18733                 grep "connect_flags:")
18734         echo "$out"
18735
18736         echo "$out" | grep -qw $flagname
18737         if [ $? -ne 0 ]; then
18738                 echo "connect flag $flagname is not set"
18739                 return
18740         fi
18741
18742         # check if multiple modify RPCs data is set
18743         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18744         echo "$out"
18745
18746         echo "$out" | grep -qw $connect_data_name ||
18747                 error "import should have connect data $connect_data_name"
18748 }
18749 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18750
18751 cleanup_247() {
18752         local submount=$1
18753
18754         trap 0
18755         umount_client $submount
18756         rmdir $submount
18757 }
18758
18759 test_247a() {
18760         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18761                 grep -q subtree ||
18762                 skip_env "Fileset feature is not supported"
18763
18764         local submount=${MOUNT}_$tdir
18765
18766         mkdir $MOUNT/$tdir
18767         mkdir -p $submount || error "mkdir $submount failed"
18768         FILESET="$FILESET/$tdir" mount_client $submount ||
18769                 error "mount $submount failed"
18770         trap "cleanup_247 $submount" EXIT
18771         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18772         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18773                 error "read $MOUNT/$tdir/$tfile failed"
18774         cleanup_247 $submount
18775 }
18776 run_test 247a "mount subdir as fileset"
18777
18778 test_247b() {
18779         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18780                 skip_env "Fileset feature is not supported"
18781
18782         local submount=${MOUNT}_$tdir
18783
18784         rm -rf $MOUNT/$tdir
18785         mkdir -p $submount || error "mkdir $submount failed"
18786         SKIP_FILESET=1
18787         FILESET="$FILESET/$tdir" mount_client $submount &&
18788                 error "mount $submount should fail"
18789         rmdir $submount
18790 }
18791 run_test 247b "mount subdir that dose not exist"
18792
18793 test_247c() {
18794         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18795                 skip_env "Fileset feature is not supported"
18796
18797         local submount=${MOUNT}_$tdir
18798
18799         mkdir -p $MOUNT/$tdir/dir1
18800         mkdir -p $submount || error "mkdir $submount failed"
18801         trap "cleanup_247 $submount" EXIT
18802         FILESET="$FILESET/$tdir" mount_client $submount ||
18803                 error "mount $submount failed"
18804         local fid=$($LFS path2fid $MOUNT/)
18805         $LFS fid2path $submount $fid && error "fid2path should fail"
18806         cleanup_247 $submount
18807 }
18808 run_test 247c "running fid2path outside subdirectory root"
18809
18810 test_247d() {
18811         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18812                 skip "Fileset feature is not supported"
18813
18814         local submount=${MOUNT}_$tdir
18815
18816         mkdir -p $MOUNT/$tdir/dir1
18817         mkdir -p $submount || error "mkdir $submount failed"
18818         FILESET="$FILESET/$tdir" mount_client $submount ||
18819                 error "mount $submount failed"
18820         trap "cleanup_247 $submount" EXIT
18821
18822         local td=$submount/dir1
18823         local fid=$($LFS path2fid $td)
18824         [ -z "$fid" ] && error "path2fid unable to get $td FID"
18825
18826         # check that we get the same pathname back
18827         local rootpath
18828         local found
18829         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
18830                 echo "$rootpath $fid"
18831                 found=$($LFS fid2path $rootpath "$fid")
18832                 [ -n "found" ] || error "fid2path should succeed"
18833                 [ "$found" == "$td" ] || error "fid2path $found != $td"
18834         done
18835         # check wrong root path format
18836         rootpath=$submount"_wrong"
18837         found=$($LFS fid2path $rootpath "$fid")
18838         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
18839
18840         cleanup_247 $submount
18841 }
18842 run_test 247d "running fid2path inside subdirectory root"
18843
18844 # LU-8037
18845 test_247e() {
18846         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18847                 grep -q subtree ||
18848                 skip "Fileset feature is not supported"
18849
18850         local submount=${MOUNT}_$tdir
18851
18852         mkdir $MOUNT/$tdir
18853         mkdir -p $submount || error "mkdir $submount failed"
18854         FILESET="$FILESET/.." mount_client $submount &&
18855                 error "mount $submount should fail"
18856         rmdir $submount
18857 }
18858 run_test 247e "mount .. as fileset"
18859
18860 test_247f() {
18861         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18862         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18863                 skip "Need at least version 2.13.52"
18864         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18865                 grep -q subtree ||
18866                 skip "Fileset feature is not supported"
18867
18868         mkdir $DIR/$tdir || error "mkdir $tdir failed"
18869         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
18870                 error "mkdir remote failed"
18871         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
18872         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
18873                 error "mkdir striped failed"
18874         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
18875
18876         local submount=${MOUNT}_$tdir
18877
18878         mkdir -p $submount || error "mkdir $submount failed"
18879
18880         local dir
18881         local fileset=$FILESET
18882
18883         for dir in $tdir/remote $tdir/remote/subdir \
18884                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
18885                 FILESET="$fileset/$dir" mount_client $submount ||
18886                         error "mount $dir failed"
18887                 umount_client $submount
18888         done
18889 }
18890 run_test 247f "mount striped or remote directory as fileset"
18891
18892 test_248a() {
18893         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
18894         [ -z "$fast_read_sav" ] && skip "no fast read support"
18895
18896         # create a large file for fast read verification
18897         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
18898
18899         # make sure the file is created correctly
18900         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
18901                 { rm -f $DIR/$tfile; skip "file creation error"; }
18902
18903         echo "Test 1: verify that fast read is 4 times faster on cache read"
18904
18905         # small read with fast read enabled
18906         $LCTL set_param -n llite.*.fast_read=1
18907         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18908                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18909                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18910         # small read with fast read disabled
18911         $LCTL set_param -n llite.*.fast_read=0
18912         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18913                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18914                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18915
18916         # verify that fast read is 4 times faster for cache read
18917         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
18918                 error_not_in_vm "fast read was not 4 times faster: " \
18919                            "$t_fast vs $t_slow"
18920
18921         echo "Test 2: verify the performance between big and small read"
18922         $LCTL set_param -n llite.*.fast_read=1
18923
18924         # 1k non-cache read
18925         cancel_lru_locks osc
18926         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18927                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18928                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18929
18930         # 1M non-cache read
18931         cancel_lru_locks osc
18932         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18933                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18934                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18935
18936         # verify that big IO is not 4 times faster than small IO
18937         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
18938                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
18939
18940         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
18941         rm -f $DIR/$tfile
18942 }
18943 run_test 248a "fast read verification"
18944
18945 test_248b() {
18946         # Default short_io_bytes=16384, try both smaller and larger sizes.
18947         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
18948         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
18949         echo "bs=53248 count=113 normal buffered write"
18950         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
18951                 error "dd of initial data file failed"
18952         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
18953
18954         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
18955         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
18956                 error "dd with sync normal writes failed"
18957         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
18958
18959         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
18960         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
18961                 error "dd with sync small writes failed"
18962         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
18963
18964         cancel_lru_locks osc
18965
18966         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
18967         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
18968         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
18969         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
18970                 iflag=direct || error "dd with O_DIRECT small read failed"
18971         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
18972         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
18973                 error "compare $TMP/$tfile.1 failed"
18974
18975         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
18976         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
18977
18978         # just to see what the maximum tunable value is, and test parsing
18979         echo "test invalid parameter 2MB"
18980         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
18981                 error "too-large short_io_bytes allowed"
18982         echo "test maximum parameter 512KB"
18983         # if we can set a larger short_io_bytes, run test regardless of version
18984         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
18985                 # older clients may not allow setting it this large, that's OK
18986                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
18987                         skip "Need at least client version 2.13.50"
18988                 error "medium short_io_bytes failed"
18989         fi
18990         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
18991         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
18992
18993         echo "test large parameter 64KB"
18994         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
18995         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
18996
18997         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
18998         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
18999                 error "dd with sync large writes failed"
19000         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19001
19002         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19003         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19004         num=$((113 * 4096 / PAGE_SIZE))
19005         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19006         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19007                 error "dd with O_DIRECT large writes failed"
19008         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19009                 error "compare $DIR/$tfile.3 failed"
19010
19011         cancel_lru_locks osc
19012
19013         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19014         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19015                 error "dd with O_DIRECT large read failed"
19016         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19017                 error "compare $TMP/$tfile.2 failed"
19018
19019         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19020         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19021                 error "dd with O_DIRECT large read failed"
19022         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19023                 error "compare $TMP/$tfile.3 failed"
19024 }
19025 run_test 248b "test short_io read and write for both small and large sizes"
19026
19027 test_249() { # LU-7890
19028         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19029                 skip "Need at least version 2.8.54"
19030
19031         rm -f $DIR/$tfile
19032         $LFS setstripe -c 1 $DIR/$tfile
19033         # Offset 2T == 4k * 512M
19034         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19035                 error "dd to 2T offset failed"
19036 }
19037 run_test 249 "Write above 2T file size"
19038
19039 test_250() {
19040         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19041          && skip "no 16TB file size limit on ZFS"
19042
19043         $LFS setstripe -c 1 $DIR/$tfile
19044         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19045         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19046         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19047         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19048                 conv=notrunc,fsync && error "append succeeded"
19049         return 0
19050 }
19051 run_test 250 "Write above 16T limit"
19052
19053 test_251() {
19054         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19055
19056         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19057         #Skip once - writing the first stripe will succeed
19058         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19059         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19060                 error "short write happened"
19061
19062         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19063         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19064                 error "short read happened"
19065
19066         rm -f $DIR/$tfile
19067 }
19068 run_test 251 "Handling short read and write correctly"
19069
19070 test_252() {
19071         remote_mds_nodsh && skip "remote MDS with nodsh"
19072         remote_ost_nodsh && skip "remote OST with nodsh"
19073         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19074                 skip_env "ldiskfs only test"
19075         fi
19076
19077         local tgt
19078         local dev
19079         local out
19080         local uuid
19081         local num
19082         local gen
19083
19084         # check lr_reader on OST0000
19085         tgt=ost1
19086         dev=$(facet_device $tgt)
19087         out=$(do_facet $tgt $LR_READER $dev)
19088         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19089         echo "$out"
19090         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19091         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19092                 error "Invalid uuid returned by $LR_READER on target $tgt"
19093         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19094
19095         # check lr_reader -c on MDT0000
19096         tgt=mds1
19097         dev=$(facet_device $tgt)
19098         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19099                 skip "$LR_READER does not support additional options"
19100         fi
19101         out=$(do_facet $tgt $LR_READER -c $dev)
19102         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19103         echo "$out"
19104         num=$(echo "$out" | grep -c "mdtlov")
19105         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19106                 error "Invalid number of mdtlov clients returned by $LR_READER"
19107         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19108
19109         # check lr_reader -cr on MDT0000
19110         out=$(do_facet $tgt $LR_READER -cr $dev)
19111         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19112         echo "$out"
19113         echo "$out" | grep -q "^reply_data:$" ||
19114                 error "$LR_READER should have returned 'reply_data' section"
19115         num=$(echo "$out" | grep -c "client_generation")
19116         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19117 }
19118 run_test 252 "check lr_reader tool"
19119
19120 test_253() {
19121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19122         remote_mds_nodsh && skip "remote MDS with nodsh"
19123         remote_mgs_nodsh && skip "remote MGS with nodsh"
19124
19125         local ostidx=0
19126         local rc=0
19127         local ost_name=$(ostname_from_index $ostidx)
19128
19129         # on the mdt's osc
19130         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19131         do_facet $SINGLEMDS $LCTL get_param -n \
19132                 osp.$mdtosc_proc1.reserved_mb_high ||
19133                 skip  "remote MDS does not support reserved_mb_high"
19134
19135         rm -rf $DIR/$tdir
19136         wait_mds_ost_sync
19137         wait_delete_completed
19138         mkdir $DIR/$tdir
19139
19140         pool_add $TESTNAME || error "Pool creation failed"
19141         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19142
19143         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19144                 error "Setstripe failed"
19145
19146         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19147
19148         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19149                     grep "watermarks")
19150         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19151
19152         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19153                         osp.$mdtosc_proc1.prealloc_status)
19154         echo "prealloc_status $oa_status"
19155
19156         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19157                 error "File creation should fail"
19158
19159         #object allocation was stopped, but we still able to append files
19160         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19161                 oflag=append || error "Append failed"
19162
19163         rm -f $DIR/$tdir/$tfile.0
19164
19165         # For this test, we want to delete the files we created to go out of
19166         # space but leave the watermark, so we remain nearly out of space
19167         ost_watermarks_enospc_delete_files $tfile $ostidx
19168
19169         wait_delete_completed
19170
19171         sleep_maxage
19172
19173         for i in $(seq 10 12); do
19174                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19175                         2>/dev/null || error "File creation failed after rm"
19176         done
19177
19178         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19179                         osp.$mdtosc_proc1.prealloc_status)
19180         echo "prealloc_status $oa_status"
19181
19182         if (( oa_status != 0 )); then
19183                 error "Object allocation still disable after rm"
19184         fi
19185 }
19186 run_test 253 "Check object allocation limit"
19187
19188 test_254() {
19189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19190         remote_mds_nodsh && skip "remote MDS with nodsh"
19191         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19192                 skip "MDS does not support changelog_size"
19193
19194         local cl_user
19195         local MDT0=$(facet_svc $SINGLEMDS)
19196
19197         changelog_register || error "changelog_register failed"
19198
19199         changelog_clear 0 || error "changelog_clear failed"
19200
19201         local size1=$(do_facet $SINGLEMDS \
19202                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19203         echo "Changelog size $size1"
19204
19205         rm -rf $DIR/$tdir
19206         $LFS mkdir -i 0 $DIR/$tdir
19207         # change something
19208         mkdir -p $DIR/$tdir/pics/2008/zachy
19209         touch $DIR/$tdir/pics/2008/zachy/timestamp
19210         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19211         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19212         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19213         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19214         rm $DIR/$tdir/pics/desktop.jpg
19215
19216         local size2=$(do_facet $SINGLEMDS \
19217                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19218         echo "Changelog size after work $size2"
19219
19220         (( $size2 > $size1 )) ||
19221                 error "new Changelog size=$size2 less than old size=$size1"
19222 }
19223 run_test 254 "Check changelog size"
19224
19225 ladvise_no_type()
19226 {
19227         local type=$1
19228         local file=$2
19229
19230         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19231                 awk -F: '{print $2}' | grep $type > /dev/null
19232         if [ $? -ne 0 ]; then
19233                 return 0
19234         fi
19235         return 1
19236 }
19237
19238 ladvise_no_ioctl()
19239 {
19240         local file=$1
19241
19242         lfs ladvise -a willread $file > /dev/null 2>&1
19243         if [ $? -eq 0 ]; then
19244                 return 1
19245         fi
19246
19247         lfs ladvise -a willread $file 2>&1 |
19248                 grep "Inappropriate ioctl for device" > /dev/null
19249         if [ $? -eq 0 ]; then
19250                 return 0
19251         fi
19252         return 1
19253 }
19254
19255 percent() {
19256         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19257 }
19258
19259 # run a random read IO workload
19260 # usage: random_read_iops <filename> <filesize> <iosize>
19261 random_read_iops() {
19262         local file=$1
19263         local fsize=$2
19264         local iosize=${3:-4096}
19265
19266         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19267                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19268 }
19269
19270 drop_file_oss_cache() {
19271         local file="$1"
19272         local nodes="$2"
19273
19274         $LFS ladvise -a dontneed $file 2>/dev/null ||
19275                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19276 }
19277
19278 ladvise_willread_performance()
19279 {
19280         local repeat=10
19281         local average_origin=0
19282         local average_cache=0
19283         local average_ladvise=0
19284
19285         for ((i = 1; i <= $repeat; i++)); do
19286                 echo "Iter $i/$repeat: reading without willread hint"
19287                 cancel_lru_locks osc
19288                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19289                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19290                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19291                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19292
19293                 cancel_lru_locks osc
19294                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19295                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19296                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19297
19298                 cancel_lru_locks osc
19299                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19300                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19301                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19302                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19303                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19304         done
19305         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19306         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19307         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19308
19309         speedup_cache=$(percent $average_cache $average_origin)
19310         speedup_ladvise=$(percent $average_ladvise $average_origin)
19311
19312         echo "Average uncached read: $average_origin"
19313         echo "Average speedup with OSS cached read: " \
19314                 "$average_cache = +$speedup_cache%"
19315         echo "Average speedup with ladvise willread: " \
19316                 "$average_ladvise = +$speedup_ladvise%"
19317
19318         local lowest_speedup=20
19319         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19320                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19321                         "got $average_cache%. Skipping ladvise willread check."
19322                 return 0
19323         fi
19324
19325         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19326         # it is still good to run until then to exercise 'ladvise willread'
19327         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19328                 [ "$ost1_FSTYPE" = "zfs" ] &&
19329                 echo "osd-zfs does not support dontneed or drop_caches" &&
19330                 return 0
19331
19332         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19333         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
19334                 error_not_in_vm "Speedup with willread is less than " \
19335                         "$lowest_speedup%, got $average_ladvise%"
19336 }
19337
19338 test_255a() {
19339         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19340                 skip "lustre < 2.8.54 does not support ladvise "
19341         remote_ost_nodsh && skip "remote OST with nodsh"
19342
19343         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19344
19345         ladvise_no_type willread $DIR/$tfile &&
19346                 skip "willread ladvise is not supported"
19347
19348         ladvise_no_ioctl $DIR/$tfile &&
19349                 skip "ladvise ioctl is not supported"
19350
19351         local size_mb=100
19352         local size=$((size_mb * 1048576))
19353         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19354                 error "dd to $DIR/$tfile failed"
19355
19356         lfs ladvise -a willread $DIR/$tfile ||
19357                 error "Ladvise failed with no range argument"
19358
19359         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19360                 error "Ladvise failed with no -l or -e argument"
19361
19362         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19363                 error "Ladvise failed with only -e argument"
19364
19365         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19366                 error "Ladvise failed with only -l argument"
19367
19368         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19369                 error "End offset should not be smaller than start offset"
19370
19371         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19372                 error "End offset should not be equal to start offset"
19373
19374         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19375                 error "Ladvise failed with overflowing -s argument"
19376
19377         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19378                 error "Ladvise failed with overflowing -e argument"
19379
19380         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19381                 error "Ladvise failed with overflowing -l argument"
19382
19383         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19384                 error "Ladvise succeeded with conflicting -l and -e arguments"
19385
19386         echo "Synchronous ladvise should wait"
19387         local delay=4
19388 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19389         do_nodes $(comma_list $(osts_nodes)) \
19390                 $LCTL set_param fail_val=$delay fail_loc=0x237
19391
19392         local start_ts=$SECONDS
19393         lfs ladvise -a willread $DIR/$tfile ||
19394                 error "Ladvise failed with no range argument"
19395         local end_ts=$SECONDS
19396         local inteval_ts=$((end_ts - start_ts))
19397
19398         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19399                 error "Synchronous advice didn't wait reply"
19400         fi
19401
19402         echo "Asynchronous ladvise shouldn't wait"
19403         local start_ts=$SECONDS
19404         lfs ladvise -a willread -b $DIR/$tfile ||
19405                 error "Ladvise failed with no range argument"
19406         local end_ts=$SECONDS
19407         local inteval_ts=$((end_ts - start_ts))
19408
19409         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19410                 error "Asynchronous advice blocked"
19411         fi
19412
19413         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19414         ladvise_willread_performance
19415 }
19416 run_test 255a "check 'lfs ladvise -a willread'"
19417
19418 facet_meminfo() {
19419         local facet=$1
19420         local info=$2
19421
19422         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19423 }
19424
19425 test_255b() {
19426         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19427                 skip "lustre < 2.8.54 does not support ladvise "
19428         remote_ost_nodsh && skip "remote OST with nodsh"
19429
19430         lfs setstripe -c 1 -i 0 $DIR/$tfile
19431
19432         ladvise_no_type dontneed $DIR/$tfile &&
19433                 skip "dontneed ladvise is not supported"
19434
19435         ladvise_no_ioctl $DIR/$tfile &&
19436                 skip "ladvise ioctl is not supported"
19437
19438         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19439                 [ "$ost1_FSTYPE" = "zfs" ] &&
19440                 skip "zfs-osd does not support 'ladvise dontneed'"
19441
19442         local size_mb=100
19443         local size=$((size_mb * 1048576))
19444         # In order to prevent disturbance of other processes, only check 3/4
19445         # of the memory usage
19446         local kibibytes=$((size_mb * 1024 * 3 / 4))
19447
19448         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19449                 error "dd to $DIR/$tfile failed"
19450
19451         #force write to complete before dropping OST cache & checking memory
19452         sync
19453
19454         local total=$(facet_meminfo ost1 MemTotal)
19455         echo "Total memory: $total KiB"
19456
19457         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19458         local before_read=$(facet_meminfo ost1 Cached)
19459         echo "Cache used before read: $before_read KiB"
19460
19461         lfs ladvise -a willread $DIR/$tfile ||
19462                 error "Ladvise willread failed"
19463         local after_read=$(facet_meminfo ost1 Cached)
19464         echo "Cache used after read: $after_read KiB"
19465
19466         lfs ladvise -a dontneed $DIR/$tfile ||
19467                 error "Ladvise dontneed again failed"
19468         local no_read=$(facet_meminfo ost1 Cached)
19469         echo "Cache used after dontneed ladvise: $no_read KiB"
19470
19471         if [ $total -lt $((before_read + kibibytes)) ]; then
19472                 echo "Memory is too small, abort checking"
19473                 return 0
19474         fi
19475
19476         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19477                 error "Ladvise willread should use more memory" \
19478                         "than $kibibytes KiB"
19479         fi
19480
19481         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19482                 error "Ladvise dontneed should release more memory" \
19483                         "than $kibibytes KiB"
19484         fi
19485 }
19486 run_test 255b "check 'lfs ladvise -a dontneed'"
19487
19488 test_255c() {
19489         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19490                 skip "lustre < 2.10.50 does not support lockahead"
19491
19492         local count
19493         local new_count
19494         local difference
19495         local i
19496         local rc
19497
19498         test_mkdir -p $DIR/$tdir
19499         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19500
19501         #test 10 returns only success/failure
19502         i=10
19503         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19504         rc=$?
19505         if [ $rc -eq 255 ]; then
19506                 error "Ladvise test${i} failed, ${rc}"
19507         fi
19508
19509         #test 11 counts lock enqueue requests, all others count new locks
19510         i=11
19511         count=$(do_facet ost1 \
19512                 $LCTL get_param -n ost.OSS.ost.stats)
19513         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19514
19515         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19516         rc=$?
19517         if [ $rc -eq 255 ]; then
19518                 error "Ladvise test${i} failed, ${rc}"
19519         fi
19520
19521         new_count=$(do_facet ost1 \
19522                 $LCTL get_param -n ost.OSS.ost.stats)
19523         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19524                    awk '{ print $2 }')
19525
19526         difference="$((new_count - count))"
19527         if [ $difference -ne $rc ]; then
19528                 error "Ladvise test${i}, bad enqueue count, returned " \
19529                       "${rc}, actual ${difference}"
19530         fi
19531
19532         for i in $(seq 12 21); do
19533                 # If we do not do this, we run the risk of having too many
19534                 # locks and starting lock cancellation while we are checking
19535                 # lock counts.
19536                 cancel_lru_locks osc
19537
19538                 count=$($LCTL get_param -n \
19539                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19540
19541                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19542                 rc=$?
19543                 if [ $rc -eq 255 ]; then
19544                         error "Ladvise test ${i} failed, ${rc}"
19545                 fi
19546
19547                 new_count=$($LCTL get_param -n \
19548                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19549                 difference="$((new_count - count))"
19550
19551                 # Test 15 output is divided by 100 to map down to valid return
19552                 if [ $i -eq 15 ]; then
19553                         rc="$((rc * 100))"
19554                 fi
19555
19556                 if [ $difference -ne $rc ]; then
19557                         error "Ladvise test ${i}, bad lock count, returned " \
19558                               "${rc}, actual ${difference}"
19559                 fi
19560         done
19561
19562         #test 22 returns only success/failure
19563         i=22
19564         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19565         rc=$?
19566         if [ $rc -eq 255 ]; then
19567                 error "Ladvise test${i} failed, ${rc}"
19568         fi
19569 }
19570 run_test 255c "suite of ladvise lockahead tests"
19571
19572 test_256() {
19573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19574         remote_mds_nodsh && skip "remote MDS with nodsh"
19575         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19576         changelog_users $SINGLEMDS | grep "^cl" &&
19577                 skip "active changelog user"
19578
19579         local cl_user
19580         local cat_sl
19581         local mdt_dev
19582
19583         mdt_dev=$(mdsdevname 1)
19584         echo $mdt_dev
19585
19586         changelog_register || error "changelog_register failed"
19587
19588         rm -rf $DIR/$tdir
19589         mkdir -p $DIR/$tdir
19590
19591         changelog_clear 0 || error "changelog_clear failed"
19592
19593         # change something
19594         touch $DIR/$tdir/{1..10}
19595
19596         # stop the MDT
19597         stop $SINGLEMDS || error "Fail to stop MDT"
19598
19599         # remount the MDT
19600
19601         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19602
19603         #after mount new plainllog is used
19604         touch $DIR/$tdir/{11..19}
19605         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19606         stack_trap "rm -f $tmpfile"
19607         cat_sl=$(do_facet $SINGLEMDS "sync; \
19608                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19609                  llog_reader $tmpfile | grep -c type=1064553b")
19610         do_facet $SINGLEMDS llog_reader $tmpfile
19611
19612         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19613
19614         changelog_clear 0 || error "changelog_clear failed"
19615
19616         cat_sl=$(do_facet $SINGLEMDS "sync; \
19617                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19618                  llog_reader $tmpfile | grep -c type=1064553b")
19619
19620         if (( cat_sl == 2 )); then
19621                 error "Empty plain llog was not deleted from changelog catalog"
19622         elif (( cat_sl != 1 )); then
19623                 error "Active plain llog shouldn't be deleted from catalog"
19624         fi
19625 }
19626 run_test 256 "Check llog delete for empty and not full state"
19627
19628 test_257() {
19629         remote_mds_nodsh && skip "remote MDS with nodsh"
19630         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19631                 skip "Need MDS version at least 2.8.55"
19632
19633         test_mkdir $DIR/$tdir
19634
19635         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19636                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19637         stat $DIR/$tdir
19638
19639 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19640         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19641         local facet=mds$((mdtidx + 1))
19642         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19643         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19644
19645         stop $facet || error "stop MDS failed"
19646         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19647                 error "start MDS fail"
19648         wait_recovery_complete $facet
19649 }
19650 run_test 257 "xattr locks are not lost"
19651
19652 # Verify we take the i_mutex when security requires it
19653 test_258a() {
19654 #define OBD_FAIL_IMUTEX_SEC 0x141c
19655         $LCTL set_param fail_loc=0x141c
19656         touch $DIR/$tfile
19657         chmod u+s $DIR/$tfile
19658         chmod a+rwx $DIR/$tfile
19659         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19660         RC=$?
19661         if [ $RC -ne 0 ]; then
19662                 error "error, failed to take i_mutex, rc=$?"
19663         fi
19664         rm -f $DIR/$tfile
19665 }
19666 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19667
19668 # Verify we do NOT take the i_mutex in the normal case
19669 test_258b() {
19670 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19671         $LCTL set_param fail_loc=0x141d
19672         touch $DIR/$tfile
19673         chmod a+rwx $DIR
19674         chmod a+rw $DIR/$tfile
19675         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19676         RC=$?
19677         if [ $RC -ne 0 ]; then
19678                 error "error, took i_mutex unnecessarily, rc=$?"
19679         fi
19680         rm -f $DIR/$tfile
19681
19682 }
19683 run_test 258b "verify i_mutex security behavior"
19684
19685 test_259() {
19686         local file=$DIR/$tfile
19687         local before
19688         local after
19689
19690         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19691
19692         stack_trap "rm -f $file" EXIT
19693
19694         wait_delete_completed
19695         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19696         echo "before: $before"
19697
19698         $LFS setstripe -i 0 -c 1 $file
19699         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19700         sync_all_data
19701         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19702         echo "after write: $after"
19703
19704 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19705         do_facet ost1 $LCTL set_param fail_loc=0x2301
19706         $TRUNCATE $file 0
19707         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19708         echo "after truncate: $after"
19709
19710         stop ost1
19711         do_facet ost1 $LCTL set_param fail_loc=0
19712         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19713         sleep 2
19714         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19715         echo "after restart: $after"
19716         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19717                 error "missing truncate?"
19718
19719         return 0
19720 }
19721 run_test 259 "crash at delayed truncate"
19722
19723 test_260() {
19724 #define OBD_FAIL_MDC_CLOSE               0x806
19725         $LCTL set_param fail_loc=0x80000806
19726         touch $DIR/$tfile
19727
19728 }
19729 run_test 260 "Check mdc_close fail"
19730
19731 ### Data-on-MDT sanity tests ###
19732 test_270a() {
19733         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19734                 skip "Need MDS version at least 2.10.55 for DoM"
19735
19736         # create DoM file
19737         local dom=$DIR/$tdir/dom_file
19738         local tmp=$DIR/$tdir/tmp_file
19739
19740         mkdir -p $DIR/$tdir
19741
19742         # basic checks for DoM component creation
19743         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19744                 error "Can set MDT layout to non-first entry"
19745
19746         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19747                 error "Can define multiple entries as MDT layout"
19748
19749         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19750
19751         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19752         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19753         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19754
19755         local mdtidx=$($LFS getstripe -m $dom)
19756         local mdtname=MDT$(printf %04x $mdtidx)
19757         local facet=mds$((mdtidx + 1))
19758         local space_check=1
19759
19760         # Skip free space checks with ZFS
19761         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19762
19763         # write
19764         sync
19765         local size_tmp=$((65536 * 3))
19766         local mdtfree1=$(do_facet $facet \
19767                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19768
19769         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19770         # check also direct IO along write
19771         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19772         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19773         sync
19774         cmp $tmp $dom || error "file data is different"
19775         [ $(stat -c%s $dom) == $size_tmp ] ||
19776                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19777         if [ $space_check == 1 ]; then
19778                 local mdtfree2=$(do_facet $facet \
19779                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19780
19781                 # increase in usage from by $size_tmp
19782                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19783                         error "MDT free space wrong after write: " \
19784                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19785         fi
19786
19787         # truncate
19788         local size_dom=10000
19789
19790         $TRUNCATE $dom $size_dom
19791         [ $(stat -c%s $dom) == $size_dom ] ||
19792                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19793         if [ $space_check == 1 ]; then
19794                 mdtfree1=$(do_facet $facet \
19795                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19796                 # decrease in usage from $size_tmp to new $size_dom
19797                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19798                   $(((size_tmp - size_dom) / 1024)) ] ||
19799                         error "MDT free space is wrong after truncate: " \
19800                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19801         fi
19802
19803         # append
19804         cat $tmp >> $dom
19805         sync
19806         size_dom=$((size_dom + size_tmp))
19807         [ $(stat -c%s $dom) == $size_dom ] ||
19808                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19809         if [ $space_check == 1 ]; then
19810                 mdtfree2=$(do_facet $facet \
19811                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19812                 # increase in usage by $size_tmp from previous
19813                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19814                         error "MDT free space is wrong after append: " \
19815                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19816         fi
19817
19818         # delete
19819         rm $dom
19820         if [ $space_check == 1 ]; then
19821                 mdtfree1=$(do_facet $facet \
19822                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19823                 # decrease in usage by $size_dom from previous
19824                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
19825                         error "MDT free space is wrong after removal: " \
19826                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
19827         fi
19828
19829         # combined striping
19830         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
19831                 error "Can't create DoM + OST striping"
19832
19833         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
19834         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19835         # check also direct IO along write
19836         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19837         sync
19838         cmp $tmp $dom || error "file data is different"
19839         [ $(stat -c%s $dom) == $size_tmp ] ||
19840                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19841         rm $dom $tmp
19842
19843         return 0
19844 }
19845 run_test 270a "DoM: basic functionality tests"
19846
19847 test_270b() {
19848         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19849                 skip "Need MDS version at least 2.10.55"
19850
19851         local dom=$DIR/$tdir/dom_file
19852         local max_size=1048576
19853
19854         mkdir -p $DIR/$tdir
19855         $LFS setstripe -E $max_size -L mdt $dom
19856
19857         # truncate over the limit
19858         $TRUNCATE $dom $(($max_size + 1)) &&
19859                 error "successful truncate over the maximum size"
19860         # write over the limit
19861         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
19862                 error "successful write over the maximum size"
19863         # append over the limit
19864         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
19865         echo "12345" >> $dom && error "successful append over the maximum size"
19866         rm $dom
19867
19868         return 0
19869 }
19870 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
19871
19872 test_270c() {
19873         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19874                 skip "Need MDS version at least 2.10.55"
19875
19876         mkdir -p $DIR/$tdir
19877         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19878
19879         # check files inherit DoM EA
19880         touch $DIR/$tdir/first
19881         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
19882                 error "bad pattern"
19883         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
19884                 error "bad stripe count"
19885         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
19886                 error "bad stripe size"
19887
19888         # check directory inherits DoM EA and uses it as default
19889         mkdir $DIR/$tdir/subdir
19890         touch $DIR/$tdir/subdir/second
19891         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
19892                 error "bad pattern in sub-directory"
19893         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
19894                 error "bad stripe count in sub-directory"
19895         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
19896                 error "bad stripe size in sub-directory"
19897         return 0
19898 }
19899 run_test 270c "DoM: DoM EA inheritance tests"
19900
19901 test_270d() {
19902         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19903                 skip "Need MDS version at least 2.10.55"
19904
19905         mkdir -p $DIR/$tdir
19906         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19907
19908         # inherit default DoM striping
19909         mkdir $DIR/$tdir/subdir
19910         touch $DIR/$tdir/subdir/f1
19911
19912         # change default directory striping
19913         $LFS setstripe -c 1 $DIR/$tdir/subdir
19914         touch $DIR/$tdir/subdir/f2
19915         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
19916                 error "wrong default striping in file 2"
19917         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
19918                 error "bad pattern in file 2"
19919         return 0
19920 }
19921 run_test 270d "DoM: change striping from DoM to RAID0"
19922
19923 test_270e() {
19924         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19925                 skip "Need MDS version at least 2.10.55"
19926
19927         mkdir -p $DIR/$tdir/dom
19928         mkdir -p $DIR/$tdir/norm
19929         DOMFILES=20
19930         NORMFILES=10
19931         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
19932         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
19933
19934         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
19935         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
19936
19937         # find DoM files by layout
19938         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
19939         [ $NUM -eq  $DOMFILES ] ||
19940                 error "lfs find -L: found $NUM, expected $DOMFILES"
19941         echo "Test 1: lfs find 20 DOM files by layout: OK"
19942
19943         # there should be 1 dir with default DOM striping
19944         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
19945         [ $NUM -eq  1 ] ||
19946                 error "lfs find -L: found $NUM, expected 1 dir"
19947         echo "Test 2: lfs find 1 DOM dir by layout: OK"
19948
19949         # find DoM files by stripe size
19950         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
19951         [ $NUM -eq  $DOMFILES ] ||
19952                 error "lfs find -S: found $NUM, expected $DOMFILES"
19953         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
19954
19955         # find files by stripe offset except DoM files
19956         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
19957         [ $NUM -eq  $NORMFILES ] ||
19958                 error "lfs find -i: found $NUM, expected $NORMFILES"
19959         echo "Test 5: lfs find no DOM files by stripe index: OK"
19960         return 0
19961 }
19962 run_test 270e "DoM: lfs find with DoM files test"
19963
19964 test_270f() {
19965         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19966                 skip "Need MDS version at least 2.10.55"
19967
19968         local mdtname=${FSNAME}-MDT0000-mdtlov
19969         local dom=$DIR/$tdir/dom_file
19970         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
19971                                                 lod.$mdtname.dom_stripesize)
19972         local dom_limit=131072
19973
19974         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
19975         local dom_current=$(do_facet mds1 $LCTL get_param -n \
19976                                                 lod.$mdtname.dom_stripesize)
19977         [ ${dom_limit} -eq ${dom_current} ] ||
19978                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
19979
19980         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19981         $LFS setstripe -d $DIR/$tdir
19982         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
19983                 error "Can't set directory default striping"
19984
19985         # exceed maximum stripe size
19986         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
19987                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
19988         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
19989                 error "Able to create DoM component size more than LOD limit"
19990
19991         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
19992         dom_current=$(do_facet mds1 $LCTL get_param -n \
19993                                                 lod.$mdtname.dom_stripesize)
19994         [ 0 -eq ${dom_current} ] ||
19995                 error "Can't set zero DoM stripe limit"
19996         rm $dom
19997
19998         # attempt to create DoM file on server with disabled DoM should
19999         # remove DoM entry from layout and be succeed
20000         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20001                 error "Can't create DoM file (DoM is disabled)"
20002         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20003                 error "File has DoM component while DoM is disabled"
20004         rm $dom
20005
20006         # attempt to create DoM file with only DoM stripe should return error
20007         $LFS setstripe -E $dom_limit -L mdt $dom &&
20008                 error "Able to create DoM-only file while DoM is disabled"
20009
20010         # too low values to be aligned with smallest stripe size 64K
20011         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20012         dom_current=$(do_facet mds1 $LCTL get_param -n \
20013                                                 lod.$mdtname.dom_stripesize)
20014         [ 30000 -eq ${dom_current} ] &&
20015                 error "Can set too small DoM stripe limit"
20016
20017         # 64K is a minimal stripe size in Lustre, expect limit of that size
20018         [ 65536 -eq ${dom_current} ] ||
20019                 error "Limit is not set to 64K but ${dom_current}"
20020
20021         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20022         dom_current=$(do_facet mds1 $LCTL get_param -n \
20023                                                 lod.$mdtname.dom_stripesize)
20024         echo $dom_current
20025         [ 2147483648 -eq ${dom_current} ] &&
20026                 error "Can set too large DoM stripe limit"
20027
20028         do_facet mds1 $LCTL set_param -n \
20029                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20030         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20031                 error "Can't create DoM component size after limit change"
20032         do_facet mds1 $LCTL set_param -n \
20033                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20034         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20035                 error "Can't create DoM file after limit decrease"
20036         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20037                 error "Can create big DoM component after limit decrease"
20038         touch ${dom}_def ||
20039                 error "Can't create file with old default layout"
20040
20041         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20042         return 0
20043 }
20044 run_test 270f "DoM: maximum DoM stripe size checks"
20045
20046 test_270g() {
20047         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20048                 skip "Need MDS version at least 2.13.52"
20049         local dom=$DIR/$tdir/$tfile
20050
20051         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20052         local lodname=${FSNAME}-MDT0000-mdtlov
20053
20054         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20055         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20056         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20057         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20058
20059         local dom_limit=1024
20060         local dom_threshold="50%"
20061
20062         $LFS setstripe -d $DIR/$tdir
20063         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20064                 error "Can't set directory default striping"
20065
20066         do_facet mds1 $LCTL set_param -n \
20067                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20068         # set 0 threshold and create DOM file to change tunable stripesize
20069         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20070         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20071                 error "Failed to create $dom file"
20072         # now tunable dom_cur_stripesize should reach maximum
20073         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20074                                         lod.${lodname}.dom_stripesize_cur_kb)
20075         [[ $dom_current == $dom_limit ]] ||
20076                 error "Current DOM stripesize is not maximum"
20077         rm $dom
20078
20079         # set threshold for further tests
20080         do_facet mds1 $LCTL set_param -n \
20081                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20082         echo "DOM threshold is $dom_threshold free space"
20083         local dom_def
20084         local dom_set
20085         # Spoof bfree to exceed threshold
20086         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20087         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20088         for spfree in 40 20 0 15 30 55; do
20089                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20090                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20091                         error "Failed to create $dom file"
20092                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20093                                         lod.${lodname}.dom_stripesize_cur_kb)
20094                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20095                 [[ $dom_def != $dom_current ]] ||
20096                         error "Default stripe size was not changed"
20097                 if [[ $spfree > 0 ]] ; then
20098                         dom_set=$($LFS getstripe -S $dom)
20099                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20100                                 error "DOM component size is still old"
20101                 else
20102                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20103                                 error "DoM component is set with no free space"
20104                 fi
20105                 rm $dom
20106                 dom_current=$dom_def
20107         done
20108 }
20109 run_test 270g "DoM: default DoM stripe size depends on free space"
20110
20111 test_270h() {
20112         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20113                 skip "Need MDS version at least 2.13.53"
20114
20115         local mdtname=${FSNAME}-MDT0000-mdtlov
20116         local dom=$DIR/$tdir/$tfile
20117         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20118
20119         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20120         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20121
20122         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20123         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20124                 error "can't create OST file"
20125         # mirrored file with DOM entry in the second mirror
20126         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20127                 error "can't create mirror with DoM component"
20128
20129         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20130
20131         # DOM component in the middle and has other enries in the same mirror,
20132         # should succeed but lost DoM component
20133         $LFS setstripe --copy=${dom}_1 $dom ||
20134                 error "Can't create file from OST|DOM mirror layout"
20135         # check new file has no DoM layout after all
20136         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20137                 error "File has DoM component while DoM is disabled"
20138 }
20139 run_test 270h "DoM: DoM stripe removal when disabled on server"
20140
20141 test_271a() {
20142         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20143                 skip "Need MDS version at least 2.10.55"
20144
20145         local dom=$DIR/$tdir/dom
20146
20147         mkdir -p $DIR/$tdir
20148
20149         $LFS setstripe -E 1024K -L mdt $dom
20150
20151         lctl set_param -n mdc.*.stats=clear
20152         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20153         cat $dom > /dev/null
20154         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20155         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20156         ls $dom
20157         rm -f $dom
20158 }
20159 run_test 271a "DoM: data is cached for read after write"
20160
20161 test_271b() {
20162         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20163                 skip "Need MDS version at least 2.10.55"
20164
20165         local dom=$DIR/$tdir/dom
20166
20167         mkdir -p $DIR/$tdir
20168
20169         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20170
20171         lctl set_param -n mdc.*.stats=clear
20172         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20173         cancel_lru_locks mdc
20174         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20175         # second stat to check size is cached on client
20176         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20177         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20178         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20179         rm -f $dom
20180 }
20181 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20182
20183 test_271ba() {
20184         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20185                 skip "Need MDS version at least 2.10.55"
20186
20187         local dom=$DIR/$tdir/dom
20188
20189         mkdir -p $DIR/$tdir
20190
20191         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20192
20193         lctl set_param -n mdc.*.stats=clear
20194         lctl set_param -n osc.*.stats=clear
20195         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20196         cancel_lru_locks mdc
20197         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20198         # second stat to check size is cached on client
20199         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20200         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20201         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20202         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20203         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20204         rm -f $dom
20205 }
20206 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20207
20208
20209 get_mdc_stats() {
20210         local mdtidx=$1
20211         local param=$2
20212         local mdt=MDT$(printf %04x $mdtidx)
20213
20214         if [ -z $param ]; then
20215                 lctl get_param -n mdc.*$mdt*.stats
20216         else
20217                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20218         fi
20219 }
20220
20221 test_271c() {
20222         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20223                 skip "Need MDS version at least 2.10.55"
20224
20225         local dom=$DIR/$tdir/dom
20226
20227         mkdir -p $DIR/$tdir
20228
20229         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20230
20231         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20232         local facet=mds$((mdtidx + 1))
20233
20234         cancel_lru_locks mdc
20235         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20236         createmany -o $dom 1000
20237         lctl set_param -n mdc.*.stats=clear
20238         smalliomany -w $dom 1000 200
20239         get_mdc_stats $mdtidx
20240         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20241         # Each file has 1 open, 1 IO enqueues, total 2000
20242         # but now we have also +1 getxattr for security.capability, total 3000
20243         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20244         unlinkmany $dom 1000
20245
20246         cancel_lru_locks mdc
20247         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20248         createmany -o $dom 1000
20249         lctl set_param -n mdc.*.stats=clear
20250         smalliomany -w $dom 1000 200
20251         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20252         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20253         # for OPEN and IO lock.
20254         [ $((enq - enq_2)) -ge 1000 ] ||
20255                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20256         unlinkmany $dom 1000
20257         return 0
20258 }
20259 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20260
20261 cleanup_271def_tests() {
20262         trap 0
20263         rm -f $1
20264 }
20265
20266 test_271d() {
20267         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20268                 skip "Need MDS version at least 2.10.57"
20269
20270         local dom=$DIR/$tdir/dom
20271         local tmp=$TMP/$tfile
20272         trap "cleanup_271def_tests $tmp" EXIT
20273
20274         mkdir -p $DIR/$tdir
20275
20276         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20277
20278         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20279
20280         cancel_lru_locks mdc
20281         dd if=/dev/urandom of=$tmp bs=1000 count=1
20282         dd if=$tmp of=$dom bs=1000 count=1
20283         cancel_lru_locks mdc
20284
20285         cat /etc/hosts >> $tmp
20286         lctl set_param -n mdc.*.stats=clear
20287
20288         # append data to the same file it should update local page
20289         echo "Append to the same page"
20290         cat /etc/hosts >> $dom
20291         local num=$(get_mdc_stats $mdtidx ost_read)
20292         local ra=$(get_mdc_stats $mdtidx req_active)
20293         local rw=$(get_mdc_stats $mdtidx req_waittime)
20294
20295         [ -z $num ] || error "$num READ RPC occured"
20296         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20297         echo "... DONE"
20298
20299         # compare content
20300         cmp $tmp $dom || error "file miscompare"
20301
20302         cancel_lru_locks mdc
20303         lctl set_param -n mdc.*.stats=clear
20304
20305         echo "Open and read file"
20306         cat $dom > /dev/null
20307         local num=$(get_mdc_stats $mdtidx ost_read)
20308         local ra=$(get_mdc_stats $mdtidx req_active)
20309         local rw=$(get_mdc_stats $mdtidx req_waittime)
20310
20311         [ -z $num ] || error "$num READ RPC occured"
20312         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20313         echo "... DONE"
20314
20315         # compare content
20316         cmp $tmp $dom || error "file miscompare"
20317
20318         return 0
20319 }
20320 run_test 271d "DoM: read on open (1K file in reply buffer)"
20321
20322 test_271f() {
20323         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20324                 skip "Need MDS version at least 2.10.57"
20325
20326         local dom=$DIR/$tdir/dom
20327         local tmp=$TMP/$tfile
20328         trap "cleanup_271def_tests $tmp" EXIT
20329
20330         mkdir -p $DIR/$tdir
20331
20332         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20333
20334         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20335
20336         cancel_lru_locks mdc
20337         dd if=/dev/urandom of=$tmp bs=265000 count=1
20338         dd if=$tmp of=$dom bs=265000 count=1
20339         cancel_lru_locks mdc
20340         cat /etc/hosts >> $tmp
20341         lctl set_param -n mdc.*.stats=clear
20342
20343         echo "Append to the same page"
20344         cat /etc/hosts >> $dom
20345         local num=$(get_mdc_stats $mdtidx ost_read)
20346         local ra=$(get_mdc_stats $mdtidx req_active)
20347         local rw=$(get_mdc_stats $mdtidx req_waittime)
20348
20349         [ -z $num ] || error "$num READ RPC occured"
20350         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20351         echo "... DONE"
20352
20353         # compare content
20354         cmp $tmp $dom || error "file miscompare"
20355
20356         cancel_lru_locks mdc
20357         lctl set_param -n mdc.*.stats=clear
20358
20359         echo "Open and read file"
20360         cat $dom > /dev/null
20361         local num=$(get_mdc_stats $mdtidx ost_read)
20362         local ra=$(get_mdc_stats $mdtidx req_active)
20363         local rw=$(get_mdc_stats $mdtidx req_waittime)
20364
20365         [ -z $num ] && num=0
20366         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20367         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20368         echo "... DONE"
20369
20370         # compare content
20371         cmp $tmp $dom || error "file miscompare"
20372
20373         return 0
20374 }
20375 run_test 271f "DoM: read on open (200K file and read tail)"
20376
20377 test_271g() {
20378         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20379                 skip "Skipping due to old client or server version"
20380
20381         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20382         # to get layout
20383         $CHECKSTAT -t file $DIR1/$tfile
20384
20385         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20386         MULTIOP_PID=$!
20387         sleep 1
20388         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20389         $LCTL set_param fail_loc=0x80000314
20390         rm $DIR1/$tfile || error "Unlink fails"
20391         RC=$?
20392         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20393         [ $RC -eq 0 ] || error "Failed write to stale object"
20394 }
20395 run_test 271g "Discard DoM data vs client flush race"
20396
20397 test_272a() {
20398         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20399                 skip "Need MDS version at least 2.11.50"
20400
20401         local dom=$DIR/$tdir/dom
20402         mkdir -p $DIR/$tdir
20403
20404         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20405         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20406                 error "failed to write data into $dom"
20407         local old_md5=$(md5sum $dom)
20408
20409         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20410                 error "failed to migrate to the same DoM component"
20411
20412         local new_md5=$(md5sum $dom)
20413
20414         [ "$old_md5" == "$new_md5" ] ||
20415                 error "md5sum differ: $old_md5, $new_md5"
20416
20417         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20418                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20419 }
20420 run_test 272a "DoM migration: new layout with the same DOM component"
20421
20422 test_272b() {
20423         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20424                 skip "Need MDS version at least 2.11.50"
20425
20426         local dom=$DIR/$tdir/dom
20427         mkdir -p $DIR/$tdir
20428         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20429
20430         local mdtidx=$($LFS getstripe -m $dom)
20431         local mdtname=MDT$(printf %04x $mdtidx)
20432         local facet=mds$((mdtidx + 1))
20433
20434         local mdtfree1=$(do_facet $facet \
20435                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20436         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20437                 error "failed to write data into $dom"
20438         local old_md5=$(md5sum $dom)
20439         cancel_lru_locks mdc
20440         local mdtfree1=$(do_facet $facet \
20441                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20442
20443         $LFS migrate -c2 $dom ||
20444                 error "failed to migrate to the new composite layout"
20445         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20446                 error "MDT stripe was not removed"
20447
20448         cancel_lru_locks mdc
20449         local new_md5=$(md5sum $dom)
20450         [ "$old_md5" == "$new_md5" ] ||
20451                 error "$old_md5 != $new_md5"
20452
20453         # Skip free space checks with ZFS
20454         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20455                 local mdtfree2=$(do_facet $facet \
20456                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20457                 [ $mdtfree2 -gt $mdtfree1 ] ||
20458                         error "MDT space is not freed after migration"
20459         fi
20460         return 0
20461 }
20462 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20463
20464 test_272c() {
20465         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20466                 skip "Need MDS version at least 2.11.50"
20467
20468         local dom=$DIR/$tdir/$tfile
20469         mkdir -p $DIR/$tdir
20470         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20471
20472         local mdtidx=$($LFS getstripe -m $dom)
20473         local mdtname=MDT$(printf %04x $mdtidx)
20474         local facet=mds$((mdtidx + 1))
20475
20476         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20477                 error "failed to write data into $dom"
20478         local old_md5=$(md5sum $dom)
20479         cancel_lru_locks mdc
20480         local mdtfree1=$(do_facet $facet \
20481                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20482
20483         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20484                 error "failed to migrate to the new composite layout"
20485         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20486                 error "MDT stripe was not removed"
20487
20488         cancel_lru_locks mdc
20489         local new_md5=$(md5sum $dom)
20490         [ "$old_md5" == "$new_md5" ] ||
20491                 error "$old_md5 != $new_md5"
20492
20493         # Skip free space checks with ZFS
20494         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20495                 local mdtfree2=$(do_facet $facet \
20496                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20497                 [ $mdtfree2 -gt $mdtfree1 ] ||
20498                         error "MDS space is not freed after migration"
20499         fi
20500         return 0
20501 }
20502 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20503
20504 test_272d() {
20505         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20506                 skip "Need MDS version at least 2.12.55"
20507
20508         local dom=$DIR/$tdir/$tfile
20509         mkdir -p $DIR/$tdir
20510         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20511
20512         local mdtidx=$($LFS getstripe -m $dom)
20513         local mdtname=MDT$(printf %04x $mdtidx)
20514         local facet=mds$((mdtidx + 1))
20515
20516         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20517                 error "failed to write data into $dom"
20518         local old_md5=$(md5sum $dom)
20519         cancel_lru_locks mdc
20520         local mdtfree1=$(do_facet $facet \
20521                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20522
20523         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20524                 error "failed mirroring to the new composite layout"
20525         $LFS mirror resync $dom ||
20526                 error "failed mirror resync"
20527         $LFS mirror split --mirror-id 1 -d $dom ||
20528                 error "failed mirror split"
20529
20530         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20531                 error "MDT stripe was not removed"
20532
20533         cancel_lru_locks mdc
20534         local new_md5=$(md5sum $dom)
20535         [ "$old_md5" == "$new_md5" ] ||
20536                 error "$old_md5 != $new_md5"
20537
20538         # Skip free space checks with ZFS
20539         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20540                 local mdtfree2=$(do_facet $facet \
20541                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20542                 [ $mdtfree2 -gt $mdtfree1 ] ||
20543                         error "MDS space is not freed after DOM mirror deletion"
20544         fi
20545         return 0
20546 }
20547 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20548
20549 test_272e() {
20550         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20551                 skip "Need MDS version at least 2.12.55"
20552
20553         local dom=$DIR/$tdir/$tfile
20554         mkdir -p $DIR/$tdir
20555         $LFS setstripe -c 2 $dom
20556
20557         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20558                 error "failed to write data into $dom"
20559         local old_md5=$(md5sum $dom)
20560         cancel_lru_locks mdc
20561
20562         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20563                 error "failed mirroring to the DOM layout"
20564         $LFS mirror resync $dom ||
20565                 error "failed mirror resync"
20566         $LFS mirror split --mirror-id 1 -d $dom ||
20567                 error "failed mirror split"
20568
20569         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20570                 error "MDT stripe was not removed"
20571
20572         cancel_lru_locks mdc
20573         local new_md5=$(md5sum $dom)
20574         [ "$old_md5" == "$new_md5" ] ||
20575                 error "$old_md5 != $new_md5"
20576
20577         return 0
20578 }
20579 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20580
20581 test_272f() {
20582         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20583                 skip "Need MDS version at least 2.12.55"
20584
20585         local dom=$DIR/$tdir/$tfile
20586         mkdir -p $DIR/$tdir
20587         $LFS setstripe -c 2 $dom
20588
20589         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20590                 error "failed to write data into $dom"
20591         local old_md5=$(md5sum $dom)
20592         cancel_lru_locks mdc
20593
20594         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20595                 error "failed migrating to the DOM file"
20596
20597         cancel_lru_locks mdc
20598         local new_md5=$(md5sum $dom)
20599         [ "$old_md5" != "$new_md5" ] &&
20600                 error "$old_md5 != $new_md5"
20601
20602         return 0
20603 }
20604 run_test 272f "DoM migration: OST-striped file to DOM file"
20605
20606 test_273a() {
20607         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20608                 skip "Need MDS version at least 2.11.50"
20609
20610         # Layout swap cannot be done if either file has DOM component,
20611         # this will never be supported, migration should be used instead
20612
20613         local dom=$DIR/$tdir/$tfile
20614         mkdir -p $DIR/$tdir
20615
20616         $LFS setstripe -c2 ${dom}_plain
20617         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20618         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20619                 error "can swap layout with DoM component"
20620         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20621                 error "can swap layout with DoM component"
20622
20623         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20624         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20625                 error "can swap layout with DoM component"
20626         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20627                 error "can swap layout with DoM component"
20628         return 0
20629 }
20630 run_test 273a "DoM: layout swapping should fail with DOM"
20631
20632 test_275() {
20633         remote_ost_nodsh && skip "remote OST with nodsh"
20634         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20635                 skip "Need OST version >= 2.10.57"
20636
20637         local file=$DIR/$tfile
20638         local oss
20639
20640         oss=$(comma_list $(osts_nodes))
20641
20642         dd if=/dev/urandom of=$file bs=1M count=2 ||
20643                 error "failed to create a file"
20644         cancel_lru_locks osc
20645
20646         #lock 1
20647         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20648                 error "failed to read a file"
20649
20650 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20651         $LCTL set_param fail_loc=0x8000031f
20652
20653         cancel_lru_locks osc &
20654         sleep 1
20655
20656 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20657         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20658         #IO takes another lock, but matches the PENDING one
20659         #and places it to the IO RPC
20660         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20661                 error "failed to read a file with PENDING lock"
20662 }
20663 run_test 275 "Read on a canceled duplicate lock"
20664
20665 test_276() {
20666         remote_ost_nodsh && skip "remote OST with nodsh"
20667         local pid
20668
20669         do_facet ost1 "(while true; do \
20670                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20671                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20672         pid=$!
20673
20674         for LOOP in $(seq 20); do
20675                 stop ost1
20676                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20677         done
20678         kill -9 $pid
20679         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20680                 rm $TMP/sanity_276_pid"
20681 }
20682 run_test 276 "Race between mount and obd_statfs"
20683
20684 test_277() {
20685         $LCTL set_param ldlm.namespaces.*.lru_size=0
20686         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20687         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20688                         grep ^used_mb | awk '{print $2}')
20689         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20690         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20691                 oflag=direct conv=notrunc
20692         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20693                         grep ^used_mb | awk '{print $2}')
20694         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20695 }
20696 run_test 277 "Direct IO shall drop page cache"
20697
20698 test_278() {
20699         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20700         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20701         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20702                 skip "needs the same host for mdt1 mdt2" && return
20703
20704         local pid1
20705         local pid2
20706
20707 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20708         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20709         stop mds2 &
20710         pid2=$!
20711
20712         stop mds1
20713
20714         echo "Starting MDTs"
20715         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20716         wait $pid2
20717 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20718 #will return NULL
20719         do_facet mds2 $LCTL set_param fail_loc=0
20720
20721         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20722         wait_recovery_complete mds2
20723 }
20724 run_test 278 "Race starting MDS between MDTs stop/start"
20725
20726 test_280() {
20727         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20728                 skip "Need MGS version at least 2.13.52"
20729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20730         combined_mgs_mds || skip "needs combined MGS/MDT"
20731
20732         umount_client $MOUNT
20733 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20734         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20735
20736         mount_client $MOUNT &
20737         sleep 1
20738         stop mgs || error "stop mgs failed"
20739         #for a race mgs would crash
20740         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20741         mount_client $MOUNT || error "mount client failed"
20742 }
20743 run_test 280 "Race between MGS umount and client llog processing"
20744
20745 cleanup_test_300() {
20746         trap 0
20747         umask $SAVE_UMASK
20748 }
20749 test_striped_dir() {
20750         local mdt_index=$1
20751         local stripe_count
20752         local stripe_index
20753
20754         mkdir -p $DIR/$tdir
20755
20756         SAVE_UMASK=$(umask)
20757         trap cleanup_test_300 RETURN EXIT
20758
20759         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20760                                                 $DIR/$tdir/striped_dir ||
20761                 error "set striped dir error"
20762
20763         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20764         [ "$mode" = "755" ] || error "expect 755 got $mode"
20765
20766         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20767                 error "getdirstripe failed"
20768         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20769         if [ "$stripe_count" != "2" ]; then
20770                 error "1:stripe_count is $stripe_count, expect 2"
20771         fi
20772         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20773         if [ "$stripe_count" != "2" ]; then
20774                 error "2:stripe_count is $stripe_count, expect 2"
20775         fi
20776
20777         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20778         if [ "$stripe_index" != "$mdt_index" ]; then
20779                 error "stripe_index is $stripe_index, expect $mdt_index"
20780         fi
20781
20782         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20783                 error "nlink error after create striped dir"
20784
20785         mkdir $DIR/$tdir/striped_dir/a
20786         mkdir $DIR/$tdir/striped_dir/b
20787
20788         stat $DIR/$tdir/striped_dir/a ||
20789                 error "create dir under striped dir failed"
20790         stat $DIR/$tdir/striped_dir/b ||
20791                 error "create dir under striped dir failed"
20792
20793         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20794                 error "nlink error after mkdir"
20795
20796         rmdir $DIR/$tdir/striped_dir/a
20797         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20798                 error "nlink error after rmdir"
20799
20800         rmdir $DIR/$tdir/striped_dir/b
20801         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20802                 error "nlink error after rmdir"
20803
20804         chattr +i $DIR/$tdir/striped_dir
20805         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20806                 error "immutable flags not working under striped dir!"
20807         chattr -i $DIR/$tdir/striped_dir
20808
20809         rmdir $DIR/$tdir/striped_dir ||
20810                 error "rmdir striped dir error"
20811
20812         cleanup_test_300
20813
20814         true
20815 }
20816
20817 test_300a() {
20818         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20819                 skip "skipped for lustre < 2.7.0"
20820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20821         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20822
20823         test_striped_dir 0 || error "failed on striped dir on MDT0"
20824         test_striped_dir 1 || error "failed on striped dir on MDT0"
20825 }
20826 run_test 300a "basic striped dir sanity test"
20827
20828 test_300b() {
20829         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20830                 skip "skipped for lustre < 2.7.0"
20831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20832         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20833
20834         local i
20835         local mtime1
20836         local mtime2
20837         local mtime3
20838
20839         test_mkdir $DIR/$tdir || error "mkdir fail"
20840         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20841                 error "set striped dir error"
20842         for i in {0..9}; do
20843                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
20844                 sleep 1
20845                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
20846                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
20847                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
20848                 sleep 1
20849                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
20850                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
20851                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
20852         done
20853         true
20854 }
20855 run_test 300b "check ctime/mtime for striped dir"
20856
20857 test_300c() {
20858         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20859                 skip "skipped for lustre < 2.7.0"
20860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20861         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20862
20863         local file_count
20864
20865         mkdir -p $DIR/$tdir
20866         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
20867                 error "set striped dir error"
20868
20869         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
20870                 error "chown striped dir failed"
20871
20872         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
20873                 error "create 5k files failed"
20874
20875         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
20876
20877         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
20878
20879         rm -rf $DIR/$tdir
20880 }
20881 run_test 300c "chown && check ls under striped directory"
20882
20883 test_300d() {
20884         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20885                 skip "skipped for lustre < 2.7.0"
20886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20887         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20888
20889         local stripe_count
20890         local file
20891
20892         mkdir -p $DIR/$tdir
20893         $LFS setstripe -c 2 $DIR/$tdir
20894
20895         #local striped directory
20896         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20897                 error "set striped dir error"
20898         #look at the directories for debug purposes
20899         ls -l $DIR/$tdir
20900         $LFS getdirstripe $DIR/$tdir
20901         ls -l $DIR/$tdir/striped_dir
20902         $LFS getdirstripe $DIR/$tdir/striped_dir
20903         createmany -o $DIR/$tdir/striped_dir/f 10 ||
20904                 error "create 10 files failed"
20905
20906         #remote striped directory
20907         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
20908                 error "set striped dir error"
20909         #look at the directories for debug purposes
20910         ls -l $DIR/$tdir
20911         $LFS getdirstripe $DIR/$tdir
20912         ls -l $DIR/$tdir/remote_striped_dir
20913         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
20914         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
20915                 error "create 10 files failed"
20916
20917         for file in $(find $DIR/$tdir); do
20918                 stripe_count=$($LFS getstripe -c $file)
20919                 [ $stripe_count -eq 2 ] ||
20920                         error "wrong stripe $stripe_count for $file"
20921         done
20922
20923         rm -rf $DIR/$tdir
20924 }
20925 run_test 300d "check default stripe under striped directory"
20926
20927 test_300e() {
20928         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20929                 skip "Need MDS version at least 2.7.55"
20930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20931         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20932
20933         local stripe_count
20934         local file
20935
20936         mkdir -p $DIR/$tdir
20937
20938         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20939                 error "set striped dir error"
20940
20941         touch $DIR/$tdir/striped_dir/a
20942         touch $DIR/$tdir/striped_dir/b
20943         touch $DIR/$tdir/striped_dir/c
20944
20945         mkdir $DIR/$tdir/striped_dir/dir_a
20946         mkdir $DIR/$tdir/striped_dir/dir_b
20947         mkdir $DIR/$tdir/striped_dir/dir_c
20948
20949         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
20950                 error "set striped adir under striped dir error"
20951
20952         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
20953                 error "set striped bdir under striped dir error"
20954
20955         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
20956                 error "set striped cdir under striped dir error"
20957
20958         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
20959                 error "rename dir under striped dir fails"
20960
20961         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
20962                 error "rename dir under different stripes fails"
20963
20964         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
20965                 error "rename file under striped dir should succeed"
20966
20967         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
20968                 error "rename dir under striped dir should succeed"
20969
20970         rm -rf $DIR/$tdir
20971 }
20972 run_test 300e "check rename under striped directory"
20973
20974 test_300f() {
20975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20976         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20977         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20978                 skip "Need MDS version at least 2.7.55"
20979
20980         local stripe_count
20981         local file
20982
20983         rm -rf $DIR/$tdir
20984         mkdir -p $DIR/$tdir
20985
20986         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20987                 error "set striped dir error"
20988
20989         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
20990                 error "set striped dir error"
20991
20992         touch $DIR/$tdir/striped_dir/a
20993         mkdir $DIR/$tdir/striped_dir/dir_a
20994         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
20995                 error "create striped dir under striped dir fails"
20996
20997         touch $DIR/$tdir/striped_dir1/b
20998         mkdir $DIR/$tdir/striped_dir1/dir_b
20999         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21000                 error "create striped dir under striped dir fails"
21001
21002         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21003                 error "rename dir under different striped dir should fail"
21004
21005         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21006                 error "rename striped dir under diff striped dir should fail"
21007
21008         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21009                 error "rename file under diff striped dirs fails"
21010
21011         rm -rf $DIR/$tdir
21012 }
21013 run_test 300f "check rename cross striped directory"
21014
21015 test_300_check_default_striped_dir()
21016 {
21017         local dirname=$1
21018         local default_count=$2
21019         local default_index=$3
21020         local stripe_count
21021         local stripe_index
21022         local dir_stripe_index
21023         local dir
21024
21025         echo "checking $dirname $default_count $default_index"
21026         $LFS setdirstripe -D -c $default_count -i $default_index \
21027                                 -t all_char $DIR/$tdir/$dirname ||
21028                 error "set default stripe on striped dir error"
21029         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21030         [ $stripe_count -eq $default_count ] ||
21031                 error "expect $default_count get $stripe_count for $dirname"
21032
21033         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21034         [ $stripe_index -eq $default_index ] ||
21035                 error "expect $default_index get $stripe_index for $dirname"
21036
21037         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21038                                                 error "create dirs failed"
21039
21040         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21041         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21042         for dir in $(find $DIR/$tdir/$dirname/*); do
21043                 stripe_count=$($LFS getdirstripe -c $dir)
21044                 [ $stripe_count -eq $default_count ] ||
21045                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21046                 error "stripe count $default_count != $stripe_count for $dir"
21047
21048                 stripe_index=$($LFS getdirstripe -i $dir)
21049                 [ $default_index -eq -1 ] ||
21050                         [ $stripe_index -eq $default_index ] ||
21051                         error "$stripe_index != $default_index for $dir"
21052
21053                 #check default stripe
21054                 stripe_count=$($LFS getdirstripe -D -c $dir)
21055                 [ $stripe_count -eq $default_count ] ||
21056                 error "default count $default_count != $stripe_count for $dir"
21057
21058                 stripe_index=$($LFS getdirstripe -D -i $dir)
21059                 [ $stripe_index -eq $default_index ] ||
21060                 error "default index $default_index != $stripe_index for $dir"
21061         done
21062         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21063 }
21064
21065 test_300g() {
21066         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21067         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21068                 skip "Need MDS version at least 2.7.55"
21069
21070         local dir
21071         local stripe_count
21072         local stripe_index
21073
21074         mkdir $DIR/$tdir
21075         mkdir $DIR/$tdir/normal_dir
21076
21077         #Checking when client cache stripe index
21078         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21079         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21080                 error "create striped_dir failed"
21081
21082         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21083                 error "create dir0 fails"
21084         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21085         [ $stripe_index -eq 0 ] ||
21086                 error "dir0 expect index 0 got $stripe_index"
21087
21088         mkdir $DIR/$tdir/striped_dir/dir1 ||
21089                 error "create dir1 fails"
21090         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21091         [ $stripe_index -eq 1 ] ||
21092                 error "dir1 expect index 1 got $stripe_index"
21093
21094         #check default stripe count/stripe index
21095         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21096         test_300_check_default_striped_dir normal_dir 1 0
21097         test_300_check_default_striped_dir normal_dir 2 1
21098         test_300_check_default_striped_dir normal_dir 2 -1
21099
21100         #delete default stripe information
21101         echo "delete default stripeEA"
21102         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21103                 error "set default stripe on striped dir error"
21104
21105         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21106         for dir in $(find $DIR/$tdir/normal_dir/*); do
21107                 stripe_count=$($LFS getdirstripe -c $dir)
21108                 [ $stripe_count -eq 0 ] ||
21109                         error "expect 1 get $stripe_count for $dir"
21110                 stripe_index=$($LFS getdirstripe -i $dir)
21111                 [ $stripe_index -eq 0 ] ||
21112                         error "expect 0 get $stripe_index for $dir"
21113         done
21114 }
21115 run_test 300g "check default striped directory for normal directory"
21116
21117 test_300h() {
21118         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21119         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21120                 skip "Need MDS version at least 2.7.55"
21121
21122         local dir
21123         local stripe_count
21124
21125         mkdir $DIR/$tdir
21126         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21127                 error "set striped dir error"
21128
21129         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21130         test_300_check_default_striped_dir striped_dir 1 0
21131         test_300_check_default_striped_dir striped_dir 2 1
21132         test_300_check_default_striped_dir striped_dir 2 -1
21133
21134         #delete default stripe information
21135         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21136                 error "set default stripe on striped dir error"
21137
21138         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21139         for dir in $(find $DIR/$tdir/striped_dir/*); do
21140                 stripe_count=$($LFS getdirstripe -c $dir)
21141                 [ $stripe_count -eq 0 ] ||
21142                         error "expect 1 get $stripe_count for $dir"
21143         done
21144 }
21145 run_test 300h "check default striped directory for striped directory"
21146
21147 test_300i() {
21148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21149         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21150         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21151                 skip "Need MDS version at least 2.7.55"
21152
21153         local stripe_count
21154         local file
21155
21156         mkdir $DIR/$tdir
21157
21158         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21159                 error "set striped dir error"
21160
21161         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21162                 error "create files under striped dir failed"
21163
21164         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21165                 error "set striped hashdir error"
21166
21167         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21168                 error "create dir0 under hash dir failed"
21169         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21170                 error "create dir1 under hash dir failed"
21171
21172         # unfortunately, we need to umount to clear dir layout cache for now
21173         # once we fully implement dir layout, we can drop this
21174         umount_client $MOUNT || error "umount failed"
21175         mount_client $MOUNT || error "mount failed"
21176
21177         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21178         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21179         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21180
21181         #set the stripe to be unknown hash type
21182         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21183         $LCTL set_param fail_loc=0x1901
21184         for ((i = 0; i < 10; i++)); do
21185                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21186                         error "stat f-$i failed"
21187                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21188         done
21189
21190         touch $DIR/$tdir/striped_dir/f0 &&
21191                 error "create under striped dir with unknown hash should fail"
21192
21193         $LCTL set_param fail_loc=0
21194
21195         umount_client $MOUNT || error "umount failed"
21196         mount_client $MOUNT || error "mount failed"
21197
21198         return 0
21199 }
21200 run_test 300i "client handle unknown hash type striped directory"
21201
21202 test_300j() {
21203         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21205         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21206                 skip "Need MDS version at least 2.7.55"
21207
21208         local stripe_count
21209         local file
21210
21211         mkdir $DIR/$tdir
21212
21213         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21214         $LCTL set_param fail_loc=0x1702
21215         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21216                 error "set striped dir error"
21217
21218         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21219                 error "create files under striped dir failed"
21220
21221         $LCTL set_param fail_loc=0
21222
21223         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21224
21225         return 0
21226 }
21227 run_test 300j "test large update record"
21228
21229 test_300k() {
21230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21231         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21232         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21233                 skip "Need MDS version at least 2.7.55"
21234
21235         # this test needs a huge transaction
21236         local kb
21237         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21238              osd*.$FSNAME-MDT0000.kbytestotal")
21239         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21240
21241         local stripe_count
21242         local file
21243
21244         mkdir $DIR/$tdir
21245
21246         #define OBD_FAIL_LARGE_STRIPE   0x1703
21247         $LCTL set_param fail_loc=0x1703
21248         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21249                 error "set striped dir error"
21250         $LCTL set_param fail_loc=0
21251
21252         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21253                 error "getstripeddir fails"
21254         rm -rf $DIR/$tdir/striped_dir ||
21255                 error "unlink striped dir fails"
21256
21257         return 0
21258 }
21259 run_test 300k "test large striped directory"
21260
21261 test_300l() {
21262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21263         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21264         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21265                 skip "Need MDS version at least 2.7.55"
21266
21267         local stripe_index
21268
21269         test_mkdir -p $DIR/$tdir/striped_dir
21270         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21271                         error "chown $RUNAS_ID failed"
21272         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21273                 error "set default striped dir failed"
21274
21275         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21276         $LCTL set_param fail_loc=0x80000158
21277         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21278
21279         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21280         [ $stripe_index -eq 1 ] ||
21281                 error "expect 1 get $stripe_index for $dir"
21282 }
21283 run_test 300l "non-root user to create dir under striped dir with stale layout"
21284
21285 test_300m() {
21286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21287         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21288         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21289                 skip "Need MDS version at least 2.7.55"
21290
21291         mkdir -p $DIR/$tdir/striped_dir
21292         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21293                 error "set default stripes dir error"
21294
21295         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21296
21297         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21298         [ $stripe_count -eq 0 ] ||
21299                         error "expect 0 get $stripe_count for a"
21300
21301         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21302                 error "set default stripes dir error"
21303
21304         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21305
21306         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21307         [ $stripe_count -eq 0 ] ||
21308                         error "expect 0 get $stripe_count for b"
21309
21310         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21311                 error "set default stripes dir error"
21312
21313         mkdir $DIR/$tdir/striped_dir/c &&
21314                 error "default stripe_index is invalid, mkdir c should fails"
21315
21316         rm -rf $DIR/$tdir || error "rmdir fails"
21317 }
21318 run_test 300m "setstriped directory on single MDT FS"
21319
21320 cleanup_300n() {
21321         local list=$(comma_list $(mdts_nodes))
21322
21323         trap 0
21324         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21325 }
21326
21327 test_300n() {
21328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21329         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21330         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21331                 skip "Need MDS version at least 2.7.55"
21332         remote_mds_nodsh && skip "remote MDS with nodsh"
21333
21334         local stripe_index
21335         local list=$(comma_list $(mdts_nodes))
21336
21337         trap cleanup_300n RETURN EXIT
21338         mkdir -p $DIR/$tdir
21339         chmod 777 $DIR/$tdir
21340         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21341                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21342                 error "create striped dir succeeds with gid=0"
21343
21344         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21345         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21346                 error "create striped dir fails with gid=-1"
21347
21348         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21349         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21350                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21351                 error "set default striped dir succeeds with gid=0"
21352
21353
21354         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21355         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21356                 error "set default striped dir fails with gid=-1"
21357
21358
21359         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21360         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21361                                         error "create test_dir fails"
21362         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21363                                         error "create test_dir1 fails"
21364         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21365                                         error "create test_dir2 fails"
21366         cleanup_300n
21367 }
21368 run_test 300n "non-root user to create dir under striped dir with default EA"
21369
21370 test_300o() {
21371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21372         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21373         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21374                 skip "Need MDS version at least 2.7.55"
21375
21376         local numfree1
21377         local numfree2
21378
21379         mkdir -p $DIR/$tdir
21380
21381         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21382         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21383         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21384                 skip "not enough free inodes $numfree1 $numfree2"
21385         fi
21386
21387         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21388         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21389         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21390                 skip "not enough free space $numfree1 $numfree2"
21391         fi
21392
21393         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21394                 error "setdirstripe fails"
21395
21396         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21397                 error "create dirs fails"
21398
21399         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21400         ls $DIR/$tdir/striped_dir > /dev/null ||
21401                 error "ls striped dir fails"
21402         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21403                 error "unlink big striped dir fails"
21404 }
21405 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21406
21407 test_300p() {
21408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21409         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21410         remote_mds_nodsh && skip "remote MDS with nodsh"
21411
21412         mkdir -p $DIR/$tdir
21413
21414         #define OBD_FAIL_OUT_ENOSPC     0x1704
21415         do_facet mds2 lctl set_param fail_loc=0x80001704
21416         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21417                  && error "create striped directory should fail"
21418
21419         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21420
21421         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21422         true
21423 }
21424 run_test 300p "create striped directory without space"
21425
21426 test_300q() {
21427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21428         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21429
21430         local fd=$(free_fd)
21431         local cmd="exec $fd<$tdir"
21432         cd $DIR
21433         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21434         eval $cmd
21435         cmd="exec $fd<&-"
21436         trap "eval $cmd" EXIT
21437         cd $tdir || error "cd $tdir fails"
21438         rmdir  ../$tdir || error "rmdir $tdir fails"
21439         mkdir local_dir && error "create dir succeeds"
21440         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21441         eval $cmd
21442         return 0
21443 }
21444 run_test 300q "create remote directory under orphan directory"
21445
21446 test_300r() {
21447         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21448                 skip "Need MDS version at least 2.7.55" && return
21449         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21450
21451         mkdir $DIR/$tdir
21452
21453         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21454                 error "set striped dir error"
21455
21456         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21457                 error "getstripeddir fails"
21458
21459         local stripe_count
21460         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21461                       awk '/lmv_stripe_count:/ { print $2 }')
21462
21463         [ $MDSCOUNT -ne $stripe_count ] &&
21464                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21465
21466         rm -rf $DIR/$tdir/striped_dir ||
21467                 error "unlink striped dir fails"
21468 }
21469 run_test 300r "test -1 striped directory"
21470
21471 prepare_remote_file() {
21472         mkdir $DIR/$tdir/src_dir ||
21473                 error "create remote source failed"
21474
21475         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21476                  error "cp to remote source failed"
21477         touch $DIR/$tdir/src_dir/a
21478
21479         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21480                 error "create remote target dir failed"
21481
21482         touch $DIR/$tdir/tgt_dir/b
21483
21484         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21485                 error "rename dir cross MDT failed!"
21486
21487         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21488                 error "src_child still exists after rename"
21489
21490         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21491                 error "missing file(a) after rename"
21492
21493         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21494                 error "diff after rename"
21495 }
21496
21497 test_310a() {
21498         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21500
21501         local remote_file=$DIR/$tdir/tgt_dir/b
21502
21503         mkdir -p $DIR/$tdir
21504
21505         prepare_remote_file || error "prepare remote file failed"
21506
21507         #open-unlink file
21508         $OPENUNLINK $remote_file $remote_file ||
21509                 error "openunlink $remote_file failed"
21510         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21511 }
21512 run_test 310a "open unlink remote file"
21513
21514 test_310b() {
21515         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21517
21518         local remote_file=$DIR/$tdir/tgt_dir/b
21519
21520         mkdir -p $DIR/$tdir
21521
21522         prepare_remote_file || error "prepare remote file failed"
21523
21524         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21525         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21526         $CHECKSTAT -t file $remote_file || error "check file failed"
21527 }
21528 run_test 310b "unlink remote file with multiple links while open"
21529
21530 test_310c() {
21531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21532         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21533
21534         local remote_file=$DIR/$tdir/tgt_dir/b
21535
21536         mkdir -p $DIR/$tdir
21537
21538         prepare_remote_file || error "prepare remote file failed"
21539
21540         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21541         multiop_bg_pause $remote_file O_uc ||
21542                         error "mulitop failed for remote file"
21543         MULTIPID=$!
21544         $MULTIOP $DIR/$tfile Ouc
21545         kill -USR1 $MULTIPID
21546         wait $MULTIPID
21547 }
21548 run_test 310c "open-unlink remote file with multiple links"
21549
21550 #LU-4825
21551 test_311() {
21552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21553         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21554         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21555                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21556         remote_mds_nodsh && skip "remote MDS with nodsh"
21557
21558         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21559         local mdts=$(comma_list $(mdts_nodes))
21560
21561         mkdir -p $DIR/$tdir
21562         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21563         createmany -o $DIR/$tdir/$tfile. 1000
21564
21565         # statfs data is not real time, let's just calculate it
21566         old_iused=$((old_iused + 1000))
21567
21568         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21569                         osp.*OST0000*MDT0000.create_count")
21570         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21571                                 osp.*OST0000*MDT0000.max_create_count")
21572         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21573
21574         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21575         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21576         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21577
21578         unlinkmany $DIR/$tdir/$tfile. 1000
21579
21580         do_nodes $mdts "$LCTL set_param -n \
21581                         osp.*OST0000*.max_create_count=$max_count"
21582         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21583                 do_nodes $mdts "$LCTL set_param -n \
21584                                 osp.*OST0000*.create_count=$count"
21585         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21586                         grep "=0" && error "create_count is zero"
21587
21588         local new_iused
21589         for i in $(seq 120); do
21590                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21591                 # system may be too busy to destroy all objs in time, use
21592                 # a somewhat small value to not fail autotest
21593                 [ $((old_iused - new_iused)) -gt 400 ] && break
21594                 sleep 1
21595         done
21596
21597         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21598         [ $((old_iused - new_iused)) -gt 400 ] ||
21599                 error "objs not destroyed after unlink"
21600 }
21601 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21602
21603 zfs_oid_to_objid()
21604 {
21605         local ost=$1
21606         local objid=$2
21607
21608         local vdevdir=$(dirname $(facet_vdevice $ost))
21609         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21610         local zfs_zapid=$(do_facet $ost $cmd |
21611                           grep -w "/O/0/d$((objid%32))" -C 5 |
21612                           awk '/Object/{getline; print $1}')
21613         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21614                           awk "/$objid = /"'{printf $3}')
21615
21616         echo $zfs_objid
21617 }
21618
21619 zfs_object_blksz() {
21620         local ost=$1
21621         local objid=$2
21622
21623         local vdevdir=$(dirname $(facet_vdevice $ost))
21624         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21625         local blksz=$(do_facet $ost $cmd $objid |
21626                       awk '/dblk/{getline; printf $4}')
21627
21628         case "${blksz: -1}" in
21629                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21630                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21631                 *) ;;
21632         esac
21633
21634         echo $blksz
21635 }
21636
21637 test_312() { # LU-4856
21638         remote_ost_nodsh && skip "remote OST with nodsh"
21639         [ "$ost1_FSTYPE" = "zfs" ] ||
21640                 skip_env "the test only applies to zfs"
21641
21642         local max_blksz=$(do_facet ost1 \
21643                           $ZFS get -p recordsize $(facet_device ost1) |
21644                           awk '!/VALUE/{print $3}')
21645
21646         # to make life a little bit easier
21647         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21648         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21649
21650         local tf=$DIR/$tdir/$tfile
21651         touch $tf
21652         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21653
21654         # Get ZFS object id
21655         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21656         # block size change by sequential overwrite
21657         local bs
21658
21659         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21660                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21661
21662                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21663                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21664         done
21665         rm -f $tf
21666
21667         # block size change by sequential append write
21668         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21669         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21670         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21671         local count
21672
21673         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21674                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21675                         oflag=sync conv=notrunc
21676
21677                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21678                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21679                         error "blksz error, actual $blksz, " \
21680                                 "expected: 2 * $count * $PAGE_SIZE"
21681         done
21682         rm -f $tf
21683
21684         # random write
21685         touch $tf
21686         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21687         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21688
21689         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21690         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21691         [ $blksz -eq $PAGE_SIZE ] ||
21692                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21693
21694         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21695         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21696         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21697
21698         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21699         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21700         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21701 }
21702 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21703
21704 test_313() {
21705         remote_ost_nodsh && skip "remote OST with nodsh"
21706
21707         local file=$DIR/$tfile
21708
21709         rm -f $file
21710         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21711
21712         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21713         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21714         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21715                 error "write should failed"
21716         do_facet ost1 "$LCTL set_param fail_loc=0"
21717         rm -f $file
21718 }
21719 run_test 313 "io should fail after last_rcvd update fail"
21720
21721 test_314() {
21722         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21723
21724         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21725         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21726         rm -f $DIR/$tfile
21727         wait_delete_completed
21728         do_facet ost1 "$LCTL set_param fail_loc=0"
21729 }
21730 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21731
21732 test_315() { # LU-618
21733         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21734
21735         local file=$DIR/$tfile
21736         rm -f $file
21737
21738         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21739                 error "multiop file write failed"
21740         $MULTIOP $file oO_RDONLY:r4063232_c &
21741         PID=$!
21742
21743         sleep 2
21744
21745         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21746         kill -USR1 $PID
21747
21748         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21749         rm -f $file
21750 }
21751 run_test 315 "read should be accounted"
21752
21753 test_316() {
21754         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21755         large_xattr_enabled || skip_env "ea_inode feature disabled"
21756
21757         rm -rf $DIR/$tdir/d
21758         mkdir -p $DIR/$tdir/d
21759         chown nobody $DIR/$tdir/d
21760         touch $DIR/$tdir/d/file
21761
21762         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21763 }
21764 run_test 316 "lfs mv"
21765
21766 test_317() {
21767         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21768                 skip "Need MDS version at least 2.11.53"
21769         if [ "$ost1_FSTYPE" == "zfs" ]; then
21770                 skip "LU-10370: no implementation for ZFS"
21771         fi
21772
21773         local trunc_sz
21774         local grant_blk_size
21775
21776         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21777                         awk '/grant_block_size:/ { print $2; exit; }')
21778         #
21779         # Create File of size 5M. Truncate it to below size's and verify
21780         # blocks count.
21781         #
21782         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21783                 error "Create file $DIR/$tfile failed"
21784         stack_trap "rm -f $DIR/$tfile" EXIT
21785
21786         for trunc_sz in 2097152 4097 4000 509 0; do
21787                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21788                         error "truncate $tfile to $trunc_sz failed"
21789                 local sz=$(stat --format=%s $DIR/$tfile)
21790                 local blk=$(stat --format=%b $DIR/$tfile)
21791                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21792                                      grant_blk_size) * 8))
21793
21794                 if [[ $blk -ne $trunc_blk ]]; then
21795                         $(which stat) $DIR/$tfile
21796                         error "Expected Block $trunc_blk got $blk for $tfile"
21797                 fi
21798
21799                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21800                         error "Expected Size $trunc_sz got $sz for $tfile"
21801         done
21802
21803         #
21804         # sparse file test
21805         # Create file with a hole and write actual two blocks. Block count
21806         # must be 16.
21807         #
21808         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21809                 conv=fsync || error "Create file : $DIR/$tfile"
21810
21811         # Calculate the final truncate size.
21812         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21813
21814         #
21815         # truncate to size $trunc_sz bytes. Strip the last block
21816         # The block count must drop to 8
21817         #
21818         $TRUNCATE $DIR/$tfile $trunc_sz ||
21819                 error "truncate $tfile to $trunc_sz failed"
21820
21821         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
21822         sz=$(stat --format=%s $DIR/$tfile)
21823         blk=$(stat --format=%b $DIR/$tfile)
21824
21825         if [[ $blk -ne $trunc_bsz ]]; then
21826                 $(which stat) $DIR/$tfile
21827                 error "Expected Block $trunc_bsz got $blk for $tfile"
21828         fi
21829
21830         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21831                 error "Expected Size $trunc_sz got $sz for $tfile"
21832 }
21833 run_test 317 "Verify blocks get correctly update after truncate"
21834
21835 test_318() {
21836         local old_max_active=$($LCTL get_param -n \
21837                             llite.*.max_read_ahead_async_active 2>/dev/null)
21838
21839         $LCTL set_param llite.*.max_read_ahead_async_active=256
21840         local max_active=$($LCTL get_param -n \
21841                            llite.*.max_read_ahead_async_active 2>/dev/null)
21842         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
21843
21844         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
21845                 error "set max_read_ahead_async_active should succeed"
21846
21847         $LCTL set_param llite.*.max_read_ahead_async_active=512
21848         max_active=$($LCTL get_param -n \
21849                      llite.*.max_read_ahead_async_active 2>/dev/null)
21850         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
21851
21852         # restore @max_active
21853         [ $old_max_active -ne 0 ] && $LCTL set_param \
21854                 llite.*.max_read_ahead_async_active=$old_max_active
21855
21856         local old_threshold=$($LCTL get_param -n \
21857                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21858         local max_per_file_mb=$($LCTL get_param -n \
21859                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
21860
21861         local invalid=$(($max_per_file_mb + 1))
21862         $LCTL set_param \
21863                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
21864                         && error "set $invalid should fail"
21865
21866         local valid=$(($invalid - 1))
21867         $LCTL set_param \
21868                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
21869                         error "set $valid should succeed"
21870         local threshold=$($LCTL get_param -n \
21871                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21872         [ $threshold -eq $valid ] || error \
21873                 "expect threshold $valid got $threshold"
21874         $LCTL set_param \
21875                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
21876 }
21877 run_test 318 "Verify async readahead tunables"
21878
21879 test_319() {
21880         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
21881
21882         local before=$(date +%s)
21883         local evict
21884         local mdir=$DIR/$tdir
21885         local file=$mdir/xxx
21886
21887         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
21888         touch $file
21889
21890 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
21891         $LCTL set_param fail_val=5 fail_loc=0x8000032c
21892         $LFS mv -m1 $file &
21893
21894         sleep 1
21895         dd if=$file of=/dev/null
21896         wait
21897         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
21898           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
21899
21900         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
21901 }
21902 run_test 319 "lost lease lock on migrate error"
21903
21904 test_398a() { # LU-4198
21905         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21906         $LCTL set_param ldlm.namespaces.*.lru_size=clear
21907
21908         # request a new lock on client
21909         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21910
21911         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21912         local lock_count=$($LCTL get_param -n \
21913                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21914         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
21915
21916         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
21917
21918         # no lock cached, should use lockless IO and not enqueue new lock
21919         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21920         lock_count=$($LCTL get_param -n \
21921                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21922         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
21923 }
21924 run_test 398a "direct IO should cancel lock otherwise lockless"
21925
21926 test_398b() { # LU-4198
21927         which fio || skip_env "no fio installed"
21928         $LFS setstripe -c -1 $DIR/$tfile
21929
21930         local size=12
21931         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
21932
21933         local njobs=4
21934         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
21935         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21936                 --numjobs=$njobs --fallocate=none \
21937                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21938                 --filename=$DIR/$tfile &
21939         bg_pid=$!
21940
21941         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
21942         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
21943                 --numjobs=$njobs --fallocate=none \
21944                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21945                 --filename=$DIR/$tfile || true
21946         wait $bg_pid
21947
21948         rm -rf $DIR/$tfile
21949 }
21950 run_test 398b "DIO and buffer IO race"
21951
21952 test_398c() { # LU-4198
21953         which fio || skip_env "no fio installed"
21954
21955         saved_debug=$($LCTL get_param -n debug)
21956         $LCTL set_param debug=0
21957
21958         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
21959         ((size /= 1024)) # by megabytes
21960         ((size /= 2)) # write half of the OST at most
21961         [ $size -gt 40 ] && size=40 #reduce test time anyway
21962
21963         $LFS setstripe -c 1 $DIR/$tfile
21964
21965         # it seems like ldiskfs reserves more space than necessary if the
21966         # writing blocks are not mapped, so it extends the file firstly
21967         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
21968         cancel_lru_locks osc
21969
21970         # clear and verify rpc_stats later
21971         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
21972
21973         local njobs=4
21974         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
21975         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
21976                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
21977                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21978                 --filename=$DIR/$tfile
21979         [ $? -eq 0 ] || error "fio write error"
21980
21981         [ $($LCTL get_param -n \
21982          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
21983                 error "Locks were requested while doing AIO"
21984
21985         # get the percentage of 1-page I/O
21986         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
21987                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
21988                 awk '{print $7}')
21989         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
21990
21991         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
21992         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21993                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
21994                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21995                 --filename=$DIR/$tfile
21996         [ $? -eq 0 ] || error "fio mixed read write error"
21997
21998         echo "AIO with large block size ${size}M"
21999         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22000                 --numjobs=1 --fallocate=none --ioengine=libaio \
22001                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22002                 --filename=$DIR/$tfile
22003         [ $? -eq 0 ] || error "fio large block size failed"
22004
22005         rm -rf $DIR/$tfile
22006         $LCTL set_param debug="$saved_debug"
22007 }
22008 run_test 398c "run fio to test AIO"
22009
22010 test_398d() { #  LU-13846
22011         test -f aiocp || skip_env "no aiocp installed"
22012         local aio_file=$DIR/aio_file
22013
22014         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22015
22016         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22017         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22018
22019         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22020         rm -rf $DIR/$tfile $aio_file
22021 }
22022 run_test 398d "run aiocp to verify block size > stripe size"
22023
22024 test_fake_rw() {
22025         local read_write=$1
22026         if [ "$read_write" = "write" ]; then
22027                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22028         elif [ "$read_write" = "read" ]; then
22029                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22030         else
22031                 error "argument error"
22032         fi
22033
22034         # turn off debug for performance testing
22035         local saved_debug=$($LCTL get_param -n debug)
22036         $LCTL set_param debug=0
22037
22038         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22039
22040         # get ost1 size - $FSNAME-OST0000
22041         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22042         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22043         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22044
22045         if [ "$read_write" = "read" ]; then
22046                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
22047         fi
22048
22049         local start_time=$(date +%s.%N)
22050         $dd_cmd bs=1M count=$blocks oflag=sync ||
22051                 error "real dd $read_write error"
22052         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22053
22054         if [ "$read_write" = "write" ]; then
22055                 rm -f $DIR/$tfile
22056         fi
22057
22058         # define OBD_FAIL_OST_FAKE_RW           0x238
22059         do_facet ost1 $LCTL set_param fail_loc=0x238
22060
22061         local start_time=$(date +%s.%N)
22062         $dd_cmd bs=1M count=$blocks oflag=sync ||
22063                 error "fake dd $read_write error"
22064         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22065
22066         if [ "$read_write" = "write" ]; then
22067                 # verify file size
22068                 cancel_lru_locks osc
22069                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22070                         error "$tfile size not $blocks MB"
22071         fi
22072         do_facet ost1 $LCTL set_param fail_loc=0
22073
22074         echo "fake $read_write $duration_fake vs. normal $read_write" \
22075                 "$duration in seconds"
22076         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22077                 error_not_in_vm "fake write is slower"
22078
22079         $LCTL set_param -n debug="$saved_debug"
22080         rm -f $DIR/$tfile
22081 }
22082 test_399a() { # LU-7655 for OST fake write
22083         remote_ost_nodsh && skip "remote OST with nodsh"
22084
22085         test_fake_rw write
22086 }
22087 run_test 399a "fake write should not be slower than normal write"
22088
22089 test_399b() { # LU-8726 for OST fake read
22090         remote_ost_nodsh && skip "remote OST with nodsh"
22091         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22092                 skip_env "ldiskfs only test"
22093         fi
22094
22095         test_fake_rw read
22096 }
22097 run_test 399b "fake read should not be slower than normal read"
22098
22099 test_400a() { # LU-1606, was conf-sanity test_74
22100         if ! which $CC > /dev/null 2>&1; then
22101                 skip_env "$CC is not installed"
22102         fi
22103
22104         local extra_flags=''
22105         local out=$TMP/$tfile
22106         local prefix=/usr/include/lustre
22107         local prog
22108
22109         # Oleg removes c files in his test rig so test if any c files exist
22110         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22111                 skip_env "Needed c test files are missing"
22112
22113         if ! [[ -d $prefix ]]; then
22114                 # Assume we're running in tree and fixup the include path.
22115                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22116                 extra_flags+=" -L$LUSTRE/utils/.lib"
22117         fi
22118
22119         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22120                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22121                         error "client api broken"
22122         done
22123         rm -f $out
22124 }
22125 run_test 400a "Lustre client api program can compile and link"
22126
22127 test_400b() { # LU-1606, LU-5011
22128         local header
22129         local out=$TMP/$tfile
22130         local prefix=/usr/include/linux/lustre
22131
22132         # We use a hard coded prefix so that this test will not fail
22133         # when run in tree. There are headers in lustre/include/lustre/
22134         # that are not packaged (like lustre_idl.h) and have more
22135         # complicated include dependencies (like config.h and lnet/types.h).
22136         # Since this test about correct packaging we just skip them when
22137         # they don't exist (see below) rather than try to fixup cppflags.
22138
22139         if ! which $CC > /dev/null 2>&1; then
22140                 skip_env "$CC is not installed"
22141         fi
22142
22143         for header in $prefix/*.h; do
22144                 if ! [[ -f "$header" ]]; then
22145                         continue
22146                 fi
22147
22148                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22149                         continue # lustre_ioctl.h is internal header
22150                 fi
22151
22152                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22153                         error "cannot compile '$header'"
22154         done
22155         rm -f $out
22156 }
22157 run_test 400b "packaged headers can be compiled"
22158
22159 test_401a() { #LU-7437
22160         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22161         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22162
22163         #count the number of parameters by "list_param -R"
22164         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22165         #count the number of parameters by listing proc files
22166         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22167         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22168         echo "proc_dirs='$proc_dirs'"
22169         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22170         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22171                       sort -u | wc -l)
22172
22173         [ $params -eq $procs ] ||
22174                 error "found $params parameters vs. $procs proc files"
22175
22176         # test the list_param -D option only returns directories
22177         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22178         #count the number of parameters by listing proc directories
22179         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22180                 sort -u | wc -l)
22181
22182         [ $params -eq $procs ] ||
22183                 error "found $params parameters vs. $procs proc files"
22184 }
22185 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22186
22187 test_401b() {
22188         local save=$($LCTL get_param -n jobid_var)
22189         local tmp=testing
22190
22191         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
22192                 error "no error returned when setting bad parameters"
22193
22194         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
22195         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22196
22197         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
22198         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
22199         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22200 }
22201 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22202
22203 test_401c() {
22204         local jobid_var_old=$($LCTL get_param -n jobid_var)
22205         local jobid_var_new
22206
22207         $LCTL set_param jobid_var= &&
22208                 error "no error returned for 'set_param a='"
22209
22210         jobid_var_new=$($LCTL get_param -n jobid_var)
22211         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22212                 error "jobid_var was changed by setting without value"
22213
22214         $LCTL set_param jobid_var &&
22215                 error "no error returned for 'set_param a'"
22216
22217         jobid_var_new=$($LCTL get_param -n jobid_var)
22218         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22219                 error "jobid_var was changed by setting without value"
22220 }
22221 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22222
22223 test_401d() {
22224         local jobid_var_old=$($LCTL get_param -n jobid_var)
22225         local jobid_var_new
22226         local new_value="foo=bar"
22227
22228         $LCTL set_param jobid_var=$new_value ||
22229                 error "'set_param a=b' did not accept a value containing '='"
22230
22231         jobid_var_new=$($LCTL get_param -n jobid_var)
22232         [[ "$jobid_var_new" == "$new_value" ]] ||
22233                 error "'set_param a=b' failed on a value containing '='"
22234
22235         # Reset the jobid_var to test the other format
22236         $LCTL set_param jobid_var=$jobid_var_old
22237         jobid_var_new=$($LCTL get_param -n jobid_var)
22238         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22239                 error "failed to reset jobid_var"
22240
22241         $LCTL set_param jobid_var $new_value ||
22242                 error "'set_param a b' did not accept a value containing '='"
22243
22244         jobid_var_new=$($LCTL get_param -n jobid_var)
22245         [[ "$jobid_var_new" == "$new_value" ]] ||
22246                 error "'set_param a b' failed on a value containing '='"
22247
22248         $LCTL set_param jobid_var $jobid_var_old
22249         jobid_var_new=$($LCTL get_param -n jobid_var)
22250         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22251                 error "failed to reset jobid_var"
22252 }
22253 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22254
22255 test_402() {
22256         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22257         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22258                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22259         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22260                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22261                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22262         remote_mds_nodsh && skip "remote MDS with nodsh"
22263
22264         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22265 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22266         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22267         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22268                 echo "Touch failed - OK"
22269 }
22270 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22271
22272 test_403() {
22273         local file1=$DIR/$tfile.1
22274         local file2=$DIR/$tfile.2
22275         local tfile=$TMP/$tfile
22276
22277         rm -f $file1 $file2 $tfile
22278
22279         touch $file1
22280         ln $file1 $file2
22281
22282         # 30 sec OBD_TIMEOUT in ll_getattr()
22283         # right before populating st_nlink
22284         $LCTL set_param fail_loc=0x80001409
22285         stat -c %h $file1 > $tfile &
22286
22287         # create an alias, drop all locks and reclaim the dentry
22288         < $file2
22289         cancel_lru_locks mdc
22290         cancel_lru_locks osc
22291         sysctl -w vm.drop_caches=2
22292
22293         wait
22294
22295         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22296
22297         rm -f $tfile $file1 $file2
22298 }
22299 run_test 403 "i_nlink should not drop to zero due to aliasing"
22300
22301 test_404() { # LU-6601
22302         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22303                 skip "Need server version newer than 2.8.52"
22304         remote_mds_nodsh && skip "remote MDS with nodsh"
22305
22306         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22307                 awk '/osp .*-osc-MDT/ { print $4}')
22308
22309         local osp
22310         for osp in $mosps; do
22311                 echo "Deactivate: " $osp
22312                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22313                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22314                         awk -vp=$osp '$4 == p { print $2 }')
22315                 [ $stat = IN ] || {
22316                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22317                         error "deactivate error"
22318                 }
22319                 echo "Activate: " $osp
22320                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22321                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22322                         awk -vp=$osp '$4 == p { print $2 }')
22323                 [ $stat = UP ] || {
22324                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22325                         error "activate error"
22326                 }
22327         done
22328 }
22329 run_test 404 "validate manual {de}activated works properly for OSPs"
22330
22331 test_405() {
22332         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22333         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22334                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22335                         skip "Layout swap lock is not supported"
22336
22337         check_swap_layouts_support
22338         check_swap_layout_no_dom $DIR
22339
22340         test_mkdir $DIR/$tdir
22341         swap_lock_test -d $DIR/$tdir ||
22342                 error "One layout swap locked test failed"
22343 }
22344 run_test 405 "Various layout swap lock tests"
22345
22346 test_406() {
22347         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22348         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22349         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22351         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22352                 skip "Need MDS version at least 2.8.50"
22353
22354         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22355         local test_pool=$TESTNAME
22356
22357         pool_add $test_pool || error "pool_add failed"
22358         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22359                 error "pool_add_targets failed"
22360
22361         save_layout_restore_at_exit $MOUNT
22362
22363         # parent set default stripe count only, child will stripe from both
22364         # parent and fs default
22365         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22366                 error "setstripe $MOUNT failed"
22367         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22368         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22369         for i in $(seq 10); do
22370                 local f=$DIR/$tdir/$tfile.$i
22371                 touch $f || error "touch failed"
22372                 local count=$($LFS getstripe -c $f)
22373                 [ $count -eq $OSTCOUNT ] ||
22374                         error "$f stripe count $count != $OSTCOUNT"
22375                 local offset=$($LFS getstripe -i $f)
22376                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22377                 local size=$($LFS getstripe -S $f)
22378                 [ $size -eq $((def_stripe_size * 2)) ] ||
22379                         error "$f stripe size $size != $((def_stripe_size * 2))"
22380                 local pool=$($LFS getstripe -p $f)
22381                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22382         done
22383
22384         # change fs default striping, delete parent default striping, now child
22385         # will stripe from new fs default striping only
22386         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22387                 error "change $MOUNT default stripe failed"
22388         $LFS setstripe -c 0 $DIR/$tdir ||
22389                 error "delete $tdir default stripe failed"
22390         for i in $(seq 11 20); do
22391                 local f=$DIR/$tdir/$tfile.$i
22392                 touch $f || error "touch $f failed"
22393                 local count=$($LFS getstripe -c $f)
22394                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22395                 local offset=$($LFS getstripe -i $f)
22396                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22397                 local size=$($LFS getstripe -S $f)
22398                 [ $size -eq $def_stripe_size ] ||
22399                         error "$f stripe size $size != $def_stripe_size"
22400                 local pool=$($LFS getstripe -p $f)
22401                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22402         done
22403
22404         unlinkmany $DIR/$tdir/$tfile. 1 20
22405
22406         local f=$DIR/$tdir/$tfile
22407         pool_remove_all_targets $test_pool $f
22408         pool_remove $test_pool $f
22409 }
22410 run_test 406 "DNE support fs default striping"
22411
22412 test_407() {
22413         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22414         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22415                 skip "Need MDS version at least 2.8.55"
22416         remote_mds_nodsh && skip "remote MDS with nodsh"
22417
22418         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22419                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22420         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22421                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22422         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22423
22424         #define OBD_FAIL_DT_TXN_STOP    0x2019
22425         for idx in $(seq $MDSCOUNT); do
22426                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22427         done
22428         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22429         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22430                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22431         true
22432 }
22433 run_test 407 "transaction fail should cause operation fail"
22434
22435 test_408() {
22436         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22437
22438         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22439         lctl set_param fail_loc=0x8000040a
22440         # let ll_prepare_partial_page() fail
22441         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22442
22443         rm -f $DIR/$tfile
22444
22445         # create at least 100 unused inodes so that
22446         # shrink_icache_memory(0) should not return 0
22447         touch $DIR/$tfile-{0..100}
22448         rm -f $DIR/$tfile-{0..100}
22449         sync
22450
22451         echo 2 > /proc/sys/vm/drop_caches
22452 }
22453 run_test 408 "drop_caches should not hang due to page leaks"
22454
22455 test_409()
22456 {
22457         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22458
22459         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22460         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22461         touch $DIR/$tdir/guard || error "(2) Fail to create"
22462
22463         local PREFIX=$(str_repeat 'A' 128)
22464         echo "Create 1K hard links start at $(date)"
22465         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22466                 error "(3) Fail to hard link"
22467
22468         echo "Links count should be right although linkEA overflow"
22469         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22470         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22471         [ $linkcount -eq 1001 ] ||
22472                 error "(5) Unexpected hard links count: $linkcount"
22473
22474         echo "List all links start at $(date)"
22475         ls -l $DIR/$tdir/foo > /dev/null ||
22476                 error "(6) Fail to list $DIR/$tdir/foo"
22477
22478         echo "Unlink hard links start at $(date)"
22479         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22480                 error "(7) Fail to unlink"
22481         echo "Unlink hard links finished at $(date)"
22482 }
22483 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22484
22485 test_410()
22486 {
22487         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22488                 skip "Need client version at least 2.9.59"
22489         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22490                 skip "Need MODULES build"
22491
22492         # Create a file, and stat it from the kernel
22493         local testfile=$DIR/$tfile
22494         touch $testfile
22495
22496         local run_id=$RANDOM
22497         local my_ino=$(stat --format "%i" $testfile)
22498
22499         # Try to insert the module. This will always fail as the
22500         # module is designed to not be inserted.
22501         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22502             &> /dev/null
22503
22504         # Anything but success is a test failure
22505         dmesg | grep -q \
22506             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22507             error "no inode match"
22508 }
22509 run_test 410 "Test inode number returned from kernel thread"
22510
22511 cleanup_test411_cgroup() {
22512         trap 0
22513         rmdir "$1"
22514 }
22515
22516 test_411() {
22517         local cg_basedir=/sys/fs/cgroup/memory
22518         # LU-9966
22519         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22520                 skip "no setup for cgroup"
22521
22522         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22523                 error "test file creation failed"
22524         cancel_lru_locks osc
22525
22526         # Create a very small memory cgroup to force a slab allocation error
22527         local cgdir=$cg_basedir/osc_slab_alloc
22528         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22529         trap "cleanup_test411_cgroup $cgdir" EXIT
22530         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22531         echo 1M > $cgdir/memory.limit_in_bytes
22532
22533         # Should not LBUG, just be killed by oom-killer
22534         # dd will return 0 even allocation failure in some environment.
22535         # So don't check return value
22536         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22537         cleanup_test411_cgroup $cgdir
22538
22539         return 0
22540 }
22541 run_test 411 "Slab allocation error with cgroup does not LBUG"
22542
22543 test_412() {
22544         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22545         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22546                 skip "Need server version at least 2.10.55"
22547         fi
22548
22549         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22550                 error "mkdir failed"
22551         $LFS getdirstripe $DIR/$tdir
22552         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22553         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22554                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22555         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22556         [ $stripe_count -eq 2 ] ||
22557                 error "expect 2 get $stripe_count"
22558 }
22559 run_test 412 "mkdir on specific MDTs"
22560
22561 test_qos_mkdir() {
22562         local mkdir_cmd=$1
22563         local stripe_count=$2
22564         local mdts=$(comma_list $(mdts_nodes))
22565
22566         local testdir
22567         local lmv_qos_prio_free
22568         local lmv_qos_threshold_rr
22569         local lmv_qos_maxage
22570         local lod_qos_prio_free
22571         local lod_qos_threshold_rr
22572         local lod_qos_maxage
22573         local count
22574         local i
22575
22576         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22577         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22578         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22579                 head -n1)
22580         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22581         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22582         stack_trap "$LCTL set_param \
22583                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22584         stack_trap "$LCTL set_param \
22585                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22586         stack_trap "$LCTL set_param \
22587                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22588
22589         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22590                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22591         lod_qos_prio_free=${lod_qos_prio_free%%%}
22592         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22593                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22594         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22595         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22596                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22597         stack_trap "do_nodes $mdts $LCTL set_param \
22598                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22599         stack_trap "do_nodes $mdts $LCTL set_param \
22600                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22601                 EXIT
22602         stack_trap "do_nodes $mdts $LCTL set_param \
22603                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22604
22605         echo
22606         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22607
22608         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22609         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22610
22611         testdir=$DIR/$tdir-s$stripe_count/rr
22612
22613         for i in $(seq $((100 * MDSCOUNT))); do
22614                 eval $mkdir_cmd $testdir/subdir$i ||
22615                         error "$mkdir_cmd subdir$i failed"
22616         done
22617
22618         for i in $(seq $MDSCOUNT); do
22619                 count=$($LFS getdirstripe -i $testdir/* |
22620                                 grep ^$((i - 1))$ | wc -l)
22621                 echo "$count directories created on MDT$((i - 1))"
22622                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22623
22624                 if [ $stripe_count -gt 1 ]; then
22625                         count=$($LFS getdirstripe $testdir/* |
22626                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22627                         echo "$count stripes created on MDT$((i - 1))"
22628                         # deviation should < 5% of average
22629                         [ $count -lt $((95 * stripe_count)) ] ||
22630                         [ $count -gt $((105 * stripe_count)) ] &&
22631                                 error "stripes are not evenly distributed"
22632                 fi
22633         done
22634
22635         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22636         do_nodes $mdts $LCTL set_param \
22637                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22638
22639         echo
22640         echo "Check for uneven MDTs: "
22641
22642         local ffree
22643         local bavail
22644         local max
22645         local min
22646         local max_index
22647         local min_index
22648         local tmp
22649
22650         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22651         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22652         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22653
22654         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22655         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22656         max_index=0
22657         min_index=0
22658         for ((i = 1; i < ${#ffree[@]}; i++)); do
22659                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22660                 if [ $tmp -gt $max ]; then
22661                         max=$tmp
22662                         max_index=$i
22663                 fi
22664                 if [ $tmp -lt $min ]; then
22665                         min=$tmp
22666                         min_index=$i
22667                 fi
22668         done
22669
22670         [ ${ffree[min_index]} -eq 0 ] &&
22671                 skip "no free files in MDT$min_index"
22672         [ ${ffree[min_index]} -gt 100000000 ] &&
22673                 skip "too much free files in MDT$min_index"
22674
22675         # Check if we need to generate uneven MDTs
22676         local threshold=50
22677         local diff=$(((max - min) * 100 / min))
22678         local value="$(generate_string 1024)"
22679
22680         while [ $diff -lt $threshold ]; do
22681                 # generate uneven MDTs, create till $threshold% diff
22682                 echo -n "weight diff=$diff% must be > $threshold% ..."
22683                 count=$((${ffree[min_index]} / 10))
22684                 # 50 sec per 10000 files in vm
22685                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22686                         skip "$count files to create"
22687                 echo "Fill MDT$min_index with $count files"
22688                 [ -d $DIR/$tdir-MDT$min_index ] ||
22689                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22690                         error "mkdir $tdir-MDT$min_index failed"
22691                 for i in $(seq $count); do
22692                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22693                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22694                                 error "create f$j_$i failed"
22695                         setfattr -n user.413b -v $value \
22696                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22697                                 error "setfattr f$j_$i failed"
22698                 done
22699
22700                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22701                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22702                 max=$(((${ffree[max_index]} >> 8) * \
22703                         (${bavail[max_index]} * bsize >> 16)))
22704                 min=$(((${ffree[min_index]} >> 8) * \
22705                         (${bavail[min_index]} * bsize >> 16)))
22706                 diff=$(((max - min) * 100 / min))
22707         done
22708
22709         echo "MDT filesfree available: ${ffree[@]}"
22710         echo "MDT blocks available: ${bavail[@]}"
22711         echo "weight diff=$diff%"
22712
22713         echo
22714         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22715
22716         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22717         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22718         # decrease statfs age, so that it can be updated in time
22719         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22720         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22721
22722         sleep 1
22723
22724         testdir=$DIR/$tdir-s$stripe_count/qos
22725
22726         for i in $(seq $((100 * MDSCOUNT))); do
22727                 eval $mkdir_cmd $testdir/subdir$i ||
22728                         error "$mkdir_cmd subdir$i failed"
22729         done
22730
22731         for i in $(seq $MDSCOUNT); do
22732                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22733                         wc -l)
22734                 echo "$count directories created on MDT$((i - 1))"
22735
22736                 if [ $stripe_count -gt 1 ]; then
22737                         count=$($LFS getdirstripe $testdir/* |
22738                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22739                         echo "$count stripes created on MDT$((i - 1))"
22740                 fi
22741         done
22742
22743         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
22744         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22745
22746         # D-value should > 10% of averge
22747         [ $((max - min)) -lt 10 ] &&
22748                 error "subdirs shouldn't be evenly distributed"
22749
22750         # ditto
22751         if [ $stripe_count -gt 1 ]; then
22752                 max=$($LFS getdirstripe $testdir/* |
22753                         grep -P "^\s+$max_index\t" | wc -l)
22754                 min=$($LFS getdirstripe $testdir/* |
22755                         grep -P "^\s+$min_index\t" | wc -l)
22756                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22757                         error "stripes shouldn't be evenly distributed"|| true
22758         fi
22759 }
22760
22761 test_413a() {
22762         [ $MDSCOUNT -lt 2 ] &&
22763                 skip "We need at least 2 MDTs for this test"
22764
22765         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22766                 skip "Need server version at least 2.12.52"
22767
22768         local stripe_count
22769
22770         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22771                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22772                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22773                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22774                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22775         done
22776 }
22777 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22778
22779 test_413b() {
22780         [ $MDSCOUNT -lt 2 ] &&
22781                 skip "We need at least 2 MDTs for this test"
22782
22783         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22784                 skip "Need server version at least 2.12.52"
22785
22786         local stripe_count
22787
22788         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22789                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22790                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22791                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22792                 $LFS setdirstripe -D -c $stripe_count \
22793                         $DIR/$tdir-s$stripe_count/rr ||
22794                         error "setdirstripe failed"
22795                 $LFS setdirstripe -D -c $stripe_count \
22796                         $DIR/$tdir-s$stripe_count/qos ||
22797                         error "setdirstripe failed"
22798                 test_qos_mkdir "mkdir" $stripe_count
22799         done
22800 }
22801 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
22802
22803 test_414() {
22804 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
22805         $LCTL set_param fail_loc=0x80000521
22806         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
22807         rm -f $DIR/$tfile
22808 }
22809 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
22810
22811 test_415() {
22812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22813         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22814                 skip "Need server version at least 2.11.52"
22815
22816         # LU-11102
22817         local total
22818         local setattr_pid
22819         local start_time
22820         local end_time
22821         local duration
22822
22823         total=500
22824         # this test may be slow on ZFS
22825         [ "$mds1_FSTYPE" == "zfs" ] && total=100
22826
22827         # though this test is designed for striped directory, let's test normal
22828         # directory too since lock is always saved as CoS lock.
22829         test_mkdir $DIR/$tdir || error "mkdir $tdir"
22830         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
22831
22832         (
22833                 while true; do
22834                         touch $DIR/$tdir
22835                 done
22836         ) &
22837         setattr_pid=$!
22838
22839         start_time=$(date +%s)
22840         for i in $(seq $total); do
22841                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
22842                         > /dev/null
22843         done
22844         end_time=$(date +%s)
22845         duration=$((end_time - start_time))
22846
22847         kill -9 $setattr_pid
22848
22849         echo "rename $total files took $duration sec"
22850         [ $duration -lt 100 ] || error "rename took $duration sec"
22851 }
22852 run_test 415 "lock revoke is not missing"
22853
22854 test_416() {
22855         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22856                 skip "Need server version at least 2.11.55"
22857
22858         # define OBD_FAIL_OSD_TXN_START    0x19a
22859         do_facet mds1 lctl set_param fail_loc=0x19a
22860
22861         lfs mkdir -c $MDSCOUNT $DIR/$tdir
22862
22863         true
22864 }
22865 run_test 416 "transaction start failure won't cause system hung"
22866
22867 cleanup_417() {
22868         trap 0
22869         do_nodes $(comma_list $(mdts_nodes)) \
22870                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
22871         do_nodes $(comma_list $(mdts_nodes)) \
22872                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
22873         do_nodes $(comma_list $(mdts_nodes)) \
22874                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
22875 }
22876
22877 test_417() {
22878         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22879         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
22880                 skip "Need MDS version at least 2.11.56"
22881
22882         trap cleanup_417 RETURN EXIT
22883
22884         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
22885         do_nodes $(comma_list $(mdts_nodes)) \
22886                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
22887         $LFS migrate -m 0 $DIR/$tdir.1 &&
22888                 error "migrate dir $tdir.1 should fail"
22889
22890         do_nodes $(comma_list $(mdts_nodes)) \
22891                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
22892         $LFS mkdir -i 1 $DIR/$tdir.2 &&
22893                 error "create remote dir $tdir.2 should fail"
22894
22895         do_nodes $(comma_list $(mdts_nodes)) \
22896                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
22897         $LFS mkdir -c 2 $DIR/$tdir.3 &&
22898                 error "create striped dir $tdir.3 should fail"
22899         true
22900 }
22901 run_test 417 "disable remote dir, striped dir and dir migration"
22902
22903 # Checks that the outputs of df [-i] and lfs df [-i] match
22904 #
22905 # usage: check_lfs_df <blocks | inodes> <mountpoint>
22906 check_lfs_df() {
22907         local dir=$2
22908         local inodes
22909         local df_out
22910         local lfs_df_out
22911         local count
22912         local passed=false
22913
22914         # blocks or inodes
22915         [ "$1" == "blocks" ] && inodes= || inodes="-i"
22916
22917         for count in {1..100}; do
22918                 cancel_lru_locks
22919                 sync; sleep 0.2
22920
22921                 # read the lines of interest
22922                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
22923                         error "df $inodes $dir | tail -n +2 failed"
22924                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
22925                         error "lfs df $inodes $dir | grep summary: failed"
22926
22927                 # skip first substrings of each output as they are different
22928                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
22929                 # compare the two outputs
22930                 passed=true
22931                 for i in {1..5}; do
22932                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
22933                 done
22934                 $passed && break
22935         done
22936
22937         if ! $passed; then
22938                 df -P $inodes $dir
22939                 echo
22940                 lfs df $inodes $dir
22941                 error "df and lfs df $1 output mismatch: "      \
22942                       "df ${inodes}: ${df_out[*]}, "            \
22943                       "lfs df ${inodes}: ${lfs_df_out[*]}"
22944         fi
22945 }
22946
22947 test_418() {
22948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22949
22950         local dir=$DIR/$tdir
22951         local numfiles=$((RANDOM % 4096 + 2))
22952         local numblocks=$((RANDOM % 256 + 1))
22953
22954         wait_delete_completed
22955         test_mkdir $dir
22956
22957         # check block output
22958         check_lfs_df blocks $dir
22959         # check inode output
22960         check_lfs_df inodes $dir
22961
22962         # create a single file and retest
22963         echo "Creating a single file and testing"
22964         createmany -o $dir/$tfile- 1 &>/dev/null ||
22965                 error "creating 1 file in $dir failed"
22966         check_lfs_df blocks $dir
22967         check_lfs_df inodes $dir
22968
22969         # create a random number of files
22970         echo "Creating $((numfiles - 1)) files and testing"
22971         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
22972                 error "creating $((numfiles - 1)) files in $dir failed"
22973
22974         # write a random number of blocks to the first test file
22975         echo "Writing $numblocks 4K blocks and testing"
22976         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
22977                 count=$numblocks &>/dev/null ||
22978                 error "dd to $dir/${tfile}-0 failed"
22979
22980         # retest
22981         check_lfs_df blocks $dir
22982         check_lfs_df inodes $dir
22983
22984         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
22985                 error "unlinking $numfiles files in $dir failed"
22986 }
22987 run_test 418 "df and lfs df outputs match"
22988
22989 test_419()
22990 {
22991         local dir=$DIR/$tdir
22992
22993         mkdir -p $dir
22994         touch $dir/file
22995
22996         cancel_lru_locks mdc
22997
22998         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
22999         $LCTL set_param fail_loc=0x1410
23000         cat $dir/file
23001         $LCTL set_param fail_loc=0
23002         rm -rf $dir
23003 }
23004 run_test 419 "Verify open file by name doesn't crash kernel"
23005
23006 test_420()
23007 {
23008         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23009                 skip "Need MDS version at least 2.12.53"
23010
23011         local SAVE_UMASK=$(umask)
23012         local dir=$DIR/$tdir
23013         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23014
23015         mkdir -p $dir
23016         umask 0000
23017         mkdir -m03777 $dir/testdir
23018         ls -dn $dir/testdir
23019         # Need to remove trailing '.' when SELinux is enabled
23020         local dirperms=$(ls -dn $dir/testdir |
23021                          awk '{ sub(/\.$/, "", $1); print $1}')
23022         [ $dirperms == "drwxrwsrwt" ] ||
23023                 error "incorrect perms on $dir/testdir"
23024
23025         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23026                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23027         ls -n $dir/testdir/testfile
23028         local fileperms=$(ls -n $dir/testdir/testfile |
23029                           awk '{ sub(/\.$/, "", $1); print $1}')
23030         [ $fileperms == "-rwxr-xr-x" ] ||
23031                 error "incorrect perms on $dir/testdir/testfile"
23032
23033         umask $SAVE_UMASK
23034 }
23035 run_test 420 "clear SGID bit on non-directories for non-members"
23036
23037 test_421a() {
23038         local cnt
23039         local fid1
23040         local fid2
23041
23042         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23043                 skip "Need MDS version at least 2.12.54"
23044
23045         test_mkdir $DIR/$tdir
23046         createmany -o $DIR/$tdir/f 3
23047         cnt=$(ls -1 $DIR/$tdir | wc -l)
23048         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23049
23050         fid1=$(lfs path2fid $DIR/$tdir/f1)
23051         fid2=$(lfs path2fid $DIR/$tdir/f2)
23052         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23053
23054         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23055         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23056
23057         cnt=$(ls -1 $DIR/$tdir | wc -l)
23058         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23059
23060         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23061         createmany -o $DIR/$tdir/f 3
23062         cnt=$(ls -1 $DIR/$tdir | wc -l)
23063         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23064
23065         fid1=$(lfs path2fid $DIR/$tdir/f1)
23066         fid2=$(lfs path2fid $DIR/$tdir/f2)
23067         echo "remove using fsname $FSNAME"
23068         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23069
23070         cnt=$(ls -1 $DIR/$tdir | wc -l)
23071         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23072 }
23073 run_test 421a "simple rm by fid"
23074
23075 test_421b() {
23076         local cnt
23077         local FID1
23078         local FID2
23079
23080         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23081                 skip "Need MDS version at least 2.12.54"
23082
23083         test_mkdir $DIR/$tdir
23084         createmany -o $DIR/$tdir/f 3
23085         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23086         MULTIPID=$!
23087
23088         FID1=$(lfs path2fid $DIR/$tdir/f1)
23089         FID2=$(lfs path2fid $DIR/$tdir/f2)
23090         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23091
23092         kill -USR1 $MULTIPID
23093         wait
23094
23095         cnt=$(ls $DIR/$tdir | wc -l)
23096         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23097 }
23098 run_test 421b "rm by fid on open file"
23099
23100 test_421c() {
23101         local cnt
23102         local FIDS
23103
23104         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23105                 skip "Need MDS version at least 2.12.54"
23106
23107         test_mkdir $DIR/$tdir
23108         createmany -o $DIR/$tdir/f 3
23109         touch $DIR/$tdir/$tfile
23110         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23111         cnt=$(ls -1 $DIR/$tdir | wc -l)
23112         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23113
23114         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23115         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23116
23117         cnt=$(ls $DIR/$tdir | wc -l)
23118         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23119 }
23120 run_test 421c "rm by fid against hardlinked files"
23121
23122 test_421d() {
23123         local cnt
23124         local FIDS
23125
23126         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23127                 skip "Need MDS version at least 2.12.54"
23128
23129         test_mkdir $DIR/$tdir
23130         createmany -o $DIR/$tdir/f 4097
23131         cnt=$(ls -1 $DIR/$tdir | wc -l)
23132         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23133
23134         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23135         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23136
23137         cnt=$(ls $DIR/$tdir | wc -l)
23138         rm -rf $DIR/$tdir
23139         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23140 }
23141 run_test 421d "rmfid en masse"
23142
23143 test_421e() {
23144         local cnt
23145         local FID
23146
23147         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23148         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23149                 skip "Need MDS version at least 2.12.54"
23150
23151         mkdir -p $DIR/$tdir
23152         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23153         createmany -o $DIR/$tdir/striped_dir/f 512
23154         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23155         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23156
23157         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23158                 sed "s/[/][^:]*://g")
23159         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23160
23161         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23162         rm -rf $DIR/$tdir
23163         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23164 }
23165 run_test 421e "rmfid in DNE"
23166
23167 test_421f() {
23168         local cnt
23169         local FID
23170
23171         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23172                 skip "Need MDS version at least 2.12.54"
23173
23174         test_mkdir $DIR/$tdir
23175         touch $DIR/$tdir/f
23176         cnt=$(ls -1 $DIR/$tdir | wc -l)
23177         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23178
23179         FID=$(lfs path2fid $DIR/$tdir/f)
23180         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23181         # rmfid should fail
23182         cnt=$(ls -1 $DIR/$tdir | wc -l)
23183         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23184
23185         chmod a+rw $DIR/$tdir
23186         ls -la $DIR/$tdir
23187         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23188         # rmfid should fail
23189         cnt=$(ls -1 $DIR/$tdir | wc -l)
23190         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23191
23192         rm -f $DIR/$tdir/f
23193         $RUNAS touch $DIR/$tdir/f
23194         FID=$(lfs path2fid $DIR/$tdir/f)
23195         echo "rmfid as root"
23196         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23197         cnt=$(ls -1 $DIR/$tdir | wc -l)
23198         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23199
23200         rm -f $DIR/$tdir/f
23201         $RUNAS touch $DIR/$tdir/f
23202         cnt=$(ls -1 $DIR/$tdir | wc -l)
23203         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23204         FID=$(lfs path2fid $DIR/$tdir/f)
23205         # rmfid w/o user_fid2path mount option should fail
23206         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23207         cnt=$(ls -1 $DIR/$tdir | wc -l)
23208         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23209
23210         umount_client $MOUNT || error "failed to umount client"
23211         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23212                 error "failed to mount client'"
23213
23214         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23215         # rmfid should succeed
23216         cnt=$(ls -1 $DIR/$tdir | wc -l)
23217         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23218
23219         # rmfid shouldn't allow to remove files due to dir's permission
23220         chmod a+rwx $DIR/$tdir
23221         touch $DIR/$tdir/f
23222         ls -la $DIR/$tdir
23223         FID=$(lfs path2fid $DIR/$tdir/f)
23224         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23225
23226         umount_client $MOUNT || error "failed to umount client"
23227         mount_client $MOUNT "$MOUNT_OPTS" ||
23228                 error "failed to mount client'"
23229
23230 }
23231 run_test 421f "rmfid checks permissions"
23232
23233 test_421g() {
23234         local cnt
23235         local FIDS
23236
23237         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23238         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23239                 skip "Need MDS version at least 2.12.54"
23240
23241         mkdir -p $DIR/$tdir
23242         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23243         createmany -o $DIR/$tdir/striped_dir/f 512
23244         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23245         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23246
23247         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23248                 sed "s/[/][^:]*://g")
23249
23250         rm -f $DIR/$tdir/striped_dir/f1*
23251         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23252         removed=$((512 - cnt))
23253
23254         # few files have been just removed, so we expect
23255         # rmfid to fail on their fids
23256         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23257         [ $removed != $errors ] && error "$errors != $removed"
23258
23259         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23260         rm -rf $DIR/$tdir
23261         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23262 }
23263 run_test 421g "rmfid to return errors properly"
23264
23265 test_422() {
23266         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23267         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23268         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23269         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23270         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23271
23272         local amc=$(at_max_get client)
23273         local amo=$(at_max_get mds1)
23274         local timeout=`lctl get_param -n timeout`
23275
23276         at_max_set 0 client
23277         at_max_set 0 mds1
23278
23279 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23280         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23281                         fail_val=$(((2*timeout + 10)*1000))
23282         touch $DIR/$tdir/d3/file &
23283         sleep 2
23284 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23285         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23286                         fail_val=$((2*timeout + 5))
23287         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23288         local pid=$!
23289         sleep 1
23290         kill -9 $pid
23291         sleep $((2 * timeout))
23292         echo kill $pid
23293         kill -9 $pid
23294         lctl mark touch
23295         touch $DIR/$tdir/d2/file3
23296         touch $DIR/$tdir/d2/file4
23297         touch $DIR/$tdir/d2/file5
23298
23299         wait
23300         at_max_set $amc client
23301         at_max_set $amo mds1
23302
23303         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23304         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23305                 error "Watchdog is always throttled"
23306 }
23307 run_test 422 "kill a process with RPC in progress"
23308
23309 stat_test() {
23310     df -h $MOUNT &
23311     df -h $MOUNT &
23312     df -h $MOUNT &
23313     df -h $MOUNT &
23314     df -h $MOUNT &
23315     df -h $MOUNT &
23316 }
23317
23318 test_423() {
23319     local _stats
23320     # ensure statfs cache is expired
23321     sleep 2;
23322
23323     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23324     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23325
23326     return 0
23327 }
23328 run_test 423 "statfs should return a right data"
23329
23330 test_424() {
23331 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23332         $LCTL set_param fail_loc=0x80000522
23333         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23334         rm -f $DIR/$tfile
23335 }
23336 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23337
23338 prep_801() {
23339         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23340         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23341                 skip "Need server version at least 2.9.55"
23342
23343         start_full_debug_logging
23344 }
23345
23346 post_801() {
23347         stop_full_debug_logging
23348 }
23349
23350 barrier_stat() {
23351         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23352                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23353                            awk '/The barrier for/ { print $7 }')
23354                 echo $st
23355         else
23356                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23357                 echo \'$st\'
23358         fi
23359 }
23360
23361 barrier_expired() {
23362         local expired
23363
23364         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23365                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23366                           awk '/will be expired/ { print $7 }')
23367         else
23368                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23369         fi
23370
23371         echo $expired
23372 }
23373
23374 test_801a() {
23375         prep_801
23376
23377         echo "Start barrier_freeze at: $(date)"
23378         #define OBD_FAIL_BARRIER_DELAY          0x2202
23379         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23380         # Do not reduce barrier time - See LU-11873
23381         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23382
23383         sleep 2
23384         local b_status=$(barrier_stat)
23385         echo "Got barrier status at: $(date)"
23386         [ "$b_status" = "'freezing_p1'" ] ||
23387                 error "(1) unexpected barrier status $b_status"
23388
23389         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23390         wait
23391         b_status=$(barrier_stat)
23392         [ "$b_status" = "'frozen'" ] ||
23393                 error "(2) unexpected barrier status $b_status"
23394
23395         local expired=$(barrier_expired)
23396         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23397         sleep $((expired + 3))
23398
23399         b_status=$(barrier_stat)
23400         [ "$b_status" = "'expired'" ] ||
23401                 error "(3) unexpected barrier status $b_status"
23402
23403         # Do not reduce barrier time - See LU-11873
23404         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23405                 error "(4) fail to freeze barrier"
23406
23407         b_status=$(barrier_stat)
23408         [ "$b_status" = "'frozen'" ] ||
23409                 error "(5) unexpected barrier status $b_status"
23410
23411         echo "Start barrier_thaw at: $(date)"
23412         #define OBD_FAIL_BARRIER_DELAY          0x2202
23413         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23414         do_facet mgs $LCTL barrier_thaw $FSNAME &
23415
23416         sleep 2
23417         b_status=$(barrier_stat)
23418         echo "Got barrier status at: $(date)"
23419         [ "$b_status" = "'thawing'" ] ||
23420                 error "(6) unexpected barrier status $b_status"
23421
23422         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23423         wait
23424         b_status=$(barrier_stat)
23425         [ "$b_status" = "'thawed'" ] ||
23426                 error "(7) unexpected barrier status $b_status"
23427
23428         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23429         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23430         do_facet mgs $LCTL barrier_freeze $FSNAME
23431
23432         b_status=$(barrier_stat)
23433         [ "$b_status" = "'failed'" ] ||
23434                 error "(8) unexpected barrier status $b_status"
23435
23436         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23437         do_facet mgs $LCTL barrier_thaw $FSNAME
23438
23439         post_801
23440 }
23441 run_test 801a "write barrier user interfaces and stat machine"
23442
23443 test_801b() {
23444         prep_801
23445
23446         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23447         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23448         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23449         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23450         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23451
23452         cancel_lru_locks mdc
23453
23454         # 180 seconds should be long enough
23455         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23456
23457         local b_status=$(barrier_stat)
23458         [ "$b_status" = "'frozen'" ] ||
23459                 error "(6) unexpected barrier status $b_status"
23460
23461         mkdir $DIR/$tdir/d0/d10 &
23462         mkdir_pid=$!
23463
23464         touch $DIR/$tdir/d1/f13 &
23465         touch_pid=$!
23466
23467         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23468         ln_pid=$!
23469
23470         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23471         mv_pid=$!
23472
23473         rm -f $DIR/$tdir/d4/f12 &
23474         rm_pid=$!
23475
23476         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
23477
23478         # To guarantee taht the 'stat' is not blocked
23479         b_status=$(barrier_stat)
23480         [ "$b_status" = "'frozen'" ] ||
23481                 error "(8) unexpected barrier status $b_status"
23482
23483         # let above commands to run at background
23484         sleep 5
23485
23486         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
23487         ps -p $touch_pid || error "(10) touch should be blocked"
23488         ps -p $ln_pid || error "(11) link should be blocked"
23489         ps -p $mv_pid || error "(12) rename should be blocked"
23490         ps -p $rm_pid || error "(13) unlink should be blocked"
23491
23492         b_status=$(barrier_stat)
23493         [ "$b_status" = "'frozen'" ] ||
23494                 error "(14) unexpected barrier status $b_status"
23495
23496         do_facet mgs $LCTL barrier_thaw $FSNAME
23497         b_status=$(barrier_stat)
23498         [ "$b_status" = "'thawed'" ] ||
23499                 error "(15) unexpected barrier status $b_status"
23500
23501         wait $mkdir_pid || error "(16) mkdir should succeed"
23502         wait $touch_pid || error "(17) touch should succeed"
23503         wait $ln_pid || error "(18) link should succeed"
23504         wait $mv_pid || error "(19) rename should succeed"
23505         wait $rm_pid || error "(20) unlink should succeed"
23506
23507         post_801
23508 }
23509 run_test 801b "modification will be blocked by write barrier"
23510
23511 test_801c() {
23512         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23513
23514         prep_801
23515
23516         stop mds2 || error "(1) Fail to stop mds2"
23517
23518         do_facet mgs $LCTL barrier_freeze $FSNAME 30
23519
23520         local b_status=$(barrier_stat)
23521         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
23522                 do_facet mgs $LCTL barrier_thaw $FSNAME
23523                 error "(2) unexpected barrier status $b_status"
23524         }
23525
23526         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23527                 error "(3) Fail to rescan barrier bitmap"
23528
23529         # Do not reduce barrier time - See LU-11873
23530         do_facet mgs $LCTL barrier_freeze $FSNAME 20
23531
23532         b_status=$(barrier_stat)
23533         [ "$b_status" = "'frozen'" ] ||
23534                 error "(4) unexpected barrier status $b_status"
23535
23536         do_facet mgs $LCTL barrier_thaw $FSNAME
23537         b_status=$(barrier_stat)
23538         [ "$b_status" = "'thawed'" ] ||
23539                 error "(5) unexpected barrier status $b_status"
23540
23541         local devname=$(mdsdevname 2)
23542
23543         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
23544
23545         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23546                 error "(7) Fail to rescan barrier bitmap"
23547
23548         post_801
23549 }
23550 run_test 801c "rescan barrier bitmap"
23551
23552 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
23553 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
23554 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
23555 saved_MOUNT_OPTS=$MOUNT_OPTS
23556
23557 cleanup_802a() {
23558         trap 0
23559
23560         stopall
23561         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
23562         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
23563         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
23564         MOUNT_OPTS=$saved_MOUNT_OPTS
23565         setupall
23566 }
23567
23568 test_802a() {
23569         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
23570         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23571         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23572                 skip "Need server version at least 2.9.55"
23573
23574         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
23575
23576         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23577
23578         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23579                 error "(2) Fail to copy"
23580
23581         trap cleanup_802a EXIT
23582
23583         # sync by force before remount as readonly
23584         sync; sync_all_data; sleep 3; sync_all_data
23585
23586         stopall
23587
23588         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
23589         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
23590         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
23591
23592         echo "Mount the server as read only"
23593         setupall server_only || error "(3) Fail to start servers"
23594
23595         echo "Mount client without ro should fail"
23596         mount_client $MOUNT &&
23597                 error "(4) Mount client without 'ro' should fail"
23598
23599         echo "Mount client with ro should succeed"
23600         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
23601         mount_client $MOUNT ||
23602                 error "(5) Mount client with 'ro' should succeed"
23603
23604         echo "Modify should be refused"
23605         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23606
23607         echo "Read should be allowed"
23608         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23609                 error "(7) Read should succeed under ro mode"
23610
23611         cleanup_802a
23612 }
23613 run_test 802a "simulate readonly device"
23614
23615 test_802b() {
23616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23617         remote_mds_nodsh && skip "remote MDS with nodsh"
23618
23619         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
23620                 skip "readonly option not available"
23621
23622         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
23623
23624         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23625                 error "(2) Fail to copy"
23626
23627         # write back all cached data before setting MDT to readonly
23628         cancel_lru_locks
23629         sync_all_data
23630
23631         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
23632         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
23633
23634         echo "Modify should be refused"
23635         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23636
23637         echo "Read should be allowed"
23638         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23639                 error "(7) Read should succeed under ro mode"
23640
23641         # disable readonly
23642         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
23643 }
23644 run_test 802b "be able to set MDTs to readonly"
23645
23646 test_803() {
23647         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23648         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23649                 skip "MDS needs to be newer than 2.10.54"
23650
23651         mkdir -p $DIR/$tdir
23652         # Create some objects on all MDTs to trigger related logs objects
23653         for idx in $(seq $MDSCOUNT); do
23654                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
23655                         $DIR/$tdir/dir${idx} ||
23656                         error "Fail to create $DIR/$tdir/dir${idx}"
23657         done
23658
23659         sync; sleep 3
23660         wait_delete_completed # ensure old test cleanups are finished
23661         echo "before create:"
23662         $LFS df -i $MOUNT
23663         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23664
23665         for i in {1..10}; do
23666                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
23667                         error "Fail to create $DIR/$tdir/foo$i"
23668         done
23669
23670         sync; sleep 3
23671         echo "after create:"
23672         $LFS df -i $MOUNT
23673         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23674
23675         # allow for an llog to be cleaned up during the test
23676         [ $after_used -ge $((before_used + 10 - 1)) ] ||
23677                 error "before ($before_used) + 10 > after ($after_used)"
23678
23679         for i in {1..10}; do
23680                 rm -rf $DIR/$tdir/foo$i ||
23681                         error "Fail to remove $DIR/$tdir/foo$i"
23682         done
23683
23684         sleep 3 # avoid MDT return cached statfs
23685         wait_delete_completed
23686         echo "after unlink:"
23687         $LFS df -i $MOUNT
23688         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23689
23690         # allow for an llog to be created during the test
23691         [ $after_used -le $((before_used + 1)) ] ||
23692                 error "after ($after_used) > before ($before_used) + 1"
23693 }
23694 run_test 803 "verify agent object for remote object"
23695
23696 test_804() {
23697         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23698         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23699                 skip "MDS needs to be newer than 2.10.54"
23700         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
23701
23702         mkdir -p $DIR/$tdir
23703         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
23704                 error "Fail to create $DIR/$tdir/dir0"
23705
23706         local fid=$($LFS path2fid $DIR/$tdir/dir0)
23707         local dev=$(mdsdevname 2)
23708
23709         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23710                 grep ${fid} || error "NOT found agent entry for dir0"
23711
23712         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
23713                 error "Fail to create $DIR/$tdir/dir1"
23714
23715         touch $DIR/$tdir/dir1/foo0 ||
23716                 error "Fail to create $DIR/$tdir/dir1/foo0"
23717         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
23718         local rc=0
23719
23720         for idx in $(seq $MDSCOUNT); do
23721                 dev=$(mdsdevname $idx)
23722                 do_facet mds${idx} \
23723                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23724                         grep ${fid} && rc=$idx
23725         done
23726
23727         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
23728                 error "Fail to rename foo0 to foo1"
23729         if [ $rc -eq 0 ]; then
23730                 for idx in $(seq $MDSCOUNT); do
23731                         dev=$(mdsdevname $idx)
23732                         do_facet mds${idx} \
23733                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23734                         grep ${fid} && rc=$idx
23735                 done
23736         fi
23737
23738         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
23739                 error "Fail to rename foo1 to foo2"
23740         if [ $rc -eq 0 ]; then
23741                 for idx in $(seq $MDSCOUNT); do
23742                         dev=$(mdsdevname $idx)
23743                         do_facet mds${idx} \
23744                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23745                         grep ${fid} && rc=$idx
23746                 done
23747         fi
23748
23749         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
23750
23751         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
23752                 error "Fail to link to $DIR/$tdir/dir1/foo2"
23753         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
23754                 error "Fail to rename foo2 to foo0"
23755         unlink $DIR/$tdir/dir1/foo0 ||
23756                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
23757         rm -rf $DIR/$tdir/dir0 ||
23758                 error "Fail to rm $DIR/$tdir/dir0"
23759
23760         for idx in $(seq $MDSCOUNT); do
23761                 dev=$(mdsdevname $idx)
23762                 rc=0
23763
23764                 stop mds${idx}
23765                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
23766                         rc=$?
23767                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
23768                         error "mount mds$idx failed"
23769                 df $MOUNT > /dev/null 2>&1
23770
23771                 # e2fsck should not return error
23772                 [ $rc -eq 0 ] ||
23773                         error "e2fsck detected error on MDT${idx}: rc=$rc"
23774         done
23775 }
23776 run_test 804 "verify agent entry for remote entry"
23777
23778 cleanup_805() {
23779         do_facet $SINGLEMDS zfs set quota=$old $fsset
23780         unlinkmany $DIR/$tdir/f- 1000000
23781         trap 0
23782 }
23783
23784 test_805() {
23785         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
23786         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
23787         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
23788                 skip "netfree not implemented before 0.7"
23789         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
23790                 skip "Need MDS version at least 2.10.57"
23791
23792         local fsset
23793         local freekb
23794         local usedkb
23795         local old
23796         local quota
23797         local pref="osd-zfs.$FSNAME-MDT0000."
23798
23799         # limit available space on MDS dataset to meet nospace issue
23800         # quickly. then ZFS 0.7.2 can use reserved space if asked
23801         # properly (using netfree flag in osd_declare_destroy()
23802         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
23803         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
23804                 gawk '{print $3}')
23805         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
23806         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
23807         let "usedkb=usedkb-freekb"
23808         let "freekb=freekb/2"
23809         if let "freekb > 5000"; then
23810                 let "freekb=5000"
23811         fi
23812         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
23813         trap cleanup_805 EXIT
23814         mkdir $DIR/$tdir
23815         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
23816                 error "Can't set PFL layout"
23817         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
23818         rm -rf $DIR/$tdir || error "not able to remove"
23819         do_facet $SINGLEMDS zfs set quota=$old $fsset
23820         trap 0
23821 }
23822 run_test 805 "ZFS can remove from full fs"
23823
23824 # Size-on-MDS test
23825 check_lsom_data()
23826 {
23827         local file=$1
23828         local size=$($LFS getsom -s $file)
23829         local expect=$(stat -c %s $file)
23830
23831         [[ $size == $expect ]] ||
23832                 error "$file expected size: $expect, got: $size"
23833
23834         local blocks=$($LFS getsom -b $file)
23835         expect=$(stat -c %b $file)
23836         [[ $blocks == $expect ]] ||
23837                 error "$file expected blocks: $expect, got: $blocks"
23838 }
23839
23840 check_lsom_size()
23841 {
23842         local size=$($LFS getsom -s $1)
23843         local expect=$2
23844
23845         [[ $size == $expect ]] ||
23846                 error "$file expected size: $expect, got: $size"
23847 }
23848
23849 test_806() {
23850         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23851                 skip "Need MDS version at least 2.11.52"
23852
23853         local bs=1048576
23854
23855         touch $DIR/$tfile || error "touch $tfile failed"
23856
23857         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23858         save_lustre_params client "llite.*.xattr_cache" > $save
23859         lctl set_param llite.*.xattr_cache=0
23860         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23861
23862         # single-threaded write
23863         echo "Test SOM for single-threaded write"
23864         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
23865                 error "write $tfile failed"
23866         check_lsom_size $DIR/$tfile $bs
23867
23868         local num=32
23869         local size=$(($num * $bs))
23870         local offset=0
23871         local i
23872
23873         echo "Test SOM for single client multi-threaded($num) write"
23874         $TRUNCATE $DIR/$tfile 0
23875         for ((i = 0; i < $num; i++)); do
23876                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23877                 local pids[$i]=$!
23878                 offset=$((offset + $bs))
23879         done
23880         for (( i=0; i < $num; i++ )); do
23881                 wait ${pids[$i]}
23882         done
23883         check_lsom_size $DIR/$tfile $size
23884
23885         $TRUNCATE $DIR/$tfile 0
23886         for ((i = 0; i < $num; i++)); do
23887                 offset=$((offset - $bs))
23888                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23889                 local pids[$i]=$!
23890         done
23891         for (( i=0; i < $num; i++ )); do
23892                 wait ${pids[$i]}
23893         done
23894         check_lsom_size $DIR/$tfile $size
23895
23896         # multi-client writes
23897         num=$(get_node_count ${CLIENTS//,/ })
23898         size=$(($num * $bs))
23899         offset=0
23900         i=0
23901
23902         echo "Test SOM for multi-client ($num) writes"
23903         $TRUNCATE $DIR/$tfile 0
23904         for client in ${CLIENTS//,/ }; do
23905                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23906                 local pids[$i]=$!
23907                 i=$((i + 1))
23908                 offset=$((offset + $bs))
23909         done
23910         for (( i=0; i < $num; i++ )); do
23911                 wait ${pids[$i]}
23912         done
23913         check_lsom_size $DIR/$tfile $offset
23914
23915         i=0
23916         $TRUNCATE $DIR/$tfile 0
23917         for client in ${CLIENTS//,/ }; do
23918                 offset=$((offset - $bs))
23919                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23920                 local pids[$i]=$!
23921                 i=$((i + 1))
23922         done
23923         for (( i=0; i < $num; i++ )); do
23924                 wait ${pids[$i]}
23925         done
23926         check_lsom_size $DIR/$tfile $size
23927
23928         # verify truncate
23929         echo "Test SOM for truncate"
23930         $TRUNCATE $DIR/$tfile 1048576
23931         check_lsom_size $DIR/$tfile 1048576
23932         $TRUNCATE $DIR/$tfile 1234
23933         check_lsom_size $DIR/$tfile 1234
23934
23935         # verify SOM blocks count
23936         echo "Verify SOM block count"
23937         $TRUNCATE $DIR/$tfile 0
23938         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
23939                 error "failed to write file $tfile"
23940         check_lsom_data $DIR/$tfile
23941 }
23942 run_test 806 "Verify Lazy Size on MDS"
23943
23944 test_807() {
23945         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23946         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23947                 skip "Need MDS version at least 2.11.52"
23948
23949         # Registration step
23950         changelog_register || error "changelog_register failed"
23951         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
23952         changelog_users $SINGLEMDS | grep -q $cl_user ||
23953                 error "User $cl_user not found in changelog_users"
23954
23955         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23956         save_lustre_params client "llite.*.xattr_cache" > $save
23957         lctl set_param llite.*.xattr_cache=0
23958         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23959
23960         rm -rf $DIR/$tdir || error "rm $tdir failed"
23961         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23962         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
23963         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
23964         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
23965                 error "truncate $tdir/trunc failed"
23966
23967         local bs=1048576
23968         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
23969                 error "write $tfile failed"
23970
23971         # multi-client wirtes
23972         local num=$(get_node_count ${CLIENTS//,/ })
23973         local offset=0
23974         local i=0
23975
23976         echo "Test SOM for multi-client ($num) writes"
23977         touch $DIR/$tfile || error "touch $tfile failed"
23978         $TRUNCATE $DIR/$tfile 0
23979         for client in ${CLIENTS//,/ }; do
23980                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23981                 local pids[$i]=$!
23982                 i=$((i + 1))
23983                 offset=$((offset + $bs))
23984         done
23985         for (( i=0; i < $num; i++ )); do
23986                 wait ${pids[$i]}
23987         done
23988
23989         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
23990         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
23991         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
23992         check_lsom_data $DIR/$tdir/trunc
23993         check_lsom_data $DIR/$tdir/single_dd
23994         check_lsom_data $DIR/$tfile
23995
23996         rm -rf $DIR/$tdir
23997         # Deregistration step
23998         changelog_deregister || error "changelog_deregister failed"
23999 }
24000 run_test 807 "verify LSOM syncing tool"
24001
24002 check_som_nologged()
24003 {
24004         local lines=$($LFS changelog $FSNAME-MDT0000 |
24005                 grep 'x=trusted.som' | wc -l)
24006         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24007 }
24008
24009 test_808() {
24010         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24011                 skip "Need MDS version at least 2.11.55"
24012
24013         # Registration step
24014         changelog_register || error "changelog_register failed"
24015
24016         touch $DIR/$tfile || error "touch $tfile failed"
24017         check_som_nologged
24018
24019         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24020                 error "write $tfile failed"
24021         check_som_nologged
24022
24023         $TRUNCATE $DIR/$tfile 1234
24024         check_som_nologged
24025
24026         $TRUNCATE $DIR/$tfile 1048576
24027         check_som_nologged
24028
24029         # Deregistration step
24030         changelog_deregister || error "changelog_deregister failed"
24031 }
24032 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24033
24034 check_som_nodata()
24035 {
24036         $LFS getsom $1
24037         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24038 }
24039
24040 test_809() {
24041         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24042                 skip "Need MDS version at least 2.11.56"
24043
24044         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24045                 error "failed to create DoM-only file $DIR/$tfile"
24046         touch $DIR/$tfile || error "touch $tfile failed"
24047         check_som_nodata $DIR/$tfile
24048
24049         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24050                 error "write $tfile failed"
24051         check_som_nodata $DIR/$tfile
24052
24053         $TRUNCATE $DIR/$tfile 1234
24054         check_som_nodata $DIR/$tfile
24055
24056         $TRUNCATE $DIR/$tfile 4097
24057         check_som_nodata $DIR/$file
24058 }
24059 run_test 809 "Verify no SOM xattr store for DoM-only files"
24060
24061 test_810() {
24062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24063         $GSS && skip_env "could not run with gss"
24064         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24065                 skip "OST < 2.12.58 doesn't align checksum"
24066
24067         set_checksums 1
24068         stack_trap "set_checksums $ORIG_CSUM" EXIT
24069         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24070
24071         local csum
24072         local before
24073         local after
24074         for csum in $CKSUM_TYPES; do
24075                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24076                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24077                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24078                         eval set -- $i
24079                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24080                         before=$(md5sum $DIR/$tfile)
24081                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24082                         after=$(md5sum $DIR/$tfile)
24083                         [ "$before" == "$after" ] ||
24084                                 error "$csum: $before != $after bs=$1 seek=$2"
24085                 done
24086         done
24087 }
24088 run_test 810 "partial page writes on ZFS (LU-11663)"
24089
24090 test_812a() {
24091         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24092                 skip "OST < 2.12.51 doesn't support this fail_loc"
24093         [ "$SHARED_KEY" = true ] &&
24094                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24095
24096         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24097         # ensure ost1 is connected
24098         stat $DIR/$tfile >/dev/null || error "can't stat"
24099         wait_osc_import_state client ost1 FULL
24100         # no locks, no reqs to let the connection idle
24101         cancel_lru_locks osc
24102
24103         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24104 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24105         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24106         wait_osc_import_state client ost1 CONNECTING
24107         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24108
24109         stat $DIR/$tfile >/dev/null || error "can't stat file"
24110 }
24111 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24112
24113 test_812b() { # LU-12378
24114         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24115                 skip "OST < 2.12.51 doesn't support this fail_loc"
24116         [ "$SHARED_KEY" = true ] &&
24117                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24118
24119         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24120         # ensure ost1 is connected
24121         stat $DIR/$tfile >/dev/null || error "can't stat"
24122         wait_osc_import_state client ost1 FULL
24123         # no locks, no reqs to let the connection idle
24124         cancel_lru_locks osc
24125
24126         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24127 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24128         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24129         wait_osc_import_state client ost1 CONNECTING
24130         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24131
24132         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24133         wait_osc_import_state client ost1 IDLE
24134 }
24135 run_test 812b "do not drop no resend request for idle connect"
24136
24137 test_813() {
24138         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24139         [ -z "$file_heat_sav" ] && skip "no file heat support"
24140
24141         local readsample
24142         local writesample
24143         local readbyte
24144         local writebyte
24145         local readsample1
24146         local writesample1
24147         local readbyte1
24148         local writebyte1
24149
24150         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24151         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24152
24153         $LCTL set_param -n llite.*.file_heat=1
24154         echo "Turn on file heat"
24155         echo "Period second: $period_second, Decay percentage: $decay_pct"
24156
24157         echo "QQQQ" > $DIR/$tfile
24158         echo "QQQQ" > $DIR/$tfile
24159         echo "QQQQ" > $DIR/$tfile
24160         cat $DIR/$tfile > /dev/null
24161         cat $DIR/$tfile > /dev/null
24162         cat $DIR/$tfile > /dev/null
24163         cat $DIR/$tfile > /dev/null
24164
24165         local out=$($LFS heat_get $DIR/$tfile)
24166
24167         $LFS heat_get $DIR/$tfile
24168         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24169         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24170         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24171         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24172
24173         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24174         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24175         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24176         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24177
24178         sleep $((period_second + 3))
24179         echo "Sleep $((period_second + 3)) seconds..."
24180         # The recursion formula to calculate the heat of the file f is as
24181         # follow:
24182         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24183         # Where Hi is the heat value in the period between time points i*I and
24184         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24185         # to the weight of Ci.
24186         out=$($LFS heat_get $DIR/$tfile)
24187         $LFS heat_get $DIR/$tfile
24188         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24189         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24190         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24191         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24192
24193         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24194                 error "read sample ($readsample) is wrong"
24195         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24196                 error "write sample ($writesample) is wrong"
24197         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24198                 error "read bytes ($readbyte) is wrong"
24199         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24200                 error "write bytes ($writebyte) is wrong"
24201
24202         echo "QQQQ" > $DIR/$tfile
24203         echo "QQQQ" > $DIR/$tfile
24204         echo "QQQQ" > $DIR/$tfile
24205         cat $DIR/$tfile > /dev/null
24206         cat $DIR/$tfile > /dev/null
24207         cat $DIR/$tfile > /dev/null
24208         cat $DIR/$tfile > /dev/null
24209
24210         sleep $((period_second + 3))
24211         echo "Sleep $((period_second + 3)) seconds..."
24212
24213         out=$($LFS heat_get $DIR/$tfile)
24214         $LFS heat_get $DIR/$tfile
24215         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24216         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24217         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24218         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24219
24220         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24221                 4 * $decay_pct) / 100") -eq 1 ] ||
24222                 error "read sample ($readsample1) is wrong"
24223         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24224                 3 * $decay_pct) / 100") -eq 1 ] ||
24225                 error "write sample ($writesample1) is wrong"
24226         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24227                 20 * $decay_pct) / 100") -eq 1 ] ||
24228                 error "read bytes ($readbyte1) is wrong"
24229         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24230                 15 * $decay_pct) / 100") -eq 1 ] ||
24231                 error "write bytes ($writebyte1) is wrong"
24232
24233         echo "Turn off file heat for the file $DIR/$tfile"
24234         $LFS heat_set -o $DIR/$tfile
24235
24236         echo "QQQQ" > $DIR/$tfile
24237         echo "QQQQ" > $DIR/$tfile
24238         echo "QQQQ" > $DIR/$tfile
24239         cat $DIR/$tfile > /dev/null
24240         cat $DIR/$tfile > /dev/null
24241         cat $DIR/$tfile > /dev/null
24242         cat $DIR/$tfile > /dev/null
24243
24244         out=$($LFS heat_get $DIR/$tfile)
24245         $LFS heat_get $DIR/$tfile
24246         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24247         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24248         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24249         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24250
24251         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24252         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24253         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24254         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24255
24256         echo "Trun on file heat for the file $DIR/$tfile"
24257         $LFS heat_set -O $DIR/$tfile
24258
24259         echo "QQQQ" > $DIR/$tfile
24260         echo "QQQQ" > $DIR/$tfile
24261         echo "QQQQ" > $DIR/$tfile
24262         cat $DIR/$tfile > /dev/null
24263         cat $DIR/$tfile > /dev/null
24264         cat $DIR/$tfile > /dev/null
24265         cat $DIR/$tfile > /dev/null
24266
24267         out=$($LFS heat_get $DIR/$tfile)
24268         $LFS heat_get $DIR/$tfile
24269         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24270         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24271         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24272         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24273
24274         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24275         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24276         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24277         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24278
24279         $LFS heat_set -c $DIR/$tfile
24280         $LCTL set_param -n llite.*.file_heat=0
24281         echo "Turn off file heat support for the Lustre filesystem"
24282
24283         echo "QQQQ" > $DIR/$tfile
24284         echo "QQQQ" > $DIR/$tfile
24285         echo "QQQQ" > $DIR/$tfile
24286         cat $DIR/$tfile > /dev/null
24287         cat $DIR/$tfile > /dev/null
24288         cat $DIR/$tfile > /dev/null
24289         cat $DIR/$tfile > /dev/null
24290
24291         out=$($LFS heat_get $DIR/$tfile)
24292         $LFS heat_get $DIR/$tfile
24293         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24294         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24295         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24296         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24297
24298         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24299         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24300         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24301         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24302
24303         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24304         rm -f $DIR/$tfile
24305 }
24306 run_test 813 "File heat verfication"
24307
24308 test_814()
24309 {
24310         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24311         echo -n y >> $DIR/$tfile
24312         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24313         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24314 }
24315 run_test 814 "sparse cp works as expected (LU-12361)"
24316
24317 test_815()
24318 {
24319         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24320         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24321 }
24322 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24323
24324 test_816() {
24325         [ "$SHARED_KEY" = true ] &&
24326                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24327
24328         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24329         # ensure ost1 is connected
24330         stat $DIR/$tfile >/dev/null || error "can't stat"
24331         wait_osc_import_state client ost1 FULL
24332         # no locks, no reqs to let the connection idle
24333         cancel_lru_locks osc
24334         lru_resize_disable osc
24335         local before
24336         local now
24337         before=$($LCTL get_param -n \
24338                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24339
24340         wait_osc_import_state client ost1 IDLE
24341         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24342         now=$($LCTL get_param -n \
24343               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24344         [ $before == $now ] || error "lru_size changed $before != $now"
24345 }
24346 run_test 816 "do not reset lru_resize on idle reconnect"
24347
24348 cleanup_817() {
24349         umount $tmpdir
24350         exportfs -u localhost:$DIR/nfsexp
24351         rm -rf $DIR/nfsexp
24352 }
24353
24354 test_817() {
24355         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24356
24357         mkdir -p $DIR/nfsexp
24358         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24359                 error "failed to export nfs"
24360
24361         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24362         stack_trap cleanup_817 EXIT
24363
24364         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24365                 error "failed to mount nfs to $tmpdir"
24366
24367         cp /bin/true $tmpdir
24368         $DIR/nfsexp/true || error "failed to execute 'true' command"
24369 }
24370 run_test 817 "nfsd won't cache write lock for exec file"
24371
24372 test_818() {
24373         mkdir $DIR/$tdir
24374         $LFS setstripe -c1 -i0 $DIR/$tfile
24375         $LFS setstripe -c1 -i1 $DIR/$tfile
24376         stop $SINGLEMDS
24377         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24378         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24379         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24380                 error "start $SINGLEMDS failed"
24381         rm -rf $DIR/$tdir
24382 }
24383 run_test 818 "unlink with failed llog"
24384
24385 test_819a() {
24386         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24387         cancel_lru_locks osc
24388         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24389         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24390         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24391         rm -f $TDIR/$tfile
24392 }
24393 run_test 819a "too big niobuf in read"
24394
24395 test_819b() {
24396         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24397         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24398         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24399         cancel_lru_locks osc
24400         sleep 1
24401         rm -f $TDIR/$tfile
24402 }
24403 run_test 819b "too big niobuf in write"
24404
24405
24406 function test_820_start_ost() {
24407         sleep 5
24408
24409         for num in $(seq $OSTCOUNT); do
24410                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24411         done
24412 }
24413
24414 test_820() {
24415         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24416
24417         mkdir $DIR/$tdir
24418         umount_client $MOUNT || error "umount failed"
24419         for num in $(seq $OSTCOUNT); do
24420                 stop ost$num
24421         done
24422
24423         # mount client with no active OSTs
24424         # so that the client can't initialize max LOV EA size
24425         # from OSC notifications
24426         mount_client $MOUNT || error "mount failed"
24427         # delay OST starting to keep this 0 max EA size for a while
24428         test_820_start_ost &
24429
24430         # create a directory on MDS2
24431         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24432                 error "Failed to create directory"
24433         # open intent should update default EA size
24434         # see mdc_update_max_ea_from_body()
24435         # notice this is the very first RPC to MDS2
24436         cp /etc/services $DIR/$tdir/mds2 ||
24437                 error "Failed to copy files to mds$n"
24438 }
24439 run_test 820 "update max EA from open intent"
24440
24441 #
24442 # tests that do cleanup/setup should be run at the end
24443 #
24444
24445 test_900() {
24446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24447         local ls
24448
24449         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
24450         $LCTL set_param fail_loc=0x903
24451
24452         cancel_lru_locks MGC
24453
24454         FAIL_ON_ERROR=true cleanup
24455         FAIL_ON_ERROR=true setup
24456 }
24457 run_test 900 "umount should not race with any mgc requeue thread"
24458
24459 # LUS-6253/LU-11185
24460 test_901() {
24461         local oldc
24462         local newc
24463         local olds
24464         local news
24465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24466
24467         # some get_param have a bug to handle dot in param name
24468         cancel_lru_locks MGC
24469         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24470         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24471         umount_client $MOUNT || error "umount failed"
24472         mount_client $MOUNT || error "mount failed"
24473         cancel_lru_locks MGC
24474         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24475         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24476
24477         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
24478         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
24479
24480         return 0
24481 }
24482 run_test 901 "don't leak a mgc lock on client umount"
24483
24484 # LU-13377
24485 test_902() {
24486         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
24487                 skip "client does not have LU-13377 fix"
24488         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
24489         $LCTL set_param fail_loc=0x1415
24490         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24491         cancel_lru_locks osc
24492         rm -f $DIR/$tfile
24493 }
24494 run_test 902 "test short write doesn't hang lustre"
24495
24496 complete $SECONDS
24497 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
24498 check_and_cleanup_lustre
24499 if [ "$I_MOUNTED" != "yes" ]; then
24500         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
24501 fi
24502 exit_status