Whamcloud - gitweb
LU-12295 mdd: don't LBUG() if dir nlink is wrong
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-9795 LU-9795 LU-9795 LU-9795
49         ALWAYS_EXCEPT+=" 17n     60a     133g    300f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64 fi
65
66 # skip nfs tests on kernels >= 4.12.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
68         # bug number:   LU-12661
69         ALWAYS_EXCEPT+=" 817"
70 fi
71 # skip cgroup tests on RHEL8.1 kernels until they are fixed
72 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
73       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
74         # bug number:   LU-13063
75         ALWAYS_EXCEPT+=" 411"
76 fi
77
78 #                                  5          12     8   12  (min)"
79 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
80
81 if [ "$mds1_FSTYPE" = "zfs" ]; then
82         # bug number for skipped test:
83         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
84         #                                               13    (min)"
85         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
86 fi
87
88 # Get the SLES distro version
89 #
90 # Returns a version string that should only be used in comparing
91 # strings returned by version_code()
92 sles_version_code()
93 {
94         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
95
96         # All SuSE Linux versions have one decimal. version_code expects two
97         local sles_version=$version.0
98         version_code $sles_version
99 }
100
101 # Check if we are running on Ubuntu or SLES so we can make decisions on
102 # what tests to run
103 if [ -r /etc/SuSE-release ]; then
104         sles_version=$(sles_version_code)
105         [ $sles_version -lt $(version_code 11.4.0) ] &&
106                 # bug number for skipped test: LU-4341
107                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
108         [ $sles_version -lt $(version_code 12.0.0) ] &&
109                 # bug number for skipped test: LU-3703
110                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
111 elif [ -r /etc/os-release ]; then
112         if grep -qi ubuntu /etc/os-release; then
113                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
114                                                 -e 's/^VERSION=//p' \
115                                                 /etc/os-release |
116                                                 awk '{ print $1 }'))
117
118                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
119                         # bug number for skipped test:
120                         #                LU-10334 LU-10366
121                         ALWAYS_EXCEPT+=" 103a     410"
122                 fi
123         fi
124 fi
125
126 build_test_filter
127 FAIL_ON_ERROR=false
128
129 cleanup() {
130         echo -n "cln.."
131         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
132         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
133 }
134 setup() {
135         echo -n "mnt.."
136         load_modules
137         setupall || exit 10
138         echo "done"
139 }
140
141 check_swap_layouts_support()
142 {
143         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
144                 skip "Does not support layout lock."
145 }
146
147 check_swap_layout_no_dom()
148 {
149         local FOLDER=$1
150         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
151         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
152 }
153
154 check_and_setup_lustre
155 DIR=${DIR:-$MOUNT}
156 assert_DIR
157
158 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
159
160 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
161 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
162 rm -rf $DIR/[Rdfs][0-9]*
163
164 # $RUNAS_ID may get set incorrectly somewhere else
165 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
166         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
167
168 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
169
170 if [ "${ONLY}" = "MOUNT" ] ; then
171         echo "Lustre is up, please go on"
172         exit
173 fi
174
175 echo "preparing for tests involving mounts"
176 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
177 touch $EXT2_DEV
178 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
179 echo # add a newline after mke2fs.
180
181 umask 077
182
183 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
184 lctl set_param debug=-1 2> /dev/null || true
185 test_0a() {
186         touch $DIR/$tfile
187         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
188         rm $DIR/$tfile
189         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
190 }
191 run_test 0a "touch; rm ====================="
192
193 test_0b() {
194         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
195         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
196 }
197 run_test 0b "chmod 0755 $DIR ============================="
198
199 test_0c() {
200         $LCTL get_param mdc.*.import | grep "state: FULL" ||
201                 error "import not FULL"
202         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
203                 error "bad target"
204 }
205 run_test 0c "check import proc"
206
207 test_0d() { # LU-3397
208         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
209                 skip "proc exports not supported before 2.10.57"
210
211         local mgs_exp="mgs.MGS.exports"
212         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
213         local exp_client_nid
214         local exp_client_version
215         local exp_val
216         local imp_val
217         local temp_imp=$DIR/$tfile.import
218         local temp_exp=$DIR/$tfile.export
219
220         # save mgc import file to $temp_imp
221         $LCTL get_param mgc.*.import | tee $temp_imp
222         # Check if client uuid is found in MGS export
223         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
224                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
225                         $client_uuid ] &&
226                         break;
227         done
228         # save mgs export file to $temp_exp
229         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
230
231         # Compare the value of field "connect_flags"
232         imp_val=$(grep "connect_flags" $temp_imp)
233         exp_val=$(grep "connect_flags" $temp_exp)
234         [ "$exp_val" == "$imp_val" ] ||
235                 error "export flags '$exp_val' != import flags '$imp_val'"
236
237         # Compare the value of client version
238         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
239         exp_val=$(version_code $exp_client_version)
240         imp_val=$CLIENT_VERSION
241         [ "$exp_val" == "$imp_val" ] ||
242                 error "export client version '$exp_val' != '$imp_val'"
243 }
244 run_test 0d "check export proc ============================="
245
246 test_1() {
247         test_mkdir $DIR/$tdir
248         test_mkdir $DIR/$tdir/d2
249         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
250         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
251         rmdir $DIR/$tdir/d2
252         rmdir $DIR/$tdir
253         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
254 }
255 run_test 1 "mkdir; remkdir; rmdir"
256
257 test_2() {
258         test_mkdir $DIR/$tdir
259         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
260         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
261         rm -r $DIR/$tdir
262         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
263 }
264 run_test 2 "mkdir; touch; rmdir; check file"
265
266 test_3() {
267         test_mkdir $DIR/$tdir
268         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
269         touch $DIR/$tdir/$tfile
270         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
271         rm -r $DIR/$tdir
272         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
273 }
274 run_test 3 "mkdir; touch; rmdir; check dir"
275
276 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
277 test_4() {
278         test_mkdir -i 1 $DIR/$tdir
279
280         touch $DIR/$tdir/$tfile ||
281                 error "Create file under remote directory failed"
282
283         rmdir $DIR/$tdir &&
284                 error "Expect error removing in-use dir $DIR/$tdir"
285
286         test -d $DIR/$tdir || error "Remote directory disappeared"
287
288         rm -rf $DIR/$tdir || error "remove remote dir error"
289 }
290 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
291
292 test_5() {
293         test_mkdir $DIR/$tdir
294         test_mkdir $DIR/$tdir/d2
295         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
296         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
297         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
298 }
299 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
300
301 test_6a() {
302         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
303         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
304         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
305                 error "$tfile does not have perm 0666 or UID $UID"
306         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
307         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
308                 error "$tfile should be 0666 and owned by UID $UID"
309 }
310 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
311
312 test_6c() {
313         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
314
315         touch $DIR/$tfile
316         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
317         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
318                 error "$tfile should be owned by UID $RUNAS_ID"
319         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
320         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
321                 error "$tfile should be owned by UID $RUNAS_ID"
322 }
323 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
324
325 test_6e() {
326         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
327
328         touch $DIR/$tfile
329         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
330         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
331                 error "$tfile should be owned by GID $UID"
332         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
333         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
334                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
335 }
336 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
337
338 test_6g() {
339         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
340
341         test_mkdir $DIR/$tdir
342         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
343         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
344         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
345         test_mkdir $DIR/$tdir/d/subdir
346         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
347                 error "$tdir/d/subdir should be GID $RUNAS_GID"
348         if [[ $MDSCOUNT -gt 1 ]]; then
349                 # check remote dir sgid inherite
350                 $LFS mkdir -i 0 $DIR/$tdir.local ||
351                         error "mkdir $tdir.local failed"
352                 chmod g+s $DIR/$tdir.local ||
353                         error "chmod $tdir.local failed"
354                 chgrp $RUNAS_GID $DIR/$tdir.local ||
355                         error "chgrp $tdir.local failed"
356                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
357                         error "mkdir $tdir.remote failed"
358                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
359                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
360                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
361                         error "$tdir.remote should be mode 02755"
362         fi
363 }
364 run_test 6g "verify new dir in sgid dir inherits group"
365
366 test_6h() { # bug 7331
367         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
368
369         touch $DIR/$tfile || error "touch failed"
370         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
371         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
372                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
373         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
374                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
375 }
376 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
377
378 test_7a() {
379         test_mkdir $DIR/$tdir
380         $MCREATE $DIR/$tdir/$tfile
381         chmod 0666 $DIR/$tdir/$tfile
382         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
383                 error "$tdir/$tfile should be mode 0666"
384 }
385 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
386
387 test_7b() {
388         if [ ! -d $DIR/$tdir ]; then
389                 test_mkdir $DIR/$tdir
390         fi
391         $MCREATE $DIR/$tdir/$tfile
392         echo -n foo > $DIR/$tdir/$tfile
393         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
394         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
395 }
396 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
397
398 test_8() {
399         test_mkdir $DIR/$tdir
400         touch $DIR/$tdir/$tfile
401         chmod 0666 $DIR/$tdir/$tfile
402         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
403                 error "$tfile mode not 0666"
404 }
405 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
406
407 test_9() {
408         test_mkdir $DIR/$tdir
409         test_mkdir $DIR/$tdir/d2
410         test_mkdir $DIR/$tdir/d2/d3
411         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
412 }
413 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
414
415 test_10() {
416         test_mkdir $DIR/$tdir
417         test_mkdir $DIR/$tdir/d2
418         touch $DIR/$tdir/d2/$tfile
419         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
420                 error "$tdir/d2/$tfile not a file"
421 }
422 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
423
424 test_11() {
425         test_mkdir $DIR/$tdir
426         test_mkdir $DIR/$tdir/d2
427         chmod 0666 $DIR/$tdir/d2
428         chmod 0705 $DIR/$tdir/d2
429         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
430                 error "$tdir/d2 mode not 0705"
431 }
432 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
433
434 test_12() {
435         test_mkdir $DIR/$tdir
436         touch $DIR/$tdir/$tfile
437         chmod 0666 $DIR/$tdir/$tfile
438         chmod 0654 $DIR/$tdir/$tfile
439         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
440                 error "$tdir/d2 mode not 0654"
441 }
442 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
443
444 test_13() {
445         test_mkdir $DIR/$tdir
446         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
447         >  $DIR/$tdir/$tfile
448         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
449                 error "$tdir/$tfile size not 0 after truncate"
450 }
451 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
452
453 test_14() {
454         test_mkdir $DIR/$tdir
455         touch $DIR/$tdir/$tfile
456         rm $DIR/$tdir/$tfile
457         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
458 }
459 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
460
461 test_15() {
462         test_mkdir $DIR/$tdir
463         touch $DIR/$tdir/$tfile
464         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
465         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
466                 error "$tdir/${tfile_2} not a file after rename"
467         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
468 }
469 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
470
471 test_16() {
472         test_mkdir $DIR/$tdir
473         touch $DIR/$tdir/$tfile
474         rm -rf $DIR/$tdir/$tfile
475         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
476 }
477 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
478
479 test_17a() {
480         test_mkdir $DIR/$tdir
481         touch $DIR/$tdir/$tfile
482         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
483         ls -l $DIR/$tdir
484         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
485                 error "$tdir/l-exist not a symlink"
486         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
487                 error "$tdir/l-exist not referencing a file"
488         rm -f $DIR/$tdir/l-exist
489         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
490 }
491 run_test 17a "symlinks: create, remove (real)"
492
493 test_17b() {
494         test_mkdir $DIR/$tdir
495         ln -s no-such-file $DIR/$tdir/l-dangle
496         ls -l $DIR/$tdir
497         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
498                 error "$tdir/l-dangle not referencing no-such-file"
499         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
500                 error "$tdir/l-dangle not referencing non-existent file"
501         rm -f $DIR/$tdir/l-dangle
502         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
503 }
504 run_test 17b "symlinks: create, remove (dangling)"
505
506 test_17c() { # bug 3440 - don't save failed open RPC for replay
507         test_mkdir $DIR/$tdir
508         ln -s foo $DIR/$tdir/$tfile
509         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
510 }
511 run_test 17c "symlinks: open dangling (should return error)"
512
513 test_17d() {
514         test_mkdir $DIR/$tdir
515         ln -s foo $DIR/$tdir/$tfile
516         touch $DIR/$tdir/$tfile || error "creating to new symlink"
517 }
518 run_test 17d "symlinks: create dangling"
519
520 test_17e() {
521         test_mkdir $DIR/$tdir
522         local foo=$DIR/$tdir/$tfile
523         ln -s $foo $foo || error "create symlink failed"
524         ls -l $foo || error "ls -l failed"
525         ls $foo && error "ls not failed" || true
526 }
527 run_test 17e "symlinks: create recursive symlink (should return error)"
528
529 test_17f() {
530         test_mkdir $DIR/$tdir
531         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
532         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
533         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
534         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
535         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
536         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
537         ls -l  $DIR/$tdir
538 }
539 run_test 17f "symlinks: long and very long symlink name"
540
541 # str_repeat(S, N) generate a string that is string S repeated N times
542 str_repeat() {
543         local s=$1
544         local n=$2
545         local ret=''
546         while [ $((n -= 1)) -ge 0 ]; do
547                 ret=$ret$s
548         done
549         echo $ret
550 }
551
552 # Long symlinks and LU-2241
553 test_17g() {
554         test_mkdir $DIR/$tdir
555         local TESTS="59 60 61 4094 4095"
556
557         # Fix for inode size boundary in 2.1.4
558         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
559                 TESTS="4094 4095"
560
561         # Patch not applied to 2.2 or 2.3 branches
562         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
563         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
564                 TESTS="4094 4095"
565
566         for i in $TESTS; do
567                 local SYMNAME=$(str_repeat 'x' $i)
568                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
569                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
570         done
571 }
572 run_test 17g "symlinks: really long symlink name and inode boundaries"
573
574 test_17h() { #bug 17378
575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
576         remote_mds_nodsh && skip "remote MDS with nodsh"
577
578         local mdt_idx
579
580         test_mkdir $DIR/$tdir
581         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
582         $LFS setstripe -c -1 $DIR/$tdir
583         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
584         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
585         touch $DIR/$tdir/$tfile || true
586 }
587 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
588
589 test_17i() { #bug 20018
590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
591         remote_mds_nodsh && skip "remote MDS with nodsh"
592
593         local foo=$DIR/$tdir/$tfile
594         local mdt_idx
595
596         test_mkdir -c1 $DIR/$tdir
597         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
598         ln -s $foo $foo || error "create symlink failed"
599 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
600         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
601         ls -l $foo && error "error not detected"
602         return 0
603 }
604 run_test 17i "don't panic on short symlink (should return error)"
605
606 test_17k() { #bug 22301
607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
608         [[ -z "$(which rsync 2>/dev/null)" ]] &&
609                 skip "no rsync command"
610         rsync --help | grep -q xattr ||
611                 skip_env "$(rsync --version | head -n1) does not support xattrs"
612         test_mkdir $DIR/$tdir
613         test_mkdir $DIR/$tdir.new
614         touch $DIR/$tdir/$tfile
615         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
616         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
617                 error "rsync failed with xattrs enabled"
618 }
619 run_test 17k "symlinks: rsync with xattrs enabled"
620
621 test_17l() { # LU-279
622         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
623                 skip "no getfattr command"
624
625         test_mkdir $DIR/$tdir
626         touch $DIR/$tdir/$tfile
627         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
628         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
629                 # -h to not follow symlinks. -m '' to list all the xattrs.
630                 # grep to remove first line: '# file: $path'.
631                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
632                 do
633                         lgetxattr_size_check $path $xattr ||
634                                 error "lgetxattr_size_check $path $xattr failed"
635                 done
636         done
637 }
638 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
639
640 # LU-1540
641 test_17m() {
642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
643         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
644         remote_mds_nodsh && skip "remote MDS with nodsh"
645         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
646         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
647                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
648
649         local short_sym="0123456789"
650         local wdir=$DIR/$tdir
651         local i
652
653         test_mkdir $wdir
654         long_sym=$short_sym
655         # create a long symlink file
656         for ((i = 0; i < 4; ++i)); do
657                 long_sym=${long_sym}${long_sym}
658         done
659
660         echo "create 512 short and long symlink files under $wdir"
661         for ((i = 0; i < 256; ++i)); do
662                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
663                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
664         done
665
666         echo "erase them"
667         rm -f $wdir/*
668         sync
669         wait_delete_completed
670
671         echo "recreate the 512 symlink files with a shorter string"
672         for ((i = 0; i < 512; ++i)); do
673                 # rewrite the symlink file with a shorter string
674                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
675                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
676         done
677
678         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
679         local devname=$(mdsdevname $mds_index)
680
681         echo "stop and checking mds${mds_index}:"
682         # e2fsck should not return error
683         stop mds${mds_index}
684         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
685         rc=$?
686
687         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
688                 error "start mds${mds_index} failed"
689         df $MOUNT > /dev/null 2>&1
690         [ $rc -eq 0 ] ||
691                 error "e2fsck detected error for short/long symlink: rc=$rc"
692         rm -f $wdir/*
693 }
694 run_test 17m "run e2fsck against MDT which contains short/long symlink"
695
696 check_fs_consistency_17n() {
697         local mdt_index
698         local rc=0
699
700         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
701         # so it only check MDT1/MDT2 instead of all of MDTs.
702         for mdt_index in 1 2; do
703                 local devname=$(mdsdevname $mdt_index)
704                 # e2fsck should not return error
705                 stop mds${mdt_index}
706                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
707                         rc=$((rc + $?))
708
709                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
710                         error "mount mds$mdt_index failed"
711                 df $MOUNT > /dev/null 2>&1
712         done
713         return $rc
714 }
715
716 test_17n() {
717         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
719         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
720         remote_mds_nodsh && skip "remote MDS with nodsh"
721         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
722         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
723                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
724
725         local i
726
727         test_mkdir $DIR/$tdir
728         for ((i=0; i<10; i++)); do
729                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
730                         error "create remote dir error $i"
731                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
732                         error "create files under remote dir failed $i"
733         done
734
735         check_fs_consistency_17n ||
736                 error "e2fsck report error after create files under remote dir"
737
738         for ((i = 0; i < 10; i++)); do
739                 rm -rf $DIR/$tdir/remote_dir_${i} ||
740                         error "destroy remote dir error $i"
741         done
742
743         check_fs_consistency_17n ||
744                 error "e2fsck report error after unlink files under remote dir"
745
746         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
747                 skip "lustre < 2.4.50 does not support migrate mv"
748
749         for ((i = 0; i < 10; i++)); do
750                 mkdir -p $DIR/$tdir/remote_dir_${i}
751                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
752                         error "create files under remote dir failed $i"
753                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
754                         error "migrate remote dir error $i"
755         done
756         check_fs_consistency_17n || error "e2fsck report error after migration"
757
758         for ((i = 0; i < 10; i++)); do
759                 rm -rf $DIR/$tdir/remote_dir_${i} ||
760                         error "destroy remote dir error $i"
761         done
762
763         check_fs_consistency_17n || error "e2fsck report error after unlink"
764 }
765 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
766
767 test_17o() {
768         remote_mds_nodsh && skip "remote MDS with nodsh"
769         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
770                 skip "Need MDS version at least 2.3.64"
771
772         local wdir=$DIR/${tdir}o
773         local mdt_index
774         local rc=0
775
776         test_mkdir $wdir
777         touch $wdir/$tfile
778         mdt_index=$($LFS getstripe -m $wdir/$tfile)
779         mdt_index=$((mdt_index + 1))
780
781         cancel_lru_locks mdc
782         #fail mds will wait the failover finish then set
783         #following fail_loc to avoid interfer the recovery process.
784         fail mds${mdt_index}
785
786         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
787         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
788         ls -l $wdir/$tfile && rc=1
789         do_facet mds${mdt_index} lctl set_param fail_loc=0
790         [[ $rc -eq 0 ]] || error "stat file should fail"
791 }
792 run_test 17o "stat file with incompat LMA feature"
793
794 test_18() {
795         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
796         ls $DIR || error "Failed to ls $DIR: $?"
797 }
798 run_test 18 "touch .../f ; ls ... =============================="
799
800 test_19a() {
801         touch $DIR/$tfile
802         ls -l $DIR
803         rm $DIR/$tfile
804         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
805 }
806 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
807
808 test_19b() {
809         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
810 }
811 run_test 19b "ls -l .../f19 (should return error) =============="
812
813 test_19c() {
814         [ $RUNAS_ID -eq $UID ] &&
815                 skip_env "RUNAS_ID = UID = $UID -- skipping"
816
817         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
818 }
819 run_test 19c "$RUNAS touch .../f19 (should return error) =="
820
821 test_19d() {
822         cat $DIR/f19 && error || true
823 }
824 run_test 19d "cat .../f19 (should return error) =============="
825
826 test_20() {
827         touch $DIR/$tfile
828         rm $DIR/$tfile
829         touch $DIR/$tfile
830         rm $DIR/$tfile
831         touch $DIR/$tfile
832         rm $DIR/$tfile
833         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
834 }
835 run_test 20 "touch .../f ; ls -l ..."
836
837 test_21() {
838         test_mkdir $DIR/$tdir
839         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
840         ln -s dangle $DIR/$tdir/link
841         echo foo >> $DIR/$tdir/link
842         cat $DIR/$tdir/dangle
843         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
844         $CHECKSTAT -f -t file $DIR/$tdir/link ||
845                 error "$tdir/link not linked to a file"
846 }
847 run_test 21 "write to dangling link"
848
849 test_22() {
850         local wdir=$DIR/$tdir
851         test_mkdir $wdir
852         chown $RUNAS_ID:$RUNAS_GID $wdir
853         (cd $wdir || error "cd $wdir failed";
854                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
855                 $RUNAS tar xf -)
856         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
857         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
858         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
859                 error "checkstat -u failed"
860 }
861 run_test 22 "unpack tar archive as non-root user"
862
863 # was test_23
864 test_23a() {
865         test_mkdir $DIR/$tdir
866         local file=$DIR/$tdir/$tfile
867
868         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
869         openfile -f O_CREAT:O_EXCL $file &&
870                 error "$file recreate succeeded" || true
871 }
872 run_test 23a "O_CREAT|O_EXCL in subdir"
873
874 test_23b() { # bug 18988
875         test_mkdir $DIR/$tdir
876         local file=$DIR/$tdir/$tfile
877
878         rm -f $file
879         echo foo > $file || error "write filed"
880         echo bar >> $file || error "append filed"
881         $CHECKSTAT -s 8 $file || error "wrong size"
882         rm $file
883 }
884 run_test 23b "O_APPEND check"
885
886 # LU-9409, size with O_APPEND and tiny writes
887 test_23c() {
888         local file=$DIR/$tfile
889
890         # single dd
891         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
892         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
893         rm -f $file
894
895         # racing tiny writes
896         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
897         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
898         wait
899         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
900         rm -f $file
901
902         #racing tiny & normal writes
903         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
905         wait
906         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
907         rm -f $file
908
909         #racing tiny & normal writes 2, ugly numbers
910         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
911         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
912         wait
913         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
914         rm -f $file
915 }
916 run_test 23c "O_APPEND size checks for tiny writes"
917
918 # LU-11069 file offset is correct after appending writes
919 test_23d() {
920         local file=$DIR/$tfile
921         local offset
922
923         echo CentaurHauls > $file
924         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
925         if ((offset != 26)); then
926                 error "wrong offset, expected 26, got '$offset'"
927         fi
928 }
929 run_test 23d "file offset is correct after appending writes"
930
931 # rename sanity
932 test_24a() {
933         echo '-- same directory rename'
934         test_mkdir $DIR/$tdir
935         touch $DIR/$tdir/$tfile.1
936         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
937         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
938 }
939 run_test 24a "rename file to non-existent target"
940
941 test_24b() {
942         test_mkdir $DIR/$tdir
943         touch $DIR/$tdir/$tfile.{1,2}
944         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
945         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
946         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
947 }
948 run_test 24b "rename file to existing target"
949
950 test_24c() {
951         test_mkdir $DIR/$tdir
952         test_mkdir $DIR/$tdir/d$testnum.1
953         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
954         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
955         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
956 }
957 run_test 24c "rename directory to non-existent target"
958
959 test_24d() {
960         test_mkdir -c1 $DIR/$tdir
961         test_mkdir -c1 $DIR/$tdir/d$testnum.1
962         test_mkdir -c1 $DIR/$tdir/d$testnum.2
963         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
964         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
965         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
966 }
967 run_test 24d "rename directory to existing target"
968
969 test_24e() {
970         echo '-- cross directory renames --'
971         test_mkdir $DIR/R5a
972         test_mkdir $DIR/R5b
973         touch $DIR/R5a/f
974         mv $DIR/R5a/f $DIR/R5b/g
975         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
976         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
977 }
978 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
979
980 test_24f() {
981         test_mkdir $DIR/R6a
982         test_mkdir $DIR/R6b
983         touch $DIR/R6a/f $DIR/R6b/g
984         mv $DIR/R6a/f $DIR/R6b/g
985         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
986         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
987 }
988 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
989
990 test_24g() {
991         test_mkdir $DIR/R7a
992         test_mkdir $DIR/R7b
993         test_mkdir $DIR/R7a/d
994         mv $DIR/R7a/d $DIR/R7b/e
995         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
996         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
997 }
998 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
999
1000 test_24h() {
1001         test_mkdir -c1 $DIR/R8a
1002         test_mkdir -c1 $DIR/R8b
1003         test_mkdir -c1 $DIR/R8a/d
1004         test_mkdir -c1 $DIR/R8b/e
1005         mrename $DIR/R8a/d $DIR/R8b/e
1006         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1007         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1008 }
1009 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1010
1011 test_24i() {
1012         echo "-- rename error cases"
1013         test_mkdir $DIR/R9
1014         test_mkdir $DIR/R9/a
1015         touch $DIR/R9/f
1016         mrename $DIR/R9/f $DIR/R9/a
1017         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1018         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1019         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1020 }
1021 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1022
1023 test_24j() {
1024         test_mkdir $DIR/R10
1025         mrename $DIR/R10/f $DIR/R10/g
1026         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1027         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1028         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1029 }
1030 run_test 24j "source does not exist ============================"
1031
1032 test_24k() {
1033         test_mkdir $DIR/R11a
1034         test_mkdir $DIR/R11a/d
1035         touch $DIR/R11a/f
1036         mv $DIR/R11a/f $DIR/R11a/d
1037         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1038         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1039 }
1040 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1041
1042 # bug 2429 - rename foo foo foo creates invalid file
1043 test_24l() {
1044         f="$DIR/f24l"
1045         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1046 }
1047 run_test 24l "Renaming a file to itself ========================"
1048
1049 test_24m() {
1050         f="$DIR/f24m"
1051         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1052         # on ext3 this does not remove either the source or target files
1053         # though the "expected" operation would be to remove the source
1054         $CHECKSTAT -t file ${f} || error "${f} missing"
1055         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1056 }
1057 run_test 24m "Renaming a file to a hard link to itself ========="
1058
1059 test_24n() {
1060     f="$DIR/f24n"
1061     # this stats the old file after it was renamed, so it should fail
1062     touch ${f}
1063     $CHECKSTAT ${f} || error "${f} missing"
1064     mv ${f} ${f}.rename
1065     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1066     $CHECKSTAT -a ${f} || error "${f} exists"
1067 }
1068 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1069
1070 test_24o() {
1071         test_mkdir $DIR/$tdir
1072         rename_many -s random -v -n 10 $DIR/$tdir
1073 }
1074 run_test 24o "rename of files during htree split"
1075
1076 test_24p() {
1077         test_mkdir $DIR/R12a
1078         test_mkdir $DIR/R12b
1079         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1080         mrename $DIR/R12a $DIR/R12b
1081         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1082         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1083         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1084         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1085 }
1086 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1087
1088 cleanup_multiop_pause() {
1089         trap 0
1090         kill -USR1 $MULTIPID
1091 }
1092
1093 test_24q() {
1094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1095
1096         test_mkdir $DIR/R13a
1097         test_mkdir $DIR/R13b
1098         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1099         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1100         MULTIPID=$!
1101
1102         trap cleanup_multiop_pause EXIT
1103         mrename $DIR/R13a $DIR/R13b
1104         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1105         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1106         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1107         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1108         cleanup_multiop_pause
1109         wait $MULTIPID || error "multiop close failed"
1110 }
1111 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1112
1113 test_24r() { #bug 3789
1114         test_mkdir $DIR/R14a
1115         test_mkdir $DIR/R14a/b
1116         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1117         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1118         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1119 }
1120 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1121
1122 test_24s() {
1123         test_mkdir $DIR/R15a
1124         test_mkdir $DIR/R15a/b
1125         test_mkdir $DIR/R15a/b/c
1126         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1127         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1128         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1129 }
1130 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1131 test_24t() {
1132         test_mkdir $DIR/R16a
1133         test_mkdir $DIR/R16a/b
1134         test_mkdir $DIR/R16a/b/c
1135         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1136         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1137         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1138 }
1139 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1140
1141 test_24u() { # bug12192
1142         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1143         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1144 }
1145 run_test 24u "create stripe file"
1146
1147 simple_cleanup_common() {
1148         local rc=0
1149         trap 0
1150         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1151
1152         local start=$SECONDS
1153         rm -rf $DIR/$tdir
1154         rc=$?
1155         wait_delete_completed
1156         echo "cleanup time $((SECONDS - start))"
1157         return $rc
1158 }
1159
1160 max_pages_per_rpc() {
1161         local mdtname="$(printf "MDT%04x" ${1:-0})"
1162         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1163 }
1164
1165 test_24v() {
1166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1167
1168         local nrfiles=${COUNT:-100000}
1169         local fname="$DIR/$tdir/$tfile"
1170
1171         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1172         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1173
1174         test_mkdir "$(dirname $fname)"
1175         # assume MDT0000 has the fewest inodes
1176         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1177         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1178         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1179
1180         trap simple_cleanup_common EXIT
1181
1182         createmany -m "$fname" $nrfiles
1183
1184         cancel_lru_locks mdc
1185         lctl set_param mdc.*.stats clear
1186
1187         # was previously test_24D: LU-6101
1188         # readdir() returns correct number of entries after cursor reload
1189         local num_ls=$(ls $DIR/$tdir | wc -l)
1190         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1191         local num_all=$(ls -a $DIR/$tdir | wc -l)
1192         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1193                 [ $num_all -ne $((nrfiles + 2)) ]; then
1194                         error "Expected $nrfiles files, got $num_ls " \
1195                                 "($num_uniq unique $num_all .&..)"
1196         fi
1197         # LU-5 large readdir
1198         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1199         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1200         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1201         # take into account of overhead in lu_dirpage header and end mark in
1202         # each page, plus one in rpc_num calculation.
1203         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1204         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1205         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1206         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1207         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1208         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1209         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1210         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1211                 error "large readdir doesn't take effect: " \
1212                       "$mds_readpage should be about $rpc_max"
1213
1214         simple_cleanup_common
1215 }
1216 run_test 24v "list large directory (test hash collision, b=17560)"
1217
1218 test_24w() { # bug21506
1219         SZ1=234852
1220         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1221         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1222         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1223         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1224         [[ "$SZ1" -eq "$SZ2" ]] ||
1225                 error "Error reading at the end of the file $tfile"
1226 }
1227 run_test 24w "Reading a file larger than 4Gb"
1228
1229 test_24x() {
1230         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1232         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1233                 skip "Need MDS version at least 2.7.56"
1234
1235         local MDTIDX=1
1236         local remote_dir=$DIR/$tdir/remote_dir
1237
1238         test_mkdir $DIR/$tdir
1239         $LFS mkdir -i $MDTIDX $remote_dir ||
1240                 error "create remote directory failed"
1241
1242         test_mkdir $DIR/$tdir/src_dir
1243         touch $DIR/$tdir/src_file
1244         test_mkdir $remote_dir/tgt_dir
1245         touch $remote_dir/tgt_file
1246
1247         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1248                 error "rename dir cross MDT failed!"
1249
1250         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1251                 error "rename file cross MDT failed!"
1252
1253         touch $DIR/$tdir/ln_file
1254         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1255                 error "ln file cross MDT failed"
1256
1257         rm -rf $DIR/$tdir || error "Can not delete directories"
1258 }
1259 run_test 24x "cross MDT rename/link"
1260
1261 test_24y() {
1262         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1264
1265         local remote_dir=$DIR/$tdir/remote_dir
1266         local mdtidx=1
1267
1268         test_mkdir $DIR/$tdir
1269         $LFS mkdir -i $mdtidx $remote_dir ||
1270                 error "create remote directory failed"
1271
1272         test_mkdir $remote_dir/src_dir
1273         touch $remote_dir/src_file
1274         test_mkdir $remote_dir/tgt_dir
1275         touch $remote_dir/tgt_file
1276
1277         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1278                 error "rename subdir in the same remote dir failed!"
1279
1280         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1281                 error "rename files in the same remote dir failed!"
1282
1283         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1284                 error "link files in the same remote dir failed!"
1285
1286         rm -rf $DIR/$tdir || error "Can not delete directories"
1287 }
1288 run_test 24y "rename/link on the same dir should succeed"
1289
1290 test_24z() {
1291         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1292         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1293                 skip "Need MDS version at least 2.12.51"
1294
1295         local index
1296
1297         for index in 0 1; do
1298                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1299                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1300         done
1301
1302         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1303
1304         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1305         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1306
1307         local mdts=$(comma_list $(mdts_nodes))
1308
1309         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1310         stack_trap "do_nodes $mdts $LCTL \
1311                 set_param mdt.*.enable_remote_rename=1" EXIT
1312
1313         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1314
1315         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1316         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1317 }
1318 run_test 24z "cross-MDT rename is done as cp"
1319
1320 test_24A() { # LU-3182
1321         local NFILES=5000
1322
1323         rm -rf $DIR/$tdir
1324         test_mkdir $DIR/$tdir
1325         trap simple_cleanup_common EXIT
1326         createmany -m $DIR/$tdir/$tfile $NFILES
1327         local t=$(ls $DIR/$tdir | wc -l)
1328         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1329         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1330         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1331            [ $v -ne $((NFILES + 2)) ] ; then
1332                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1333         fi
1334
1335         simple_cleanup_common || error "Can not delete directories"
1336 }
1337 run_test 24A "readdir() returns correct number of entries."
1338
1339 test_24B() { # LU-4805
1340         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1341
1342         local count
1343
1344         test_mkdir $DIR/$tdir
1345         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1346                 error "create striped dir failed"
1347
1348         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1349         [ $count -eq 2 ] || error "Expected 2, got $count"
1350
1351         touch $DIR/$tdir/striped_dir/a
1352
1353         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1354         [ $count -eq 3 ] || error "Expected 3, got $count"
1355
1356         touch $DIR/$tdir/striped_dir/.f
1357
1358         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1359         [ $count -eq 4 ] || error "Expected 4, got $count"
1360
1361         rm -rf $DIR/$tdir || error "Can not delete directories"
1362 }
1363 run_test 24B "readdir for striped dir return correct number of entries"
1364
1365 test_24C() {
1366         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1367
1368         mkdir $DIR/$tdir
1369         mkdir $DIR/$tdir/d0
1370         mkdir $DIR/$tdir/d1
1371
1372         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1373                 error "create striped dir failed"
1374
1375         cd $DIR/$tdir/d0/striped_dir
1376
1377         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1378         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1379         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1380
1381         [ "$d0_ino" = "$parent_ino" ] ||
1382                 error ".. wrong, expect $d0_ino, get $parent_ino"
1383
1384         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1385                 error "mv striped dir failed"
1386
1387         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1388
1389         [ "$d1_ino" = "$parent_ino" ] ||
1390                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1391 }
1392 run_test 24C "check .. in striped dir"
1393
1394 test_24E() {
1395         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1397
1398         mkdir -p $DIR/$tdir
1399         mkdir $DIR/$tdir/src_dir
1400         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1401                 error "create remote source failed"
1402
1403         touch $DIR/$tdir/src_dir/src_child/a
1404
1405         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1406                 error "create remote target dir failed"
1407
1408         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1409                 error "create remote target child failed"
1410
1411         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1412                 error "rename dir cross MDT failed!"
1413
1414         find $DIR/$tdir
1415
1416         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1417                 error "src_child still exists after rename"
1418
1419         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1420                 error "missing file(a) after rename"
1421
1422         rm -rf $DIR/$tdir || error "Can not delete directories"
1423 }
1424 run_test 24E "cross MDT rename/link"
1425
1426 test_24F () {
1427         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1428
1429         local repeats=1000
1430         [ "$SLOW" = "no" ] && repeats=100
1431
1432         mkdir -p $DIR/$tdir
1433
1434         echo "$repeats repeats"
1435         for ((i = 0; i < repeats; i++)); do
1436                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1437                 touch $DIR/$tdir/test/a || error "touch fails"
1438                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1439                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1440         done
1441
1442         true
1443 }
1444 run_test 24F "hash order vs readdir (LU-11330)"
1445
1446 test_25a() {
1447         echo '== symlink sanity ============================================='
1448
1449         test_mkdir $DIR/d25
1450         ln -s d25 $DIR/s25
1451         touch $DIR/s25/foo ||
1452                 error "File creation in symlinked directory failed"
1453 }
1454 run_test 25a "create file in symlinked directory ==============="
1455
1456 test_25b() {
1457         [ ! -d $DIR/d25 ] && test_25a
1458         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1459 }
1460 run_test 25b "lookup file in symlinked directory ==============="
1461
1462 test_26a() {
1463         test_mkdir $DIR/d26
1464         test_mkdir $DIR/d26/d26-2
1465         ln -s d26/d26-2 $DIR/s26
1466         touch $DIR/s26/foo || error "File creation failed"
1467 }
1468 run_test 26a "multiple component symlink ======================="
1469
1470 test_26b() {
1471         test_mkdir -p $DIR/$tdir/d26-2
1472         ln -s $tdir/d26-2/foo $DIR/s26-2
1473         touch $DIR/s26-2 || error "File creation failed"
1474 }
1475 run_test 26b "multiple component symlink at end of lookup ======"
1476
1477 test_26c() {
1478         test_mkdir $DIR/d26.2
1479         touch $DIR/d26.2/foo
1480         ln -s d26.2 $DIR/s26.2-1
1481         ln -s s26.2-1 $DIR/s26.2-2
1482         ln -s s26.2-2 $DIR/s26.2-3
1483         chmod 0666 $DIR/s26.2-3/foo
1484 }
1485 run_test 26c "chain of symlinks"
1486
1487 # recursive symlinks (bug 439)
1488 test_26d() {
1489         ln -s d26-3/foo $DIR/d26-3
1490 }
1491 run_test 26d "create multiple component recursive symlink"
1492
1493 test_26e() {
1494         [ ! -h $DIR/d26-3 ] && test_26d
1495         rm $DIR/d26-3
1496 }
1497 run_test 26e "unlink multiple component recursive symlink"
1498
1499 # recursive symlinks (bug 7022)
1500 test_26f() {
1501         test_mkdir $DIR/$tdir
1502         test_mkdir $DIR/$tdir/$tfile
1503         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1504         test_mkdir -p lndir/bar1
1505         test_mkdir $DIR/$tdir/$tfile/$tfile
1506         cd $tfile                || error "cd $tfile failed"
1507         ln -s .. dotdot          || error "ln dotdot failed"
1508         ln -s dotdot/lndir lndir || error "ln lndir failed"
1509         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1510         output=`ls $tfile/$tfile/lndir/bar1`
1511         [ "$output" = bar1 ] && error "unexpected output"
1512         rm -r $tfile             || error "rm $tfile failed"
1513         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1514 }
1515 run_test 26f "rm -r of a directory which has recursive symlink"
1516
1517 test_27a() {
1518         test_mkdir $DIR/$tdir
1519         $LFS getstripe $DIR/$tdir
1520         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1521         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1522         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1523 }
1524 run_test 27a "one stripe file"
1525
1526 test_27b() {
1527         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1528
1529         test_mkdir $DIR/$tdir
1530         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1531         $LFS getstripe -c $DIR/$tdir/$tfile
1532         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1533                 error "two-stripe file doesn't have two stripes"
1534
1535         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1536 }
1537 run_test 27b "create and write to two stripe file"
1538
1539 # 27c family tests specific striping, setstripe -o
1540 test_27ca() {
1541         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1542         test_mkdir -p $DIR/$tdir
1543         local osts="1"
1544
1545         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1546         $LFS getstripe -i $DIR/$tdir/$tfile
1547         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1548                 error "stripe not on specified OST"
1549
1550         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1551 }
1552 run_test 27ca "one stripe on specified OST"
1553
1554 test_27cb() {
1555         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1556         test_mkdir -p $DIR/$tdir
1557         local osts="1,0"
1558         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1559         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1560         echo "$getstripe"
1561
1562         # Strip getstripe output to a space separated list of OSTs
1563         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1564                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1565         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1566                 error "stripes not on specified OSTs"
1567
1568         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1569 }
1570 run_test 27cb "two stripes on specified OSTs"
1571
1572 test_27cc() {
1573         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1574         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1575                 skip "server does not support overstriping"
1576
1577         test_mkdir -p $DIR/$tdir
1578         local osts="0,0"
1579         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1580         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1581         echo "$getstripe"
1582
1583         # Strip getstripe output to a space separated list of OSTs
1584         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1585                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1586         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1587                 error "stripes not on specified OSTs"
1588
1589         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1590 }
1591 run_test 27cc "two stripes on the same OST"
1592
1593 test_27cd() {
1594         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1595         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1596                 skip "server does not support overstriping"
1597         test_mkdir -p $DIR/$tdir
1598         local osts="0,1,1,0"
1599         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1600         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1601         echo "$getstripe"
1602
1603         # Strip getstripe output to a space separated list of OSTs
1604         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1605                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1606         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1607                 error "stripes not on specified OSTs"
1608
1609         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1610 }
1611 run_test 27cd "four stripes on two OSTs"
1612
1613 test_27ce() {
1614         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1615                 skip_env "too many osts, skipping"
1616         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1617                 skip "server does not support overstriping"
1618         # We do one more stripe than we have OSTs
1619         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1620                 skip_env "ea_inode feature disabled"
1621
1622         test_mkdir -p $DIR/$tdir
1623         local osts=""
1624         for i in $(seq 0 $OSTCOUNT);
1625         do
1626                 osts=$osts"0"
1627                 if [ $i -ne $OSTCOUNT ]; then
1628                         osts=$osts","
1629                 fi
1630         done
1631         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1632         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1633         echo "$getstripe"
1634
1635         # Strip getstripe output to a space separated list of OSTs
1636         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1637                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1638         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1639                 error "stripes not on specified OSTs"
1640
1641         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1642 }
1643 run_test 27ce "more stripes than OSTs with -o"
1644
1645 test_27cf() {
1646         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1647         local pid=0
1648
1649         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1650         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1651         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1652         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1653                 error "failed to set $osp_proc=0"
1654
1655         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1656         pid=$!
1657         sleep 1
1658         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1659         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1660                 error "failed to set $osp_proc=1"
1661         wait $pid
1662         [[ $pid -ne 0 ]] ||
1663                 error "should return error due to $osp_proc=0"
1664 }
1665 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1666
1667 test_27d() {
1668         test_mkdir $DIR/$tdir
1669         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1670                 error "setstripe failed"
1671         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1672         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1673 }
1674 run_test 27d "create file with default settings"
1675
1676 test_27e() {
1677         # LU-5839 adds check for existed layout before setting it
1678         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1679                 skip "Need MDS version at least 2.7.56"
1680
1681         test_mkdir $DIR/$tdir
1682         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1683         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1684         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1685 }
1686 run_test 27e "setstripe existing file (should return error)"
1687
1688 test_27f() {
1689         test_mkdir $DIR/$tdir
1690         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1691                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1692         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1693                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1694         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1695         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1696 }
1697 run_test 27f "setstripe with bad stripe size (should return error)"
1698
1699 test_27g() {
1700         test_mkdir $DIR/$tdir
1701         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1702         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1703                 error "$DIR/$tdir/$tfile has object"
1704 }
1705 run_test 27g "$LFS getstripe with no objects"
1706
1707 test_27ga() {
1708         test_mkdir $DIR/$tdir
1709         touch $DIR/$tdir/$tfile || error "touch failed"
1710         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1711         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1712         local rc=$?
1713         (( rc == 2 )) || error "getstripe did not return ENOENT"
1714 }
1715 run_test 27ga "$LFS getstripe with missing file (should return error)"
1716
1717 test_27i() {
1718         test_mkdir $DIR/$tdir
1719         touch $DIR/$tdir/$tfile || error "touch failed"
1720         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1721                 error "missing objects"
1722 }
1723 run_test 27i "$LFS getstripe with some objects"
1724
1725 test_27j() {
1726         test_mkdir $DIR/$tdir
1727         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1728                 error "setstripe failed" || true
1729 }
1730 run_test 27j "setstripe with bad stripe offset (should return error)"
1731
1732 test_27k() { # bug 2844
1733         test_mkdir $DIR/$tdir
1734         local file=$DIR/$tdir/$tfile
1735         local ll_max_blksize=$((4 * 1024 * 1024))
1736         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1737         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1738         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1739         dd if=/dev/zero of=$file bs=4k count=1
1740         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1741         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1742 }
1743 run_test 27k "limit i_blksize for broken user apps"
1744
1745 test_27l() {
1746         mcreate $DIR/$tfile || error "creating file"
1747         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1748                 error "setstripe should have failed" || true
1749 }
1750 run_test 27l "check setstripe permissions (should return error)"
1751
1752 test_27m() {
1753         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1754
1755         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1756                 skip_env "multiple clients -- skipping"
1757
1758         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1759                    head -n1)
1760         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1761                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1762         fi
1763         trap simple_cleanup_common EXIT
1764         test_mkdir $DIR/$tdir
1765         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1766         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1767                 error "dd should fill OST0"
1768         i=2
1769         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1770                 i=$((i + 1))
1771                 [ $i -gt 256 ] && break
1772         done
1773         i=$((i + 1))
1774         touch $DIR/$tdir/$tfile.$i
1775         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1776             awk '{print $1}'| grep -w "0") ] &&
1777                 error "OST0 was full but new created file still use it"
1778         i=$((i + 1))
1779         touch $DIR/$tdir/$tfile.$i
1780         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1781             awk '{print $1}'| grep -w "0") ] &&
1782                 error "OST0 was full but new created file still use it"
1783         simple_cleanup_common
1784 }
1785 run_test 27m "create file while OST0 was full"
1786
1787 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1788 # if the OST isn't full anymore.
1789 reset_enospc() {
1790         local ostidx=${1:-""}
1791         local delay
1792         local ready
1793         local get_prealloc
1794
1795         local list=$(comma_list $(osts_nodes))
1796         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1797
1798         do_nodes $list lctl set_param fail_loc=0
1799         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1800         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1801                 awk '{print $1 * 2;exit;}')
1802         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1803                         grep -v \"^0$\""
1804         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1805 }
1806
1807 __exhaust_precreations() {
1808         local OSTIDX=$1
1809         local FAILLOC=$2
1810         local FAILIDX=${3:-$OSTIDX}
1811         local ofacet=ost$((OSTIDX + 1))
1812
1813         test_mkdir -p -c1 $DIR/$tdir
1814         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1815         local mfacet=mds$((mdtidx + 1))
1816         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1817
1818         local OST=$(ostname_from_index $OSTIDX)
1819
1820         # on the mdt's osc
1821         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1822         local last_id=$(do_facet $mfacet lctl get_param -n \
1823                         osp.$mdtosc_proc1.prealloc_last_id)
1824         local next_id=$(do_facet $mfacet lctl get_param -n \
1825                         osp.$mdtosc_proc1.prealloc_next_id)
1826
1827         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1828         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1829
1830         test_mkdir -p $DIR/$tdir/${OST}
1831         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1832 #define OBD_FAIL_OST_ENOSPC              0x215
1833         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1834         echo "Creating to objid $last_id on ost $OST..."
1835         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1836         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1837         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1838 }
1839
1840 exhaust_precreations() {
1841         __exhaust_precreations $1 $2 $3
1842         sleep_maxage
1843 }
1844
1845 exhaust_all_precreations() {
1846         local i
1847         for (( i=0; i < OSTCOUNT; i++ )) ; do
1848                 __exhaust_precreations $i $1 -1
1849         done
1850         sleep_maxage
1851 }
1852
1853 test_27n() {
1854         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1856         remote_mds_nodsh && skip "remote MDS with nodsh"
1857         remote_ost_nodsh && skip "remote OST with nodsh"
1858
1859         reset_enospc
1860         rm -f $DIR/$tdir/$tfile
1861         exhaust_precreations 0 0x80000215
1862         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1863         touch $DIR/$tdir/$tfile || error "touch failed"
1864         $LFS getstripe $DIR/$tdir/$tfile
1865         reset_enospc
1866 }
1867 run_test 27n "create file with some full OSTs"
1868
1869 test_27o() {
1870         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1872         remote_mds_nodsh && skip "remote MDS with nodsh"
1873         remote_ost_nodsh && skip "remote OST with nodsh"
1874
1875         reset_enospc
1876         rm -f $DIR/$tdir/$tfile
1877         exhaust_all_precreations 0x215
1878
1879         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1880
1881         reset_enospc
1882         rm -rf $DIR/$tdir/*
1883 }
1884 run_test 27o "create file with all full OSTs (should error)"
1885
1886 test_27p() {
1887         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1889         remote_mds_nodsh && skip "remote MDS with nodsh"
1890         remote_ost_nodsh && skip "remote OST with nodsh"
1891
1892         reset_enospc
1893         rm -f $DIR/$tdir/$tfile
1894         test_mkdir $DIR/$tdir
1895
1896         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1897         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1898         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1899
1900         exhaust_precreations 0 0x80000215
1901         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1902         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1903         $LFS getstripe $DIR/$tdir/$tfile
1904
1905         reset_enospc
1906 }
1907 run_test 27p "append to a truncated file with some full OSTs"
1908
1909 test_27q() {
1910         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1912         remote_mds_nodsh && skip "remote MDS with nodsh"
1913         remote_ost_nodsh && skip "remote OST with nodsh"
1914
1915         reset_enospc
1916         rm -f $DIR/$tdir/$tfile
1917
1918         test_mkdir $DIR/$tdir
1919         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1920         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1921                 error "truncate $DIR/$tdir/$tfile failed"
1922         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1923
1924         exhaust_all_precreations 0x215
1925
1926         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1927         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1928
1929         reset_enospc
1930 }
1931 run_test 27q "append to truncated file with all OSTs full (should error)"
1932
1933 test_27r() {
1934         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1936         remote_mds_nodsh && skip "remote MDS with nodsh"
1937         remote_ost_nodsh && skip "remote OST with nodsh"
1938
1939         reset_enospc
1940         rm -f $DIR/$tdir/$tfile
1941         exhaust_precreations 0 0x80000215
1942
1943         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1944
1945         reset_enospc
1946 }
1947 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1948
1949 test_27s() { # bug 10725
1950         test_mkdir $DIR/$tdir
1951         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1952         local stripe_count=0
1953         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1954         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1955                 error "stripe width >= 2^32 succeeded" || true
1956
1957 }
1958 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1959
1960 test_27t() { # bug 10864
1961         WDIR=$(pwd)
1962         WLFS=$(which lfs)
1963         cd $DIR
1964         touch $tfile
1965         $WLFS getstripe $tfile
1966         cd $WDIR
1967 }
1968 run_test 27t "check that utils parse path correctly"
1969
1970 test_27u() { # bug 4900
1971         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1972         remote_mds_nodsh && skip "remote MDS with nodsh"
1973
1974         local index
1975         local list=$(comma_list $(mdts_nodes))
1976
1977 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1978         do_nodes $list $LCTL set_param fail_loc=0x139
1979         test_mkdir -p $DIR/$tdir
1980         trap simple_cleanup_common EXIT
1981         createmany -o $DIR/$tdir/t- 1000
1982         do_nodes $list $LCTL set_param fail_loc=0
1983
1984         TLOG=$TMP/$tfile.getstripe
1985         $LFS getstripe $DIR/$tdir > $TLOG
1986         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1987         unlinkmany $DIR/$tdir/t- 1000
1988         trap 0
1989         [[ $OBJS -gt 0 ]] &&
1990                 error "$OBJS objects created on OST-0. See $TLOG" ||
1991                 rm -f $TLOG
1992 }
1993 run_test 27u "skip object creation on OSC w/o objects"
1994
1995 test_27v() { # bug 4900
1996         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1998         remote_mds_nodsh && skip "remote MDS with nodsh"
1999         remote_ost_nodsh && skip "remote OST with nodsh"
2000
2001         exhaust_all_precreations 0x215
2002         reset_enospc
2003
2004         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2005
2006         touch $DIR/$tdir/$tfile
2007         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2008         # all except ost1
2009         for (( i=1; i < OSTCOUNT; i++ )); do
2010                 do_facet ost$i lctl set_param fail_loc=0x705
2011         done
2012         local START=`date +%s`
2013         createmany -o $DIR/$tdir/$tfile 32
2014
2015         local FINISH=`date +%s`
2016         local TIMEOUT=`lctl get_param -n timeout`
2017         local PROCESS=$((FINISH - START))
2018         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2019                error "$FINISH - $START >= $TIMEOUT / 2"
2020         sleep $((TIMEOUT / 2 - PROCESS))
2021         reset_enospc
2022 }
2023 run_test 27v "skip object creation on slow OST"
2024
2025 test_27w() { # bug 10997
2026         test_mkdir $DIR/$tdir
2027         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2028         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2029                 error "stripe size $size != 65536" || true
2030         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2031                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2032 }
2033 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2034
2035 test_27wa() {
2036         [[ $OSTCOUNT -lt 2 ]] &&
2037                 skip_env "skipping multiple stripe count/offset test"
2038
2039         test_mkdir $DIR/$tdir
2040         for i in $(seq 1 $OSTCOUNT); do
2041                 offset=$((i - 1))
2042                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2043                         error "setstripe -c $i -i $offset failed"
2044                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2045                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2046                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2047                 [ $index -ne $offset ] &&
2048                         error "stripe offset $index != $offset" || true
2049         done
2050 }
2051 run_test 27wa "check $LFS setstripe -c -i options"
2052
2053 test_27x() {
2054         remote_ost_nodsh && skip "remote OST with nodsh"
2055         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2057
2058         OFFSET=$(($OSTCOUNT - 1))
2059         OSTIDX=0
2060         local OST=$(ostname_from_index $OSTIDX)
2061
2062         test_mkdir $DIR/$tdir
2063         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2064         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2065         sleep_maxage
2066         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2067         for i in $(seq 0 $OFFSET); do
2068                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2069                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2070                 error "OST0 was degraded but new created file still use it"
2071         done
2072         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2073 }
2074 run_test 27x "create files while OST0 is degraded"
2075
2076 test_27y() {
2077         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2078         remote_mds_nodsh && skip "remote MDS with nodsh"
2079         remote_ost_nodsh && skip "remote OST with nodsh"
2080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2081
2082         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2083         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2084                 osp.$mdtosc.prealloc_last_id)
2085         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2086                 osp.$mdtosc.prealloc_next_id)
2087         local fcount=$((last_id - next_id))
2088         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2089         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2090
2091         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2092                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2093         local OST_DEACTIVE_IDX=-1
2094         local OSC
2095         local OSTIDX
2096         local OST
2097
2098         for OSC in $MDS_OSCS; do
2099                 OST=$(osc_to_ost $OSC)
2100                 OSTIDX=$(index_from_ostuuid $OST)
2101                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2102                         OST_DEACTIVE_IDX=$OSTIDX
2103                 fi
2104                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2105                         echo $OSC "is Deactivated:"
2106                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2107                 fi
2108         done
2109
2110         OSTIDX=$(index_from_ostuuid $OST)
2111         test_mkdir $DIR/$tdir
2112         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2113
2114         for OSC in $MDS_OSCS; do
2115                 OST=$(osc_to_ost $OSC)
2116                 OSTIDX=$(index_from_ostuuid $OST)
2117                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2118                         echo $OST "is degraded:"
2119                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2120                                                 obdfilter.$OST.degraded=1
2121                 fi
2122         done
2123
2124         sleep_maxage
2125         createmany -o $DIR/$tdir/$tfile $fcount
2126
2127         for OSC in $MDS_OSCS; do
2128                 OST=$(osc_to_ost $OSC)
2129                 OSTIDX=$(index_from_ostuuid $OST)
2130                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2131                         echo $OST "is recovered from degraded:"
2132                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2133                                                 obdfilter.$OST.degraded=0
2134                 else
2135                         do_facet $SINGLEMDS lctl --device %$OSC activate
2136                 fi
2137         done
2138
2139         # all osp devices get activated, hence -1 stripe count restored
2140         local stripe_count=0
2141
2142         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2143         # devices get activated.
2144         sleep_maxage
2145         $LFS setstripe -c -1 $DIR/$tfile
2146         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2147         rm -f $DIR/$tfile
2148         [ $stripe_count -ne $OSTCOUNT ] &&
2149                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2150         return 0
2151 }
2152 run_test 27y "create files while OST0 is degraded and the rest inactive"
2153
2154 check_seq_oid()
2155 {
2156         log "check file $1"
2157
2158         lmm_count=$($LFS getstripe -c $1)
2159         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2160         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2161
2162         local old_ifs="$IFS"
2163         IFS=$'[:]'
2164         fid=($($LFS path2fid $1))
2165         IFS="$old_ifs"
2166
2167         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2168         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2169
2170         # compare lmm_seq and lu_fid->f_seq
2171         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2172         # compare lmm_object_id and lu_fid->oid
2173         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2174
2175         # check the trusted.fid attribute of the OST objects of the file
2176         local have_obdidx=false
2177         local stripe_nr=0
2178         $LFS getstripe $1 | while read obdidx oid hex seq; do
2179                 # skip lines up to and including "obdidx"
2180                 [ -z "$obdidx" ] && break
2181                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2182                 $have_obdidx || continue
2183
2184                 local ost=$((obdidx + 1))
2185                 local dev=$(ostdevname $ost)
2186                 local oid_hex
2187
2188                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2189
2190                 seq=$(echo $seq | sed -e "s/^0x//g")
2191                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2192                         oid_hex=$(echo $oid)
2193                 else
2194                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2195                 fi
2196                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2197
2198                 local ff=""
2199                 #
2200                 # Don't unmount/remount the OSTs if we don't need to do that.
2201                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2202                 # update too, until that use mount/ll_decode_filter_fid/mount.
2203                 # Re-enable when debugfs will understand new filter_fid.
2204                 #
2205                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2206                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2207                                 $dev 2>/dev/null" | grep "parent=")
2208                 fi
2209                 if [ -z "$ff" ]; then
2210                         stop ost$ost
2211                         mount_fstype ost$ost
2212                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2213                                 $(facet_mntpt ost$ost)/$obj_file)
2214                         unmount_fstype ost$ost
2215                         start ost$ost $dev $OST_MOUNT_OPTS
2216                         clients_up
2217                 fi
2218
2219                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2220
2221                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2222
2223                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2224                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2225                 #
2226                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2227                 #       stripe_size=1048576 component_id=1 component_start=0 \
2228                 #       component_end=33554432
2229                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2230                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2231                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2232                 local ff_pstripe
2233                 if grep -q 'stripe=' <<<$ff; then
2234                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2235                 else
2236                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2237                         # into f_ver in this case.  See comment on ff_parent.
2238                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2239                 fi
2240
2241                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2242                 [ $ff_pseq = $lmm_seq ] ||
2243                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2244                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2245                 [ $ff_poid = $lmm_oid ] ||
2246                         error "FF parent OID $ff_poid != $lmm_oid"
2247                 (($ff_pstripe == $stripe_nr)) ||
2248                         error "FF stripe $ff_pstripe != $stripe_nr"
2249
2250                 stripe_nr=$((stripe_nr + 1))
2251                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2252                         continue
2253                 if grep -q 'stripe_count=' <<<$ff; then
2254                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2255                                             -e 's/ .*//' <<<$ff)
2256                         [ $lmm_count = $ff_scnt ] ||
2257                                 error "FF stripe count $lmm_count != $ff_scnt"
2258                 fi
2259         done
2260 }
2261
2262 test_27z() {
2263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2264         remote_ost_nodsh && skip "remote OST with nodsh"
2265
2266         test_mkdir $DIR/$tdir
2267         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2268                 { error "setstripe -c -1 failed"; return 1; }
2269         # We need to send a write to every object to get parent FID info set.
2270         # This _should_ also work for setattr, but does not currently.
2271         # touch $DIR/$tdir/$tfile-1 ||
2272         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2273                 { error "dd $tfile-1 failed"; return 2; }
2274         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2275                 { error "setstripe -c -1 failed"; return 3; }
2276         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2277                 { error "dd $tfile-2 failed"; return 4; }
2278
2279         # make sure write RPCs have been sent to OSTs
2280         sync; sleep 5; sync
2281
2282         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2283         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2284 }
2285 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2286
2287 test_27A() { # b=19102
2288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2289
2290         save_layout_restore_at_exit $MOUNT
2291         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2292         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2293                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2294         local default_size=$($LFS getstripe -S $MOUNT)
2295         local default_offset=$($LFS getstripe -i $MOUNT)
2296         local dsize=$(do_facet $SINGLEMDS \
2297                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2298         [ $default_size -eq $dsize ] ||
2299                 error "stripe size $default_size != $dsize"
2300         [ $default_offset -eq -1 ] ||
2301                 error "stripe offset $default_offset != -1"
2302 }
2303 run_test 27A "check filesystem-wide default LOV EA values"
2304
2305 test_27B() { # LU-2523
2306         test_mkdir $DIR/$tdir
2307         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2308         touch $DIR/$tdir/f0
2309         # open f1 with O_LOV_DELAY_CREATE
2310         # rename f0 onto f1
2311         # call setstripe ioctl on open file descriptor for f1
2312         # close
2313         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2314                 $DIR/$tdir/f0
2315
2316         rm -f $DIR/$tdir/f1
2317         # open f1 with O_LOV_DELAY_CREATE
2318         # unlink f1
2319         # call setstripe ioctl on open file descriptor for f1
2320         # close
2321         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2322
2323         # Allow multiop to fail in imitation of NFS's busted semantics.
2324         true
2325 }
2326 run_test 27B "call setstripe on open unlinked file/rename victim"
2327
2328 # 27C family tests full striping and overstriping
2329 test_27Ca() { #LU-2871
2330         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2331
2332         declare -a ost_idx
2333         local index
2334         local found
2335         local i
2336         local j
2337
2338         test_mkdir $DIR/$tdir
2339         cd $DIR/$tdir
2340         for i in $(seq 0 $((OSTCOUNT - 1))); do
2341                 # set stripe across all OSTs starting from OST$i
2342                 $LFS setstripe -i $i -c -1 $tfile$i
2343                 # get striping information
2344                 ost_idx=($($LFS getstripe $tfile$i |
2345                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2346                 echo ${ost_idx[@]}
2347
2348                 # check the layout
2349                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2350                         error "${#ost_idx[@]} != $OSTCOUNT"
2351
2352                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2353                         found=0
2354                         for j in $(echo ${ost_idx[@]}); do
2355                                 if [ $index -eq $j ]; then
2356                                         found=1
2357                                         break
2358                                 fi
2359                         done
2360                         [ $found = 1 ] ||
2361                                 error "Can not find $index in ${ost_idx[@]}"
2362                 done
2363         done
2364 }
2365 run_test 27Ca "check full striping across all OSTs"
2366
2367 test_27Cb() {
2368         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2369                 skip "server does not support overstriping"
2370         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2371                 skip_env "too many osts, skipping"
2372
2373         test_mkdir -p $DIR/$tdir
2374         local setcount=$(($OSTCOUNT * 2))
2375         [ $setcount -ge 160 ] || large_xattr_enabled ||
2376                 skip_env "ea_inode feature disabled"
2377
2378         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2379                 error "setstripe failed"
2380
2381         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2382         [ $count -eq $setcount ] ||
2383                 error "stripe count $count, should be $setcount"
2384
2385         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2386                 error "overstriped should be set in pattern"
2387
2388         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2389                 error "dd failed"
2390 }
2391 run_test 27Cb "more stripes than OSTs with -C"
2392
2393 test_27Cc() {
2394         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2395                 skip "server does not support overstriping"
2396         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2397
2398         test_mkdir -p $DIR/$tdir
2399         local setcount=$(($OSTCOUNT - 1))
2400
2401         [ $setcount -ge 160 ] || large_xattr_enabled ||
2402                 skip_env "ea_inode feature disabled"
2403
2404         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2405                 error "setstripe failed"
2406
2407         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2408         [ $count -eq $setcount ] ||
2409                 error "stripe count $count, should be $setcount"
2410
2411         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2412                 error "overstriped should not be set in pattern"
2413
2414         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2415                 error "dd failed"
2416 }
2417 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2418
2419 test_27Cd() {
2420         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2421                 skip "server does not support overstriping"
2422         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2423         large_xattr_enabled || skip_env "ea_inode feature disabled"
2424
2425         test_mkdir -p $DIR/$tdir
2426         local setcount=$LOV_MAX_STRIPE_COUNT
2427
2428         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2429                 error "setstripe failed"
2430
2431         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2432         [ $count -eq $setcount ] ||
2433                 error "stripe count $count, should be $setcount"
2434
2435         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2436                 error "overstriped should be set in pattern"
2437
2438         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2439                 error "dd failed"
2440
2441         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2442 }
2443 run_test 27Cd "test maximum stripe count"
2444
2445 test_27Ce() {
2446         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2447                 skip "server does not support overstriping"
2448         test_mkdir -p $DIR/$tdir
2449
2450         pool_add $TESTNAME || error "Pool creation failed"
2451         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2452
2453         local setcount=8
2454
2455         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2456                 error "setstripe failed"
2457
2458         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2459         [ $count -eq $setcount ] ||
2460                 error "stripe count $count, should be $setcount"
2461
2462         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2463                 error "overstriped should be set in pattern"
2464
2465         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2466                 error "dd failed"
2467
2468         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2469 }
2470 run_test 27Ce "test pool with overstriping"
2471
2472 test_27Cf() {
2473         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2474                 skip "server does not support overstriping"
2475         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2476                 skip_env "too many osts, skipping"
2477
2478         test_mkdir -p $DIR/$tdir
2479
2480         local setcount=$(($OSTCOUNT * 2))
2481         [ $setcount -ge 160 ] || large_xattr_enabled ||
2482                 skip_env "ea_inode feature disabled"
2483
2484         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2485                 error "setstripe failed"
2486
2487         echo 1 > $DIR/$tdir/$tfile
2488
2489         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2490         [ $count -eq $setcount ] ||
2491                 error "stripe count $count, should be $setcount"
2492
2493         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2494                 error "overstriped should be set in pattern"
2495
2496         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2497                 error "dd failed"
2498
2499         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2500 }
2501 run_test 27Cf "test default inheritance with overstriping"
2502
2503 test_27D() {
2504         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2505         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2506         remote_mds_nodsh && skip "remote MDS with nodsh"
2507
2508         local POOL=${POOL:-testpool}
2509         local first_ost=0
2510         local last_ost=$(($OSTCOUNT - 1))
2511         local ost_step=1
2512         local ost_list=$(seq $first_ost $ost_step $last_ost)
2513         local ost_range="$first_ost $last_ost $ost_step"
2514
2515         test_mkdir $DIR/$tdir
2516         pool_add $POOL || error "pool_add failed"
2517         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2518
2519         local skip27D
2520         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2521                 skip27D+="-s 29"
2522         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2523                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2524                         skip27D+=" -s 30,31"
2525         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2526           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2527                 skip27D+=" -s 32,33"
2528         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2529                 skip27D+=" -s 34"
2530         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2531                 error "llapi_layout_test failed"
2532
2533         destroy_test_pools || error "destroy test pools failed"
2534 }
2535 run_test 27D "validate llapi_layout API"
2536
2537 # Verify that default_easize is increased from its initial value after
2538 # accessing a widely striped file.
2539 test_27E() {
2540         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2541         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2542                 skip "client does not have LU-3338 fix"
2543
2544         # 72 bytes is the minimum space required to store striping
2545         # information for a file striped across one OST:
2546         # (sizeof(struct lov_user_md_v3) +
2547         #  sizeof(struct lov_user_ost_data_v1))
2548         local min_easize=72
2549         $LCTL set_param -n llite.*.default_easize $min_easize ||
2550                 error "lctl set_param failed"
2551         local easize=$($LCTL get_param -n llite.*.default_easize)
2552
2553         [ $easize -eq $min_easize ] ||
2554                 error "failed to set default_easize"
2555
2556         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2557                 error "setstripe failed"
2558         # In order to ensure stat() call actually talks to MDS we need to
2559         # do something drastic to this file to shake off all lock, e.g.
2560         # rename it (kills lookup lock forcing cache cleaning)
2561         mv $DIR/$tfile $DIR/${tfile}-1
2562         ls -l $DIR/${tfile}-1
2563         rm $DIR/${tfile}-1
2564
2565         easize=$($LCTL get_param -n llite.*.default_easize)
2566
2567         [ $easize -gt $min_easize ] ||
2568                 error "default_easize not updated"
2569 }
2570 run_test 27E "check that default extended attribute size properly increases"
2571
2572 test_27F() { # LU-5346/LU-7975
2573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2574         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2575         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2576                 skip "Need MDS version at least 2.8.51"
2577         remote_ost_nodsh && skip "remote OST with nodsh"
2578
2579         test_mkdir $DIR/$tdir
2580         rm -f $DIR/$tdir/f0
2581         $LFS setstripe -c 2 $DIR/$tdir
2582
2583         # stop all OSTs to reproduce situation for LU-7975 ticket
2584         for num in $(seq $OSTCOUNT); do
2585                 stop ost$num
2586         done
2587
2588         # open/create f0 with O_LOV_DELAY_CREATE
2589         # truncate f0 to a non-0 size
2590         # close
2591         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2592
2593         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2594         # open/write it again to force delayed layout creation
2595         cat /etc/hosts > $DIR/$tdir/f0 &
2596         catpid=$!
2597
2598         # restart OSTs
2599         for num in $(seq $OSTCOUNT); do
2600                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2601                         error "ost$num failed to start"
2602         done
2603
2604         wait $catpid || error "cat failed"
2605
2606         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2607         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2608                 error "wrong stripecount"
2609
2610 }
2611 run_test 27F "Client resend delayed layout creation with non-zero size"
2612
2613 test_27G() { #LU-10629
2614         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2615                 skip "Need MDS version at least 2.11.51"
2616         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2617         remote_mds_nodsh && skip "remote MDS with nodsh"
2618         local POOL=${POOL:-testpool}
2619         local ostrange="0 0 1"
2620
2621         test_mkdir $DIR/$tdir
2622         touch $DIR/$tdir/$tfile.nopool
2623         pool_add $POOL || error "pool_add failed"
2624         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2625         $LFS setstripe -p $POOL $DIR/$tdir
2626
2627         local pool=$($LFS getstripe -p $DIR/$tdir)
2628
2629         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2630         touch $DIR/$tdir/$tfile.default
2631         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2632         $LFS find $DIR/$tdir -type f --pool $POOL
2633         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2634         [[ "$found" == "2" ]] ||
2635                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2636
2637         $LFS setstripe -d $DIR/$tdir
2638
2639         pool=$($LFS getstripe -p -d $DIR/$tdir)
2640
2641         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2642 }
2643 run_test 27G "Clear OST pool from stripe"
2644
2645 test_27H() {
2646         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2647                 skip "Need MDS version newer than 2.11.54"
2648         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2649         test_mkdir $DIR/$tdir
2650         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2651         touch $DIR/$tdir/$tfile
2652         $LFS getstripe -c $DIR/$tdir/$tfile
2653         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2654                 error "two-stripe file doesn't have two stripes"
2655
2656         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2657         $LFS getstripe -y $DIR/$tdir/$tfile
2658         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2659              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2660                 error "expected l_ost_idx: [02]$ not matched"
2661
2662         # make sure ost list has been cleared
2663         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2664         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2665                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2666         touch $DIR/$tdir/f3
2667         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2668 }
2669 run_test 27H "Set specific OSTs stripe"
2670
2671 test_27I() {
2672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2673         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2674         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2675                 skip "Need MDS version newer than 2.12.52"
2676         local pool=$TESTNAME
2677         local ostrange="1 1 1"
2678
2679         save_layout_restore_at_exit $MOUNT
2680         $LFS setstripe -c 2 -i 0 $MOUNT
2681         pool_add $pool || error "pool_add failed"
2682         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2683         test_mkdir $DIR/$tdir
2684         $LFS setstripe -p $pool $DIR/$tdir
2685         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2686         $LFS getstripe $DIR/$tdir/$tfile
2687 }
2688 run_test 27I "check that root dir striping does not break parent dir one"
2689
2690 test_27J() {
2691         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2692                 skip "Need MDS version newer than 2.12.51"
2693
2694         test_mkdir $DIR/$tdir
2695         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2696         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2697
2698         # create foreign file (raw way)
2699         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2700                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2701
2702         # verify foreign file (raw way)
2703         parse_foreign_file -f $DIR/$tdir/$tfile |
2704                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2705                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2706         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2707                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2708         parse_foreign_file -f $DIR/$tdir/$tfile |
2709                 grep "lov_foreign_size: 73" ||
2710                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2711         parse_foreign_file -f $DIR/$tdir/$tfile |
2712                 grep "lov_foreign_type: 1" ||
2713                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2714         parse_foreign_file -f $DIR/$tdir/$tfile |
2715                 grep "lov_foreign_flags: 0x0000DA08" ||
2716                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2717         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2718                 grep "lov_foreign_value: 0x" |
2719                 sed -e 's/lov_foreign_value: 0x//')
2720         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2721         [[ $lov = ${lov2// /} ]] ||
2722                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2723
2724         # create foreign file (lfs + API)
2725         $LFS setstripe --foreign=daos --flags 0xda08 \
2726                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2727                 error "$DIR/$tdir/${tfile}2: create failed"
2728
2729         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2730                 grep "lfm_magic:.*0x0BD70BD0" ||
2731                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2732         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2733         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2734                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2735         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2736                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2737         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2738                 grep "lfm_flags:.*0x0000DA08" ||
2739                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2740         $LFS getstripe $DIR/$tdir/${tfile}2 |
2741                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2742                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2743
2744         # modify striping should fail
2745         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2746                 error "$DIR/$tdir/$tfile: setstripe should fail"
2747         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2748                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2749
2750         # R/W should fail
2751         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2752         cat $DIR/$tdir/${tfile}2 &&
2753                 error "$DIR/$tdir/${tfile}2: read should fail"
2754         cat /etc/passwd > $DIR/$tdir/$tfile &&
2755                 error "$DIR/$tdir/$tfile: write should fail"
2756         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2757                 error "$DIR/$tdir/${tfile}2: write should fail"
2758
2759         # chmod should work
2760         chmod 222 $DIR/$tdir/$tfile ||
2761                 error "$DIR/$tdir/$tfile: chmod failed"
2762         chmod 222 $DIR/$tdir/${tfile}2 ||
2763                 error "$DIR/$tdir/${tfile}2: chmod failed"
2764
2765         # chown should work
2766         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2767                 error "$DIR/$tdir/$tfile: chown failed"
2768         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2769                 error "$DIR/$tdir/${tfile}2: chown failed"
2770
2771         # rename should work
2772         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2773                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2774         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2775                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2776
2777         #remove foreign file
2778         rm $DIR/$tdir/${tfile}.new ||
2779                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2780         rm $DIR/$tdir/${tfile}2.new ||
2781                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2782 }
2783 run_test 27J "basic ops on file with foreign LOV"
2784
2785 test_27K() {
2786         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2787                 skip "Need MDS version newer than 2.12.49"
2788
2789         test_mkdir $DIR/$tdir
2790         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2791         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2792
2793         # create foreign dir (raw way)
2794         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2795                 error "create_foreign_dir FAILED"
2796
2797         # verify foreign dir (raw way)
2798         parse_foreign_dir -d $DIR/$tdir/$tdir |
2799                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2800                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2801         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2802                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2803         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2804                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2805         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2806                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2807         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2808                 grep "lmv_foreign_value: 0x" |
2809                 sed 's/lmv_foreign_value: 0x//')
2810         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2811                 sed 's/ //g')
2812         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2813
2814         # create foreign dir (lfs + API)
2815         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2816                 $DIR/$tdir/${tdir}2 ||
2817                 error "$DIR/$tdir/${tdir}2: create failed"
2818
2819         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2820                 grep "lfm_magic:.*0x0CD50CD0" ||
2821                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2822         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2823         # - sizeof(lfm_type) - sizeof(lfm_flags)
2824         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2825                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2826         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2827                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2828         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2829                 grep "lfm_flags:.*0x0000DA05" ||
2830                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2831         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2832                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2833                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2834
2835         # file create in dir should fail
2836         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2837         touch $DIR/$tdir/${tdir}2/$tfile &&
2838                 "$DIR/${tdir}2: file create should fail"
2839
2840         # chmod should work
2841         chmod 777 $DIR/$tdir/$tdir ||
2842                 error "$DIR/$tdir: chmod failed"
2843         chmod 777 $DIR/$tdir/${tdir}2 ||
2844                 error "$DIR/${tdir}2: chmod failed"
2845
2846         # chown should work
2847         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2848                 error "$DIR/$tdir: chown failed"
2849         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2850                 error "$DIR/${tdir}2: chown failed"
2851
2852         # rename should work
2853         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2854                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2855         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2856                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2857
2858         #remove foreign dir
2859         rmdir $DIR/$tdir/${tdir}.new ||
2860                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2861         rmdir $DIR/$tdir/${tdir}2.new ||
2862                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2863 }
2864 run_test 27K "basic ops on dir with foreign LMV"
2865
2866 test_27L() {
2867         remote_mds_nodsh && skip "remote MDS with nodsh"
2868
2869         local POOL=${POOL:-$TESTNAME}
2870
2871         pool_add $POOL || error "pool_add failed"
2872
2873         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2874                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2875                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2876 }
2877 run_test 27L "lfs pool_list gives correct pool name"
2878
2879 test_27M() {
2880         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2881                 skip "Need MDS version >= than 2.12.57"
2882         remote_mds_nodsh && skip "remote MDS with nodsh"
2883         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2884
2885         test_mkdir $DIR/$tdir
2886
2887         # Set default striping on directory
2888         $LFS setstripe -C 4 $DIR/$tdir
2889
2890         echo 1 > $DIR/$tdir/${tfile}.1
2891         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2892         local setcount=4
2893         [ $count -eq $setcount ] ||
2894                 error "(1) stripe count $count, should be $setcount"
2895
2896         # Capture existing append_stripe_count setting for restore
2897         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2898         local mdts=$(comma_list $(mdts_nodes))
2899         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2900
2901         local appendcount=$orig_count
2902         echo 1 >> $DIR/$tdir/${tfile}.2_append
2903         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2904         [ $count -eq $appendcount ] ||
2905                 error "(2)stripe count $count, should be $appendcount for append"
2906
2907         # Disable O_APPEND striping, verify it works
2908         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2909
2910         # Should now get the default striping, which is 4
2911         setcount=4
2912         echo 1 >> $DIR/$tdir/${tfile}.3_append
2913         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2914         [ $count -eq $setcount ] ||
2915                 error "(3) stripe count $count, should be $setcount"
2916
2917         # Try changing the stripe count for append files
2918         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2919
2920         # Append striping is now 2 (directory default is still 4)
2921         appendcount=2
2922         echo 1 >> $DIR/$tdir/${tfile}.4_append
2923         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2924         [ $count -eq $appendcount ] ||
2925                 error "(4) stripe count $count, should be $appendcount for append"
2926
2927         # Test append stripe count of -1
2928         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2929         appendcount=$OSTCOUNT
2930         echo 1 >> $DIR/$tdir/${tfile}.5
2931         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2932         [ $count -eq $appendcount ] ||
2933                 error "(5) stripe count $count, should be $appendcount for append"
2934
2935         # Set append striping back to default of 1
2936         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2937
2938         # Try a new default striping, PFL + DOM
2939         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2940
2941         # Create normal DOM file, DOM returns stripe count == 0
2942         setcount=0
2943         touch $DIR/$tdir/${tfile}.6
2944         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2945         [ $count -eq $setcount ] ||
2946                 error "(6) stripe count $count, should be $setcount"
2947
2948         # Show
2949         appendcount=1
2950         echo 1 >> $DIR/$tdir/${tfile}.7_append
2951         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2952         [ $count -eq $appendcount ] ||
2953                 error "(7) stripe count $count, should be $appendcount for append"
2954
2955         # Clean up DOM layout
2956         $LFS setstripe -d $DIR/$tdir
2957
2958         # Now test that append striping works when layout is from root
2959         $LFS setstripe -c 2 $MOUNT
2960         # Make a special directory for this
2961         mkdir $DIR/${tdir}/${tdir}.2
2962         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2963
2964         # Verify for normal file
2965         setcount=2
2966         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2967         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2968         [ $count -eq $setcount ] ||
2969                 error "(8) stripe count $count, should be $setcount"
2970
2971         appendcount=1
2972         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2973         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2974         [ $count -eq $appendcount ] ||
2975                 error "(9) stripe count $count, should be $appendcount for append"
2976
2977         # Now test O_APPEND striping with pools
2978         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2979         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2980
2981         # Create the pool
2982         pool_add $TESTNAME || error "pool creation failed"
2983         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2984
2985         echo 1 >> $DIR/$tdir/${tfile}.10_append
2986
2987         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2988         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2989
2990         # Check that count is still correct
2991         appendcount=1
2992         echo 1 >> $DIR/$tdir/${tfile}.11_append
2993         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2994         [ $count -eq $appendcount ] ||
2995                 error "(11) stripe count $count, should be $appendcount for append"
2996
2997         # Disable O_APPEND stripe count, verify pool works separately
2998         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2999
3000         echo 1 >> $DIR/$tdir/${tfile}.12_append
3001
3002         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3003         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3004
3005         # Remove pool setting, verify it's not applied
3006         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3007
3008         echo 1 >> $DIR/$tdir/${tfile}.13_append
3009
3010         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3011         [ "$pool" = "" ] || error "(13) pool found: $pool"
3012 }
3013 run_test 27M "test O_APPEND striping"
3014
3015 test_27N() {
3016         combined_mgs_mds && skip "needs separate MGS/MDT"
3017
3018         pool_add $TESTNAME || error "pool_add failed"
3019         do_facet mgs "$LCTL pool_list $FSNAME" |
3020                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3021                 error "lctl pool_list on MGS failed"
3022 }
3023 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3024
3025 # createtest also checks that device nodes are created and
3026 # then visible correctly (#2091)
3027 test_28() { # bug 2091
3028         test_mkdir $DIR/d28
3029         $CREATETEST $DIR/d28/ct || error "createtest failed"
3030 }
3031 run_test 28 "create/mknod/mkdir with bad file types ============"
3032
3033 test_29() {
3034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3035
3036         sync; sleep 1; sync # flush out any dirty pages from previous tests
3037         cancel_lru_locks
3038         test_mkdir $DIR/d29
3039         touch $DIR/d29/foo
3040         log 'first d29'
3041         ls -l $DIR/d29
3042
3043         declare -i LOCKCOUNTORIG=0
3044         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3045                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3046         done
3047         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3048
3049         declare -i LOCKUNUSEDCOUNTORIG=0
3050         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3051                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3052         done
3053
3054         log 'second d29'
3055         ls -l $DIR/d29
3056         log 'done'
3057
3058         declare -i LOCKCOUNTCURRENT=0
3059         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3060                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3061         done
3062
3063         declare -i LOCKUNUSEDCOUNTCURRENT=0
3064         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3065                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3066         done
3067
3068         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3069                 $LCTL set_param -n ldlm.dump_namespaces ""
3070                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3071                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3072                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3073                 return 2
3074         fi
3075         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3076                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3077                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3078                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3079                 return 3
3080         fi
3081 }
3082 run_test 29 "IT_GETATTR regression  ============================"
3083
3084 test_30a() { # was test_30
3085         cp $(which ls) $DIR || cp /bin/ls $DIR
3086         $DIR/ls / || error "Can't execute binary from lustre"
3087         rm $DIR/ls
3088 }
3089 run_test 30a "execute binary from Lustre (execve) =============="
3090
3091 test_30b() {
3092         cp `which ls` $DIR || cp /bin/ls $DIR
3093         chmod go+rx $DIR/ls
3094         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3095         rm $DIR/ls
3096 }
3097 run_test 30b "execute binary from Lustre as non-root ==========="
3098
3099 test_30c() { # b=22376
3100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3101
3102         cp $(which ls) $DIR || cp /bin/ls $DIR
3103         chmod a-rw $DIR/ls
3104         cancel_lru_locks mdc
3105         cancel_lru_locks osc
3106         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3107         rm -f $DIR/ls
3108 }
3109 run_test 30c "execute binary from Lustre without read perms ===="
3110
3111 test_30d() {
3112         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3113
3114         for i in {1..10}; do
3115                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3116                 local PID=$!
3117                 sleep 1
3118                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3119                 wait $PID || error "executing dd from Lustre failed"
3120                 rm -f $DIR/$tfile
3121         done
3122
3123         rm -f $DIR/dd
3124 }
3125 run_test 30d "execute binary from Lustre while clear locks"
3126
3127 test_31a() {
3128         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3129         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3130 }
3131 run_test 31a "open-unlink file =================================="
3132
3133 test_31b() {
3134         touch $DIR/f31 || error "touch $DIR/f31 failed"
3135         ln $DIR/f31 $DIR/f31b || error "ln failed"
3136         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3137         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3138 }
3139 run_test 31b "unlink file with multiple links while open ======="
3140
3141 test_31c() {
3142         touch $DIR/f31 || error "touch $DIR/f31 failed"
3143         ln $DIR/f31 $DIR/f31c || error "ln failed"
3144         multiop_bg_pause $DIR/f31 O_uc ||
3145                 error "multiop_bg_pause for $DIR/f31 failed"
3146         MULTIPID=$!
3147         $MULTIOP $DIR/f31c Ouc
3148         kill -USR1 $MULTIPID
3149         wait $MULTIPID
3150 }
3151 run_test 31c "open-unlink file with multiple links ============="
3152
3153 test_31d() {
3154         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3155         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3156 }
3157 run_test 31d "remove of open directory ========================="
3158
3159 test_31e() { # bug 2904
3160         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3161 }
3162 run_test 31e "remove of open non-empty directory ==============="
3163
3164 test_31f() { # bug 4554
3165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3166
3167         set -vx
3168         test_mkdir $DIR/d31f
3169         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3170         cp /etc/hosts $DIR/d31f
3171         ls -l $DIR/d31f
3172         $LFS getstripe $DIR/d31f/hosts
3173         multiop_bg_pause $DIR/d31f D_c || return 1
3174         MULTIPID=$!
3175
3176         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3177         test_mkdir $DIR/d31f
3178         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3179         cp /etc/hosts $DIR/d31f
3180         ls -l $DIR/d31f
3181         $LFS getstripe $DIR/d31f/hosts
3182         multiop_bg_pause $DIR/d31f D_c || return 1
3183         MULTIPID2=$!
3184
3185         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3186         wait $MULTIPID || error "first opendir $MULTIPID failed"
3187
3188         sleep 6
3189
3190         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3191         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3192         set +vx
3193 }
3194 run_test 31f "remove of open directory with open-unlink file ==="
3195
3196 test_31g() {
3197         echo "-- cross directory link --"
3198         test_mkdir -c1 $DIR/${tdir}ga
3199         test_mkdir -c1 $DIR/${tdir}gb
3200         touch $DIR/${tdir}ga/f
3201         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3202         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3203         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3204         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3205         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3206 }
3207 run_test 31g "cross directory link==============="
3208
3209 test_31h() {
3210         echo "-- cross directory link --"
3211         test_mkdir -c1 $DIR/${tdir}
3212         test_mkdir -c1 $DIR/${tdir}/dir
3213         touch $DIR/${tdir}/f
3214         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3215         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3216         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3217         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3218         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3219 }
3220 run_test 31h "cross directory link under child==============="
3221
3222 test_31i() {
3223         echo "-- cross directory link --"
3224         test_mkdir -c1 $DIR/$tdir
3225         test_mkdir -c1 $DIR/$tdir/dir
3226         touch $DIR/$tdir/dir/f
3227         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3228         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3229         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3230         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3231         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3232 }
3233 run_test 31i "cross directory link under parent==============="
3234
3235 test_31j() {
3236         test_mkdir -c1 -p $DIR/$tdir
3237         test_mkdir -c1 -p $DIR/$tdir/dir1
3238         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3239         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3240         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3241         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3242         return 0
3243 }
3244 run_test 31j "link for directory==============="
3245
3246 test_31k() {
3247         test_mkdir -c1 -p $DIR/$tdir
3248         touch $DIR/$tdir/s
3249         touch $DIR/$tdir/exist
3250         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3251         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3252         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3253         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3254         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3255         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3256         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3257         return 0
3258 }
3259 run_test 31k "link to file: the same, non-existing, dir==============="
3260
3261 test_31m() {
3262         mkdir $DIR/d31m
3263         touch $DIR/d31m/s
3264         mkdir $DIR/d31m2
3265         touch $DIR/d31m2/exist
3266         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3267         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3268         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3269         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3270         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3271         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3272         return 0
3273 }
3274 run_test 31m "link to file: the same, non-existing, dir==============="
3275
3276 test_31n() {
3277         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3278         nlink=$(stat --format=%h $DIR/$tfile)
3279         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3280         local fd=$(free_fd)
3281         local cmd="exec $fd<$DIR/$tfile"
3282         eval $cmd
3283         cmd="exec $fd<&-"
3284         trap "eval $cmd" EXIT
3285         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3286         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3287         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3288         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3289         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3290         eval $cmd
3291 }
3292 run_test 31n "check link count of unlinked file"
3293
3294 link_one() {
3295         local tempfile=$(mktemp $1_XXXXXX)
3296         mlink $tempfile $1 2> /dev/null &&
3297                 echo "$BASHPID: link $tempfile to $1 succeeded"
3298         munlink $tempfile
3299 }
3300
3301 test_31o() { # LU-2901
3302         test_mkdir $DIR/$tdir
3303         for LOOP in $(seq 100); do
3304                 rm -f $DIR/$tdir/$tfile*
3305                 for THREAD in $(seq 8); do
3306                         link_one $DIR/$tdir/$tfile.$LOOP &
3307                 done
3308                 wait
3309                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3310                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3311                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3312                         break || true
3313         done
3314 }
3315 run_test 31o "duplicate hard links with same filename"
3316
3317 test_31p() {
3318         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3319
3320         test_mkdir $DIR/$tdir
3321         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3322         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3323
3324         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3325                 error "open unlink test1 failed"
3326         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3327                 error "open unlink test2 failed"
3328
3329         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3330                 error "test1 still exists"
3331         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3332                 error "test2 still exists"
3333 }
3334 run_test 31p "remove of open striped directory"
3335
3336 cleanup_test32_mount() {
3337         local rc=0
3338         trap 0
3339         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3340         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3341         losetup -d $loopdev || true
3342         rm -rf $DIR/$tdir
3343         return $rc
3344 }
3345
3346 test_32a() {
3347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3348
3349         echo "== more mountpoints and symlinks ================="
3350         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3351         trap cleanup_test32_mount EXIT
3352         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3353         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3354                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3355         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3356                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3357         cleanup_test32_mount
3358 }
3359 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3360
3361 test_32b() {
3362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3363
3364         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3365         trap cleanup_test32_mount EXIT
3366         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3367         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3368                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3369         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3370                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3371         cleanup_test32_mount
3372 }
3373 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3374
3375 test_32c() {
3376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3377
3378         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3379         trap cleanup_test32_mount EXIT
3380         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3381         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3382                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3383         test_mkdir -p $DIR/$tdir/d2/test_dir
3384         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3385                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3386         cleanup_test32_mount
3387 }
3388 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3389
3390 test_32d() {
3391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3392
3393         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3394         trap cleanup_test32_mount EXIT
3395         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3396         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3397                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3398         test_mkdir -p $DIR/$tdir/d2/test_dir
3399         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3400                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3401         cleanup_test32_mount
3402 }
3403 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3404
3405 test_32e() {
3406         rm -fr $DIR/$tdir
3407         test_mkdir -p $DIR/$tdir/tmp
3408         local tmp_dir=$DIR/$tdir/tmp
3409         ln -s $DIR/$tdir $tmp_dir/symlink11
3410         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3411         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3412         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3413 }
3414 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3415
3416 test_32f() {
3417         rm -fr $DIR/$tdir
3418         test_mkdir -p $DIR/$tdir/tmp
3419         local tmp_dir=$DIR/$tdir/tmp
3420         ln -s $DIR/$tdir $tmp_dir/symlink11
3421         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3422         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3423         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3424 }
3425 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3426
3427 test_32g() {
3428         local tmp_dir=$DIR/$tdir/tmp
3429         test_mkdir -p $tmp_dir
3430         test_mkdir $DIR/${tdir}2
3431         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3432         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3433         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3434         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3435         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3436         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3437 }
3438 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3439
3440 test_32h() {
3441         rm -fr $DIR/$tdir $DIR/${tdir}2
3442         tmp_dir=$DIR/$tdir/tmp
3443         test_mkdir -p $tmp_dir
3444         test_mkdir $DIR/${tdir}2
3445         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3446         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3447         ls $tmp_dir/symlink12 || error "listing symlink12"
3448         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3449 }
3450 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3451
3452 test_32i() {
3453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3454
3455         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3456         trap cleanup_test32_mount EXIT
3457         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3458         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3459                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3460         touch $DIR/$tdir/test_file
3461         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3462                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3463         cleanup_test32_mount
3464 }
3465 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3466
3467 test_32j() {
3468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3469
3470         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3471         trap cleanup_test32_mount EXIT
3472         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3473         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3474                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3475         touch $DIR/$tdir/test_file
3476         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3477                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3478         cleanup_test32_mount
3479 }
3480 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3481
3482 test_32k() {
3483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3484
3485         rm -fr $DIR/$tdir
3486         trap cleanup_test32_mount EXIT
3487         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3488         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3489                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3490         test_mkdir -p $DIR/$tdir/d2
3491         touch $DIR/$tdir/d2/test_file || error "touch failed"
3492         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3493                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3494         cleanup_test32_mount
3495 }
3496 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3497
3498 test_32l() {
3499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3500
3501         rm -fr $DIR/$tdir
3502         trap cleanup_test32_mount EXIT
3503         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3504         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3505                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3506         test_mkdir -p $DIR/$tdir/d2
3507         touch $DIR/$tdir/d2/test_file || error "touch failed"
3508         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3509                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3510         cleanup_test32_mount
3511 }
3512 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3513
3514 test_32m() {
3515         rm -fr $DIR/d32m
3516         test_mkdir -p $DIR/d32m/tmp
3517         TMP_DIR=$DIR/d32m/tmp
3518         ln -s $DIR $TMP_DIR/symlink11
3519         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3520         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3521                 error "symlink11 not a link"
3522         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3523                 error "symlink01 not a link"
3524 }
3525 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3526
3527 test_32n() {
3528         rm -fr $DIR/d32n
3529         test_mkdir -p $DIR/d32n/tmp
3530         TMP_DIR=$DIR/d32n/tmp
3531         ln -s $DIR $TMP_DIR/symlink11
3532         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3533         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3534         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3535 }
3536 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3537
3538 test_32o() {
3539         touch $DIR/$tfile
3540         test_mkdir -p $DIR/d32o/tmp
3541         TMP_DIR=$DIR/d32o/tmp
3542         ln -s $DIR/$tfile $TMP_DIR/symlink12
3543         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3544         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3545                 error "symlink12 not a link"
3546         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3547         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3548                 error "$DIR/d32o/tmp/symlink12 not file type"
3549         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3550                 error "$DIR/d32o/symlink02 not file type"
3551 }
3552 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3553
3554 test_32p() {
3555         log 32p_1
3556         rm -fr $DIR/d32p
3557         log 32p_2
3558         rm -f $DIR/$tfile
3559         log 32p_3
3560         touch $DIR/$tfile
3561         log 32p_4
3562         test_mkdir -p $DIR/d32p/tmp
3563         log 32p_5
3564         TMP_DIR=$DIR/d32p/tmp
3565         log 32p_6
3566         ln -s $DIR/$tfile $TMP_DIR/symlink12
3567         log 32p_7
3568         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3569         log 32p_8
3570         cat $DIR/d32p/tmp/symlink12 ||
3571                 error "Can't open $DIR/d32p/tmp/symlink12"
3572         log 32p_9
3573         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3574         log 32p_10
3575 }
3576 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3577
3578 test_32q() {
3579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3580
3581         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3582         trap cleanup_test32_mount EXIT
3583         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3584         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3585         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3586                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3587         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3588         cleanup_test32_mount
3589 }
3590 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3591
3592 test_32r() {
3593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3594
3595         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3596         trap cleanup_test32_mount EXIT
3597         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3598         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3599         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3600                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3601         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3602         cleanup_test32_mount
3603 }
3604 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3605
3606 test_33aa() {
3607         rm -f $DIR/$tfile
3608         touch $DIR/$tfile
3609         chmod 444 $DIR/$tfile
3610         chown $RUNAS_ID $DIR/$tfile
3611         log 33_1
3612         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3613         log 33_2
3614 }
3615 run_test 33aa "write file with mode 444 (should return error)"
3616
3617 test_33a() {
3618         rm -fr $DIR/$tdir
3619         test_mkdir $DIR/$tdir
3620         chown $RUNAS_ID $DIR/$tdir
3621         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3622                 error "$RUNAS create $tdir/$tfile failed"
3623         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3624                 error "open RDWR" || true
3625 }
3626 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3627
3628 test_33b() {
3629         rm -fr $DIR/$tdir
3630         test_mkdir $DIR/$tdir
3631         chown $RUNAS_ID $DIR/$tdir
3632         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3633 }
3634 run_test 33b "test open file with malformed flags (No panic)"
3635
3636 test_33c() {
3637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3638         remote_ost_nodsh && skip "remote OST with nodsh"
3639
3640         local ostnum
3641         local ostname
3642         local write_bytes
3643         local all_zeros
3644
3645         all_zeros=:
3646         rm -fr $DIR/$tdir
3647         test_mkdir $DIR/$tdir
3648         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3649
3650         sync
3651         for ostnum in $(seq $OSTCOUNT); do
3652                 # test-framework's OST numbering is one-based, while Lustre's
3653                 # is zero-based
3654                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3655                 # Parsing llobdstat's output sucks; we could grep the /proc
3656                 # path, but that's likely to not be as portable as using the
3657                 # llobdstat utility.  So we parse lctl output instead.
3658                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3659                         obdfilter/$ostname/stats |
3660                         awk '/^write_bytes/ {print $7}' )
3661                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3662                 if (( ${write_bytes:-0} > 0 ))
3663                 then
3664                         all_zeros=false
3665                         break;
3666                 fi
3667         done
3668
3669         $all_zeros || return 0
3670
3671         # Write four bytes
3672         echo foo > $DIR/$tdir/bar
3673         # Really write them
3674         sync
3675
3676         # Total up write_bytes after writing.  We'd better find non-zeros.
3677         for ostnum in $(seq $OSTCOUNT); do
3678                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3679                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3680                         obdfilter/$ostname/stats |
3681                         awk '/^write_bytes/ {print $7}' )
3682                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3683                 if (( ${write_bytes:-0} > 0 ))
3684                 then
3685                         all_zeros=false
3686                         break;
3687                 fi
3688         done
3689
3690         if $all_zeros
3691         then
3692                 for ostnum in $(seq $OSTCOUNT); do
3693                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3694                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3695                         do_facet ost$ostnum lctl get_param -n \
3696                                 obdfilter/$ostname/stats
3697                 done
3698                 error "OST not keeping write_bytes stats (b22312)"
3699         fi
3700 }
3701 run_test 33c "test llobdstat and write_bytes"
3702
3703 test_33d() {
3704         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3706
3707         local MDTIDX=1
3708         local remote_dir=$DIR/$tdir/remote_dir
3709
3710         test_mkdir $DIR/$tdir
3711         $LFS mkdir -i $MDTIDX $remote_dir ||
3712                 error "create remote directory failed"
3713
3714         touch $remote_dir/$tfile
3715         chmod 444 $remote_dir/$tfile
3716         chown $RUNAS_ID $remote_dir/$tfile
3717
3718         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3719
3720         chown $RUNAS_ID $remote_dir
3721         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3722                                         error "create" || true
3723         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3724                                     error "open RDWR" || true
3725         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3726 }
3727 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3728
3729 test_33e() {
3730         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3731
3732         mkdir $DIR/$tdir
3733
3734         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3735         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3736         mkdir $DIR/$tdir/local_dir
3737
3738         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3739         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3740         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3741
3742         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3743                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3744
3745         rmdir $DIR/$tdir/* || error "rmdir failed"
3746
3747         umask 777
3748         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3749         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3750         mkdir $DIR/$tdir/local_dir
3751
3752         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3753         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3754         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3755
3756         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3757                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3758
3759         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3760
3761         umask 000
3762         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3763         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3764         mkdir $DIR/$tdir/local_dir
3765
3766         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3767         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3768         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3769
3770         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3771                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3772 }
3773 run_test 33e "mkdir and striped directory should have same mode"
3774
3775 cleanup_33f() {
3776         trap 0
3777         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3778 }
3779
3780 test_33f() {
3781         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3782         remote_mds_nodsh && skip "remote MDS with nodsh"
3783
3784         mkdir $DIR/$tdir
3785         chmod go+rwx $DIR/$tdir
3786         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3787         trap cleanup_33f EXIT
3788
3789         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3790                 error "cannot create striped directory"
3791
3792         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3793                 error "cannot create files in striped directory"
3794
3795         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3796                 error "cannot remove files in striped directory"
3797
3798         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3799                 error "cannot remove striped directory"
3800
3801         cleanup_33f
3802 }
3803 run_test 33f "nonroot user can create, access, and remove a striped directory"
3804
3805 test_33g() {
3806         mkdir -p $DIR/$tdir/dir2
3807
3808         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3809         echo $err
3810         [[ $err =~ "exists" ]] || error "Not exists error"
3811 }
3812 run_test 33g "nonroot user create already existing root created file"
3813
3814 test_33h() {
3815         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3816         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3817                 skip "Need MDS version at least 2.13.50"
3818
3819         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3820                 error "mkdir $tdir failed"
3821         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3822
3823         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3824         local index2
3825
3826         for fname in $DIR/$tdir/$tfile.bak \
3827                      $DIR/$tdir/$tfile.SAV \
3828                      $DIR/$tdir/$tfile.orig \
3829                      $DIR/$tdir/$tfile~; do
3830                 touch $fname  || error "touch $fname failed"
3831                 index2=$($LFS getstripe -m $fname)
3832                 [ $index -eq $index2 ] ||
3833                         error "$fname MDT index mismatch $index != $index2"
3834         done
3835
3836         local failed=0
3837         for i in {1..250}; do
3838                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3839                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3840                         touch $fname  || error "touch $fname failed"
3841                         index2=$($LFS getstripe -m $fname)
3842                         if [[ $index != $index2 ]]; then
3843                                 failed=$((failed + 1))
3844                                 echo "$fname MDT index mismatch $index != $index2"
3845                         fi
3846                 done
3847         done
3848         echo "$failed MDT index mismatches"
3849         (( failed < 20 )) || error "MDT index mismatch $failed times"
3850
3851 }
3852 run_test 33h "temp file is located on the same MDT as target"
3853
3854 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3855 test_34a() {
3856         rm -f $DIR/f34
3857         $MCREATE $DIR/f34 || error "mcreate failed"
3858         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3859                 error "getstripe failed"
3860         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3861         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3862                 error "getstripe failed"
3863         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3864                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3865 }
3866 run_test 34a "truncate file that has not been opened ==========="
3867
3868 test_34b() {
3869         [ ! -f $DIR/f34 ] && test_34a
3870         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3871                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3872         $OPENFILE -f O_RDONLY $DIR/f34
3873         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3874                 error "getstripe failed"
3875         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3876                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3877 }
3878 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3879
3880 test_34c() {
3881         [ ! -f $DIR/f34 ] && test_34a
3882         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3883                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3884         $OPENFILE -f O_RDWR $DIR/f34
3885         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3886                 error "$LFS getstripe failed"
3887         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3888                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3889 }
3890 run_test 34c "O_RDWR opening file-with-size works =============="
3891
3892 test_34d() {
3893         [ ! -f $DIR/f34 ] && test_34a
3894         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3895                 error "dd failed"
3896         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3897                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3898         rm $DIR/f34
3899 }
3900 run_test 34d "write to sparse file ============================="
3901
3902 test_34e() {
3903         rm -f $DIR/f34e
3904         $MCREATE $DIR/f34e || error "mcreate failed"
3905         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3906         $CHECKSTAT -s 1000 $DIR/f34e ||
3907                 error "Size of $DIR/f34e not equal to 1000 bytes"
3908         $OPENFILE -f O_RDWR $DIR/f34e
3909         $CHECKSTAT -s 1000 $DIR/f34e ||
3910                 error "Size of $DIR/f34e not equal to 1000 bytes"
3911 }
3912 run_test 34e "create objects, some with size and some without =="
3913
3914 test_34f() { # bug 6242, 6243
3915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3916
3917         SIZE34F=48000
3918         rm -f $DIR/f34f
3919         $MCREATE $DIR/f34f || error "mcreate failed"
3920         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3921         dd if=$DIR/f34f of=$TMP/f34f
3922         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3923         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3924         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3925         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3926         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3927 }
3928 run_test 34f "read from a file with no objects until EOF ======="
3929
3930 test_34g() {
3931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3932
3933         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3934                 error "dd failed"
3935         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3936         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3937                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3938         cancel_lru_locks osc
3939         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3940                 error "wrong size after lock cancel"
3941
3942         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3943         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3944                 error "expanding truncate failed"
3945         cancel_lru_locks osc
3946         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3947                 error "wrong expanded size after lock cancel"
3948 }
3949 run_test 34g "truncate long file ==============================="
3950
3951 test_34h() {
3952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3953
3954         local gid=10
3955         local sz=1000
3956
3957         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3958         sync # Flush the cache so that multiop below does not block on cache
3959              # flush when getting the group lock
3960         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3961         MULTIPID=$!
3962
3963         # Since just timed wait is not good enough, let's do a sync write
3964         # that way we are sure enough time for a roundtrip + processing
3965         # passed + 2 seconds of extra margin.
3966         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3967         rm $DIR/${tfile}-1
3968         sleep 2
3969
3970         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3971                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3972                 kill -9 $MULTIPID
3973         fi
3974         wait $MULTIPID
3975         local nsz=`stat -c %s $DIR/$tfile`
3976         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3977 }
3978 run_test 34h "ftruncate file under grouplock should not block"
3979
3980 test_35a() {
3981         cp /bin/sh $DIR/f35a
3982         chmod 444 $DIR/f35a
3983         chown $RUNAS_ID $DIR/f35a
3984         $RUNAS $DIR/f35a && error || true
3985         rm $DIR/f35a
3986 }
3987 run_test 35a "exec file with mode 444 (should return and not leak)"
3988
3989 test_36a() {
3990         rm -f $DIR/f36
3991         utime $DIR/f36 || error "utime failed for MDS"
3992 }
3993 run_test 36a "MDS utime check (mknod, utime)"
3994
3995 test_36b() {
3996         echo "" > $DIR/f36
3997         utime $DIR/f36 || error "utime failed for OST"
3998 }
3999 run_test 36b "OST utime check (open, utime)"
4000
4001 test_36c() {
4002         rm -f $DIR/d36/f36
4003         test_mkdir $DIR/d36
4004         chown $RUNAS_ID $DIR/d36
4005         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4006 }
4007 run_test 36c "non-root MDS utime check (mknod, utime)"
4008
4009 test_36d() {
4010         [ ! -d $DIR/d36 ] && test_36c
4011         echo "" > $DIR/d36/f36
4012         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4013 }
4014 run_test 36d "non-root OST utime check (open, utime)"
4015
4016 test_36e() {
4017         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4018
4019         test_mkdir $DIR/$tdir
4020         touch $DIR/$tdir/$tfile
4021         $RUNAS utime $DIR/$tdir/$tfile &&
4022                 error "utime worked, expected failure" || true
4023 }
4024 run_test 36e "utime on non-owned file (should return error)"
4025
4026 subr_36fh() {
4027         local fl="$1"
4028         local LANG_SAVE=$LANG
4029         local LC_LANG_SAVE=$LC_LANG
4030         export LANG=C LC_LANG=C # for date language
4031
4032         DATESTR="Dec 20  2000"
4033         test_mkdir $DIR/$tdir
4034         lctl set_param fail_loc=$fl
4035         date; date +%s
4036         cp /etc/hosts $DIR/$tdir/$tfile
4037         sync & # write RPC generated with "current" inode timestamp, but delayed
4038         sleep 1
4039         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4040         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4041         cancel_lru_locks $OSC
4042         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4043         date; date +%s
4044         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4045                 echo "BEFORE: $LS_BEFORE" && \
4046                 echo "AFTER : $LS_AFTER" && \
4047                 echo "WANT  : $DATESTR" && \
4048                 error "$DIR/$tdir/$tfile timestamps changed" || true
4049
4050         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4051 }
4052
4053 test_36f() {
4054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4055
4056         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4057         subr_36fh "0x80000214"
4058 }
4059 run_test 36f "utime on file racing with OST BRW write =========="
4060
4061 test_36g() {
4062         remote_ost_nodsh && skip "remote OST with nodsh"
4063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4064         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4065                 skip "Need MDS version at least 2.12.51"
4066
4067         local fmd_max_age
4068         local fmd
4069         local facet="ost1"
4070         local tgt="obdfilter"
4071
4072         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4073
4074         test_mkdir $DIR/$tdir
4075         fmd_max_age=$(do_facet $facet \
4076                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4077                 head -n 1")
4078
4079         echo "FMD max age: ${fmd_max_age}s"
4080         touch $DIR/$tdir/$tfile
4081         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4082                 gawk '{cnt=cnt+$1}  END{print cnt}')
4083         echo "FMD before: $fmd"
4084         [[ $fmd == 0 ]] &&
4085                 error "FMD wasn't create by touch"
4086         sleep $((fmd_max_age + 12))
4087         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4088                 gawk '{cnt=cnt+$1}  END{print cnt}')
4089         echo "FMD after: $fmd"
4090         [[ $fmd == 0 ]] ||
4091                 error "FMD wasn't expired by ping"
4092 }
4093 run_test 36g "FMD cache expiry ====================="
4094
4095 test_36h() {
4096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4097
4098         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4099         subr_36fh "0x80000227"
4100 }
4101 run_test 36h "utime on file racing with OST BRW write =========="
4102
4103 test_36i() {
4104         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4105
4106         test_mkdir $DIR/$tdir
4107         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4108
4109         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4110         local new_mtime=$((mtime + 200))
4111
4112         #change Modify time of striped dir
4113         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4114                         error "change mtime failed"
4115
4116         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4117
4118         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4119 }
4120 run_test 36i "change mtime on striped directory"
4121
4122 # test_37 - duplicate with tests 32q 32r
4123
4124 test_38() {
4125         local file=$DIR/$tfile
4126         touch $file
4127         openfile -f O_DIRECTORY $file
4128         local RC=$?
4129         local ENOTDIR=20
4130         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4131         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4132 }
4133 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4134
4135 test_39a() { # was test_39
4136         touch $DIR/$tfile
4137         touch $DIR/${tfile}2
4138 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4139 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4140 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4141         sleep 2
4142         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4143         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4144                 echo "mtime"
4145                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4146                 echo "atime"
4147                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4148                 echo "ctime"
4149                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4150                 error "O_TRUNC didn't change timestamps"
4151         fi
4152 }
4153 run_test 39a "mtime changed on create"
4154
4155 test_39b() {
4156         test_mkdir -c1 $DIR/$tdir
4157         cp -p /etc/passwd $DIR/$tdir/fopen
4158         cp -p /etc/passwd $DIR/$tdir/flink
4159         cp -p /etc/passwd $DIR/$tdir/funlink
4160         cp -p /etc/passwd $DIR/$tdir/frename
4161         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4162
4163         sleep 1
4164         echo "aaaaaa" >> $DIR/$tdir/fopen
4165         echo "aaaaaa" >> $DIR/$tdir/flink
4166         echo "aaaaaa" >> $DIR/$tdir/funlink
4167         echo "aaaaaa" >> $DIR/$tdir/frename
4168
4169         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4170         local link_new=`stat -c %Y $DIR/$tdir/flink`
4171         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4172         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4173
4174         cat $DIR/$tdir/fopen > /dev/null
4175         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4176         rm -f $DIR/$tdir/funlink2
4177         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4178
4179         for (( i=0; i < 2; i++ )) ; do
4180                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4181                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4182                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4183                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4184
4185                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4186                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4187                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4188                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4189
4190                 cancel_lru_locks $OSC
4191                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4192         done
4193 }
4194 run_test 39b "mtime change on open, link, unlink, rename  ======"
4195
4196 # this should be set to past
4197 TEST_39_MTIME=`date -d "1 year ago" +%s`
4198
4199 # bug 11063
4200 test_39c() {
4201         touch $DIR1/$tfile
4202         sleep 2
4203         local mtime0=`stat -c %Y $DIR1/$tfile`
4204
4205         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4206         local mtime1=`stat -c %Y $DIR1/$tfile`
4207         [ "$mtime1" = $TEST_39_MTIME ] || \
4208                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4209
4210         local d1=`date +%s`
4211         echo hello >> $DIR1/$tfile
4212         local d2=`date +%s`
4213         local mtime2=`stat -c %Y $DIR1/$tfile`
4214         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4215                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4216
4217         mv $DIR1/$tfile $DIR1/$tfile-1
4218
4219         for (( i=0; i < 2; i++ )) ; do
4220                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4221                 [ "$mtime2" = "$mtime3" ] || \
4222                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4223
4224                 cancel_lru_locks $OSC
4225                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4226         done
4227 }
4228 run_test 39c "mtime change on rename ==========================="
4229
4230 # bug 21114
4231 test_39d() {
4232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4233
4234         touch $DIR1/$tfile
4235         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4236
4237         for (( i=0; i < 2; i++ )) ; do
4238                 local mtime=`stat -c %Y $DIR1/$tfile`
4239                 [ $mtime = $TEST_39_MTIME ] || \
4240                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4241
4242                 cancel_lru_locks $OSC
4243                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4244         done
4245 }
4246 run_test 39d "create, utime, stat =============================="
4247
4248 # bug 21114
4249 test_39e() {
4250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4251
4252         touch $DIR1/$tfile
4253         local mtime1=`stat -c %Y $DIR1/$tfile`
4254
4255         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4256
4257         for (( i=0; i < 2; i++ )) ; do
4258                 local mtime2=`stat -c %Y $DIR1/$tfile`
4259                 [ $mtime2 = $TEST_39_MTIME ] || \
4260                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4261
4262                 cancel_lru_locks $OSC
4263                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4264         done
4265 }
4266 run_test 39e "create, stat, utime, stat ========================"
4267
4268 # bug 21114
4269 test_39f() {
4270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4271
4272         touch $DIR1/$tfile
4273         mtime1=`stat -c %Y $DIR1/$tfile`
4274
4275         sleep 2
4276         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4277
4278         for (( i=0; i < 2; i++ )) ; do
4279                 local mtime2=`stat -c %Y $DIR1/$tfile`
4280                 [ $mtime2 = $TEST_39_MTIME ] || \
4281                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4282
4283                 cancel_lru_locks $OSC
4284                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4285         done
4286 }
4287 run_test 39f "create, stat, sleep, utime, stat ================="
4288
4289 # bug 11063
4290 test_39g() {
4291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4292
4293         echo hello >> $DIR1/$tfile
4294         local mtime1=`stat -c %Y $DIR1/$tfile`
4295
4296         sleep 2
4297         chmod o+r $DIR1/$tfile
4298
4299         for (( i=0; i < 2; i++ )) ; do
4300                 local mtime2=`stat -c %Y $DIR1/$tfile`
4301                 [ "$mtime1" = "$mtime2" ] || \
4302                         error "lost mtime: $mtime2, should be $mtime1"
4303
4304                 cancel_lru_locks $OSC
4305                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4306         done
4307 }
4308 run_test 39g "write, chmod, stat ==============================="
4309
4310 # bug 11063
4311 test_39h() {
4312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4313
4314         touch $DIR1/$tfile
4315         sleep 1
4316
4317         local d1=`date`
4318         echo hello >> $DIR1/$tfile
4319         local mtime1=`stat -c %Y $DIR1/$tfile`
4320
4321         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4322         local d2=`date`
4323         if [ "$d1" != "$d2" ]; then
4324                 echo "write and touch not within one second"
4325         else
4326                 for (( i=0; i < 2; i++ )) ; do
4327                         local mtime2=`stat -c %Y $DIR1/$tfile`
4328                         [ "$mtime2" = $TEST_39_MTIME ] || \
4329                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4330
4331                         cancel_lru_locks $OSC
4332                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4333                 done
4334         fi
4335 }
4336 run_test 39h "write, utime within one second, stat ============="
4337
4338 test_39i() {
4339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4340
4341         touch $DIR1/$tfile
4342         sleep 1
4343
4344         echo hello >> $DIR1/$tfile
4345         local mtime1=`stat -c %Y $DIR1/$tfile`
4346
4347         mv $DIR1/$tfile $DIR1/$tfile-1
4348
4349         for (( i=0; i < 2; i++ )) ; do
4350                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4351
4352                 [ "$mtime1" = "$mtime2" ] || \
4353                         error "lost mtime: $mtime2, should be $mtime1"
4354
4355                 cancel_lru_locks $OSC
4356                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4357         done
4358 }
4359 run_test 39i "write, rename, stat =============================="
4360
4361 test_39j() {
4362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4363
4364         start_full_debug_logging
4365         touch $DIR1/$tfile
4366         sleep 1
4367
4368         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4369         lctl set_param fail_loc=0x80000412
4370         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4371                 error "multiop failed"
4372         local multipid=$!
4373         local mtime1=`stat -c %Y $DIR1/$tfile`
4374
4375         mv $DIR1/$tfile $DIR1/$tfile-1
4376
4377         kill -USR1 $multipid
4378         wait $multipid || error "multiop close failed"
4379
4380         for (( i=0; i < 2; i++ )) ; do
4381                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4382                 [ "$mtime1" = "$mtime2" ] ||
4383                         error "mtime is lost on close: $mtime2, " \
4384                               "should be $mtime1"
4385
4386                 cancel_lru_locks
4387                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4388         done
4389         lctl set_param fail_loc=0
4390         stop_full_debug_logging
4391 }
4392 run_test 39j "write, rename, close, stat ======================="
4393
4394 test_39k() {
4395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4396
4397         touch $DIR1/$tfile
4398         sleep 1
4399
4400         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4401         local multipid=$!
4402         local mtime1=`stat -c %Y $DIR1/$tfile`
4403
4404         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4405
4406         kill -USR1 $multipid
4407         wait $multipid || error "multiop close failed"
4408
4409         for (( i=0; i < 2; i++ )) ; do
4410                 local mtime2=`stat -c %Y $DIR1/$tfile`
4411
4412                 [ "$mtime2" = $TEST_39_MTIME ] || \
4413                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4414
4415                 cancel_lru_locks
4416                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4417         done
4418 }
4419 run_test 39k "write, utime, close, stat ========================"
4420
4421 # this should be set to future
4422 TEST_39_ATIME=`date -d "1 year" +%s`
4423
4424 test_39l() {
4425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4426         remote_mds_nodsh && skip "remote MDS with nodsh"
4427
4428         local atime_diff=$(do_facet $SINGLEMDS \
4429                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4430         rm -rf $DIR/$tdir
4431         mkdir -p $DIR/$tdir
4432
4433         # test setting directory atime to future
4434         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4435         local atime=$(stat -c %X $DIR/$tdir)
4436         [ "$atime" = $TEST_39_ATIME ] ||
4437                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4438
4439         # test setting directory atime from future to now
4440         local now=$(date +%s)
4441         touch -a -d @$now $DIR/$tdir
4442
4443         atime=$(stat -c %X $DIR/$tdir)
4444         [ "$atime" -eq "$now"  ] ||
4445                 error "atime is not updated from future: $atime, $now"
4446
4447         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4448         sleep 3
4449
4450         # test setting directory atime when now > dir atime + atime_diff
4451         local d1=$(date +%s)
4452         ls $DIR/$tdir
4453         local d2=$(date +%s)
4454         cancel_lru_locks mdc
4455         atime=$(stat -c %X $DIR/$tdir)
4456         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4457                 error "atime is not updated  : $atime, should be $d2"
4458
4459         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4460         sleep 3
4461
4462         # test not setting directory atime when now < dir atime + atime_diff
4463         ls $DIR/$tdir
4464         cancel_lru_locks mdc
4465         atime=$(stat -c %X $DIR/$tdir)
4466         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4467                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4468
4469         do_facet $SINGLEMDS \
4470                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4471 }
4472 run_test 39l "directory atime update ==========================="
4473
4474 test_39m() {
4475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4476
4477         touch $DIR1/$tfile
4478         sleep 2
4479         local far_past_mtime=$(date -d "May 29 1953" +%s)
4480         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4481
4482         touch -m -d @$far_past_mtime $DIR1/$tfile
4483         touch -a -d @$far_past_atime $DIR1/$tfile
4484
4485         for (( i=0; i < 2; i++ )) ; do
4486                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4487                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4488                         error "atime or mtime set incorrectly"
4489
4490                 cancel_lru_locks $OSC
4491                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4492         done
4493 }
4494 run_test 39m "test atime and mtime before 1970"
4495
4496 test_39n() { # LU-3832
4497         remote_mds_nodsh && skip "remote MDS with nodsh"
4498
4499         local atime_diff=$(do_facet $SINGLEMDS \
4500                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4501         local atime0
4502         local atime1
4503         local atime2
4504
4505         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4506
4507         rm -rf $DIR/$tfile
4508         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4509         atime0=$(stat -c %X $DIR/$tfile)
4510
4511         sleep 5
4512         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4513         atime1=$(stat -c %X $DIR/$tfile)
4514
4515         sleep 5
4516         cancel_lru_locks mdc
4517         cancel_lru_locks osc
4518         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4519         atime2=$(stat -c %X $DIR/$tfile)
4520
4521         do_facet $SINGLEMDS \
4522                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4523
4524         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4525         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4526 }
4527 run_test 39n "check that O_NOATIME is honored"
4528
4529 test_39o() {
4530         TESTDIR=$DIR/$tdir/$tfile
4531         [ -e $TESTDIR ] && rm -rf $TESTDIR
4532         mkdir -p $TESTDIR
4533         cd $TESTDIR
4534         links1=2
4535         ls
4536         mkdir a b
4537         ls
4538         links2=$(stat -c %h .)
4539         [ $(($links1 + 2)) != $links2 ] &&
4540                 error "wrong links count $(($links1 + 2)) != $links2"
4541         rmdir b
4542         links3=$(stat -c %h .)
4543         [ $(($links1 + 1)) != $links3 ] &&
4544                 error "wrong links count $links1 != $links3"
4545         return 0
4546 }
4547 run_test 39o "directory cached attributes updated after create"
4548
4549 test_39p() {
4550         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4551
4552         local MDTIDX=1
4553         TESTDIR=$DIR/$tdir/$tdir
4554         [ -e $TESTDIR ] && rm -rf $TESTDIR
4555         test_mkdir -p $TESTDIR
4556         cd $TESTDIR
4557         links1=2
4558         ls
4559         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4560         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4561         ls
4562         links2=$(stat -c %h .)
4563         [ $(($links1 + 2)) != $links2 ] &&
4564                 error "wrong links count $(($links1 + 2)) != $links2"
4565         rmdir remote_dir2
4566         links3=$(stat -c %h .)
4567         [ $(($links1 + 1)) != $links3 ] &&
4568                 error "wrong links count $links1 != $links3"
4569         return 0
4570 }
4571 run_test 39p "remote directory cached attributes updated after create ========"
4572
4573 test_39r() {
4574         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4575                 skip "no atime update on old OST"
4576         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4577                 skip_env "ldiskfs only test"
4578         fi
4579
4580         local saved_adiff
4581         saved_adiff=$(do_facet ost1 \
4582                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4583         stack_trap "do_facet ost1 \
4584                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4585
4586         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4587
4588         $LFS setstripe -i 0 $DIR/$tfile
4589         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4590                 error "can't write initial file"
4591         cancel_lru_locks osc
4592
4593         # exceed atime_diff and access file
4594         sleep 6
4595         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4596
4597         local atime_cli=$(stat -c %X $DIR/$tfile)
4598         echo "client atime: $atime_cli"
4599         # allow atime update to be written to device
4600         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4601         sleep 5
4602
4603         local ostdev=$(ostdevname 1)
4604         local fid=($(lfs getstripe -y $DIR/$tfile |
4605                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4606         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4607         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4608
4609         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4610         local atime_ost=$(do_facet ost1 "$cmd" |&
4611                           awk -F'[: ]' '/atime:/ { print $4 }')
4612         (( atime_cli == atime_ost )) ||
4613                 error "atime on client $atime_cli != ost $atime_ost"
4614 }
4615 run_test 39r "lazy atime update on OST"
4616
4617 test_39q() { # LU-8041
4618         local testdir=$DIR/$tdir
4619         mkdir -p $testdir
4620         multiop_bg_pause $testdir D_c || error "multiop failed"
4621         local multipid=$!
4622         cancel_lru_locks mdc
4623         kill -USR1 $multipid
4624         local atime=$(stat -c %X $testdir)
4625         [ "$atime" -ne 0 ] || error "atime is zero"
4626 }
4627 run_test 39q "close won't zero out atime"
4628
4629 test_40() {
4630         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4631         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4632                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4633         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4634                 error "$tfile is not 4096 bytes in size"
4635 }
4636 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4637
4638 test_41() {
4639         # bug 1553
4640         small_write $DIR/f41 18
4641 }
4642 run_test 41 "test small file write + fstat ====================="
4643
4644 count_ost_writes() {
4645         lctl get_param -n ${OSC}.*.stats |
4646                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4647                         END { printf("%0.0f", writes) }'
4648 }
4649
4650 # decent default
4651 WRITEBACK_SAVE=500
4652 DIRTY_RATIO_SAVE=40
4653 MAX_DIRTY_RATIO=50
4654 BG_DIRTY_RATIO_SAVE=10
4655 MAX_BG_DIRTY_RATIO=25
4656
4657 start_writeback() {
4658         trap 0
4659         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4660         # dirty_ratio, dirty_background_ratio
4661         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4662                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4663                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4664                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4665         else
4666                 # if file not here, we are a 2.4 kernel
4667                 kill -CONT `pidof kupdated`
4668         fi
4669 }
4670
4671 stop_writeback() {
4672         # setup the trap first, so someone cannot exit the test at the
4673         # exact wrong time and mess up a machine
4674         trap start_writeback EXIT
4675         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4676         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4677                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4678                 sysctl -w vm.dirty_writeback_centisecs=0
4679                 sysctl -w vm.dirty_writeback_centisecs=0
4680                 # save and increase /proc/sys/vm/dirty_ratio
4681                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4682                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4683                 # save and increase /proc/sys/vm/dirty_background_ratio
4684                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4685                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4686         else
4687                 # if file not here, we are a 2.4 kernel
4688                 kill -STOP `pidof kupdated`
4689         fi
4690 }
4691
4692 # ensure that all stripes have some grant before we test client-side cache
4693 setup_test42() {
4694         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4695                 dd if=/dev/zero of=$i bs=4k count=1
4696                 rm $i
4697         done
4698 }
4699
4700 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4701 # file truncation, and file removal.
4702 test_42a() {
4703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4704
4705         setup_test42
4706         cancel_lru_locks $OSC
4707         stop_writeback
4708         sync; sleep 1; sync # just to be safe
4709         BEFOREWRITES=`count_ost_writes`
4710         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4711         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4712         AFTERWRITES=`count_ost_writes`
4713         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4714                 error "$BEFOREWRITES < $AFTERWRITES"
4715         start_writeback
4716 }
4717 run_test 42a "ensure that we don't flush on close"
4718
4719 test_42b() {
4720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4721
4722         setup_test42
4723         cancel_lru_locks $OSC
4724         stop_writeback
4725         sync
4726         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4727         BEFOREWRITES=$(count_ost_writes)
4728         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4729         AFTERWRITES=$(count_ost_writes)
4730         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4731                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4732         fi
4733         BEFOREWRITES=$(count_ost_writes)
4734         sync || error "sync: $?"
4735         AFTERWRITES=$(count_ost_writes)
4736         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4737                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4738         fi
4739         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4740         start_writeback
4741         return 0
4742 }
4743 run_test 42b "test destroy of file with cached dirty data ======"
4744
4745 # if these tests just want to test the effect of truncation,
4746 # they have to be very careful.  consider:
4747 # - the first open gets a {0,EOF}PR lock
4748 # - the first write conflicts and gets a {0, count-1}PW
4749 # - the rest of the writes are under {count,EOF}PW
4750 # - the open for truncate tries to match a {0,EOF}PR
4751 #   for the filesize and cancels the PWs.
4752 # any number of fixes (don't get {0,EOF} on open, match
4753 # composite locks, do smarter file size management) fix
4754 # this, but for now we want these tests to verify that
4755 # the cancellation with truncate intent works, so we
4756 # start the file with a full-file pw lock to match against
4757 # until the truncate.
4758 trunc_test() {
4759         test=$1
4760         file=$DIR/$test
4761         offset=$2
4762         cancel_lru_locks $OSC
4763         stop_writeback
4764         # prime the file with 0,EOF PW to match
4765         touch $file
4766         $TRUNCATE $file 0
4767         sync; sync
4768         # now the real test..
4769         dd if=/dev/zero of=$file bs=1024 count=100
4770         BEFOREWRITES=`count_ost_writes`
4771         $TRUNCATE $file $offset
4772         cancel_lru_locks $OSC
4773         AFTERWRITES=`count_ost_writes`
4774         start_writeback
4775 }
4776
4777 test_42c() {
4778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4779
4780         trunc_test 42c 1024
4781         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4782                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4783         rm $file
4784 }
4785 run_test 42c "test partial truncate of file with cached dirty data"
4786
4787 test_42d() {
4788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4789
4790         trunc_test 42d 0
4791         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4792                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4793         rm $file
4794 }
4795 run_test 42d "test complete truncate of file with cached dirty data"
4796
4797 test_42e() { # bug22074
4798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4799
4800         local TDIR=$DIR/${tdir}e
4801         local pages=16 # hardcoded 16 pages, don't change it.
4802         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4803         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4804         local max_dirty_mb
4805         local warmup_files
4806
4807         test_mkdir $DIR/${tdir}e
4808         $LFS setstripe -c 1 $TDIR
4809         createmany -o $TDIR/f $files
4810
4811         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4812
4813         # we assume that with $OSTCOUNT files, at least one of them will
4814         # be allocated on OST0.
4815         warmup_files=$((OSTCOUNT * max_dirty_mb))
4816         createmany -o $TDIR/w $warmup_files
4817
4818         # write a large amount of data into one file and sync, to get good
4819         # avail_grant number from OST.
4820         for ((i=0; i<$warmup_files; i++)); do
4821                 idx=$($LFS getstripe -i $TDIR/w$i)
4822                 [ $idx -ne 0 ] && continue
4823                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4824                 break
4825         done
4826         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4827         sync
4828         $LCTL get_param $proc_osc0/cur_dirty_bytes
4829         $LCTL get_param $proc_osc0/cur_grant_bytes
4830
4831         # create as much dirty pages as we can while not to trigger the actual
4832         # RPCs directly. but depends on the env, VFS may trigger flush during this
4833         # period, hopefully we are good.
4834         for ((i=0; i<$warmup_files; i++)); do
4835                 idx=$($LFS getstripe -i $TDIR/w$i)
4836                 [ $idx -ne 0 ] && continue
4837                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4838         done
4839         $LCTL get_param $proc_osc0/cur_dirty_bytes
4840         $LCTL get_param $proc_osc0/cur_grant_bytes
4841
4842         # perform the real test
4843         $LCTL set_param $proc_osc0/rpc_stats 0
4844         for ((;i<$files; i++)); do
4845                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4846                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4847         done
4848         sync
4849         $LCTL get_param $proc_osc0/rpc_stats
4850
4851         local percent=0
4852         local have_ppr=false
4853         $LCTL get_param $proc_osc0/rpc_stats |
4854                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4855                         # skip lines until we are at the RPC histogram data
4856                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4857                         $have_ppr || continue
4858
4859                         # we only want the percent stat for < 16 pages
4860                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4861
4862                         percent=$((percent + WPCT))
4863                         if [[ $percent -gt 15 ]]; then
4864                                 error "less than 16-pages write RPCs" \
4865                                       "$percent% > 15%"
4866                                 break
4867                         fi
4868                 done
4869         rm -rf $TDIR
4870 }
4871 run_test 42e "verify sub-RPC writes are not done synchronously"
4872
4873 test_43A() { # was test_43
4874         test_mkdir $DIR/$tdir
4875         cp -p /bin/ls $DIR/$tdir/$tfile
4876         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4877         pid=$!
4878         # give multiop a chance to open
4879         sleep 1
4880
4881         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4882         kill -USR1 $pid
4883         # Wait for multiop to exit
4884         wait $pid
4885 }
4886 run_test 43A "execution of file opened for write should return -ETXTBSY"
4887
4888 test_43a() {
4889         test_mkdir $DIR/$tdir
4890         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4891         $DIR/$tdir/sleep 60 &
4892         SLEEP_PID=$!
4893         # Make sure exec of $tdir/sleep wins race with truncate
4894         sleep 1
4895         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4896         kill $SLEEP_PID
4897 }
4898 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4899
4900 test_43b() {
4901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4902
4903         test_mkdir $DIR/$tdir
4904         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4905         $DIR/$tdir/sleep 60 &
4906         SLEEP_PID=$!
4907         # Make sure exec of $tdir/sleep wins race with truncate
4908         sleep 1
4909         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4910         kill $SLEEP_PID
4911 }
4912 run_test 43b "truncate of file being executed should return -ETXTBSY"
4913
4914 test_43c() {
4915         local testdir="$DIR/$tdir"
4916         test_mkdir $testdir
4917         cp $SHELL $testdir/
4918         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4919                 ( cd $testdir && md5sum -c )
4920 }
4921 run_test 43c "md5sum of copy into lustre"
4922
4923 test_44A() { # was test_44
4924         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4925
4926         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4927         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4928 }
4929 run_test 44A "zero length read from a sparse stripe"
4930
4931 test_44a() {
4932         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4933                 awk '{ print $2 }')
4934         [ -z "$nstripe" ] && skip "can't get stripe info"
4935         [[ $nstripe -gt $OSTCOUNT ]] &&
4936                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4937
4938         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4939                 awk '{ print $2 }')
4940         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4941                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4942                         awk '{ print $2 }')
4943         fi
4944
4945         OFFSETS="0 $((stride/2)) $((stride-1))"
4946         for offset in $OFFSETS; do
4947                 for i in $(seq 0 $((nstripe-1))); do
4948                         local GLOBALOFFSETS=""
4949                         # size in Bytes
4950                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4951                         local myfn=$DIR/d44a-$size
4952                         echo "--------writing $myfn at $size"
4953                         ll_sparseness_write $myfn $size ||
4954                                 error "ll_sparseness_write"
4955                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4956                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4957                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4958
4959                         for j in $(seq 0 $((nstripe-1))); do
4960                                 # size in Bytes
4961                                 size=$((((j + $nstripe )*$stride + $offset)))
4962                                 ll_sparseness_write $myfn $size ||
4963                                         error "ll_sparseness_write"
4964                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4965                         done
4966                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4967                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4968                         rm -f $myfn
4969                 done
4970         done
4971 }
4972 run_test 44a "test sparse pwrite ==============================="
4973
4974 dirty_osc_total() {
4975         tot=0
4976         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4977                 tot=$(($tot + $d))
4978         done
4979         echo $tot
4980 }
4981 do_dirty_record() {
4982         before=`dirty_osc_total`
4983         echo executing "\"$*\""
4984         eval $*
4985         after=`dirty_osc_total`
4986         echo before $before, after $after
4987 }
4988 test_45() {
4989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4990
4991         f="$DIR/f45"
4992         # Obtain grants from OST if it supports it
4993         echo blah > ${f}_grant
4994         stop_writeback
4995         sync
4996         do_dirty_record "echo blah > $f"
4997         [[ $before -eq $after ]] && error "write wasn't cached"
4998         do_dirty_record "> $f"
4999         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5000         do_dirty_record "echo blah > $f"
5001         [[ $before -eq $after ]] && error "write wasn't cached"
5002         do_dirty_record "sync"
5003         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5004         do_dirty_record "echo blah > $f"
5005         [[ $before -eq $after ]] && error "write wasn't cached"
5006         do_dirty_record "cancel_lru_locks osc"
5007         [[ $before -gt $after ]] ||
5008                 error "lock cancellation didn't lower dirty count"
5009         start_writeback
5010 }
5011 run_test 45 "osc io page accounting ============================"
5012
5013 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5014 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5015 # objects offset and an assert hit when an rpc was built with 1023's mapped
5016 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5017 test_46() {
5018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5019
5020         f="$DIR/f46"
5021         stop_writeback
5022         sync
5023         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5024         sync
5025         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5026         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5027         sync
5028         start_writeback
5029 }
5030 run_test 46 "dirtying a previously written page ================"
5031
5032 # test_47 is removed "Device nodes check" is moved to test_28
5033
5034 test_48a() { # bug 2399
5035         [ "$mds1_FSTYPE" = "zfs" ] &&
5036         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5037                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5038
5039         test_mkdir $DIR/$tdir
5040         cd $DIR/$tdir
5041         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5042         test_mkdir $DIR/$tdir
5043         touch foo || error "'touch foo' failed after recreating cwd"
5044         test_mkdir bar
5045         touch .foo || error "'touch .foo' failed after recreating cwd"
5046         test_mkdir .bar
5047         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5048         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5049         cd . || error "'cd .' failed after recreating cwd"
5050         mkdir . && error "'mkdir .' worked after recreating cwd"
5051         rmdir . && error "'rmdir .' worked after recreating cwd"
5052         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5053         cd .. || error "'cd ..' failed after recreating cwd"
5054 }
5055 run_test 48a "Access renamed working dir (should return errors)="
5056
5057 test_48b() { # bug 2399
5058         rm -rf $DIR/$tdir
5059         test_mkdir $DIR/$tdir
5060         cd $DIR/$tdir
5061         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5062         touch foo && error "'touch foo' worked after removing cwd"
5063         mkdir foo && error "'mkdir foo' worked after removing cwd"
5064         touch .foo && error "'touch .foo' worked after removing cwd"
5065         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5066         ls . > /dev/null && error "'ls .' worked after removing cwd"
5067         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5068         mkdir . && error "'mkdir .' worked after removing cwd"
5069         rmdir . && error "'rmdir .' worked after removing cwd"
5070         ln -s . foo && error "'ln -s .' worked after removing cwd"
5071         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5072 }
5073 run_test 48b "Access removed working dir (should return errors)="
5074
5075 test_48c() { # bug 2350
5076         #lctl set_param debug=-1
5077         #set -vx
5078         rm -rf $DIR/$tdir
5079         test_mkdir -p $DIR/$tdir/dir
5080         cd $DIR/$tdir/dir
5081         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5082         $TRACE touch foo && error "touch foo worked after removing cwd"
5083         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5084         touch .foo && error "touch .foo worked after removing cwd"
5085         mkdir .foo && error "mkdir .foo worked after removing cwd"
5086         $TRACE ls . && error "'ls .' worked after removing cwd"
5087         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5088         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5089         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5090         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5091         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5092 }
5093 run_test 48c "Access removed working subdir (should return errors)"
5094
5095 test_48d() { # bug 2350
5096         #lctl set_param debug=-1
5097         #set -vx
5098         rm -rf $DIR/$tdir
5099         test_mkdir -p $DIR/$tdir/dir
5100         cd $DIR/$tdir/dir
5101         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5102         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5103         $TRACE touch foo && error "'touch foo' worked after removing parent"
5104         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5105         touch .foo && error "'touch .foo' worked after removing parent"
5106         mkdir .foo && error "mkdir .foo worked after removing parent"
5107         $TRACE ls . && error "'ls .' worked after removing parent"
5108         $TRACE ls .. && error "'ls ..' worked after removing parent"
5109         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5110         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5111         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5112         true
5113 }
5114 run_test 48d "Access removed parent subdir (should return errors)"
5115
5116 test_48e() { # bug 4134
5117         #lctl set_param debug=-1
5118         #set -vx
5119         rm -rf $DIR/$tdir
5120         test_mkdir -p $DIR/$tdir/dir
5121         cd $DIR/$tdir/dir
5122         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5123         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5124         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5125         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5126         # On a buggy kernel addition of "touch foo" after cd .. will
5127         # produce kernel oops in lookup_hash_it
5128         touch ../foo && error "'cd ..' worked after recreate parent"
5129         cd $DIR
5130         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5131 }
5132 run_test 48e "Access to recreated parent subdir (should return errors)"
5133
5134 test_48f() {
5135         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5136                 skip "need MDS >= 2.13.55"
5137         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5138         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5139                 skip "needs different host for mdt1 mdt2"
5140         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5141
5142         $LFS mkdir -i0 $DIR/$tdir
5143         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5144
5145         for d in sub1 sub2 sub3; do
5146                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5147                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5148                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5149         done
5150
5151         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5152 }
5153 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5154
5155 test_49() { # LU-1030
5156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5157         remote_ost_nodsh && skip "remote OST with nodsh"
5158
5159         # get ost1 size - $FSNAME-OST0000
5160         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5161                 awk '{ print $4 }')
5162         # write 800M at maximum
5163         [[ $ost1_size -lt 2 ]] && ost1_size=2
5164         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5165
5166         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5167         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5168         local dd_pid=$!
5169
5170         # change max_pages_per_rpc while writing the file
5171         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5172         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5173         # loop until dd process exits
5174         while ps ax -opid | grep -wq $dd_pid; do
5175                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5176                 sleep $((RANDOM % 5 + 1))
5177         done
5178         # restore original max_pages_per_rpc
5179         $LCTL set_param $osc1_mppc=$orig_mppc
5180         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5181 }
5182 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5183
5184 test_50() {
5185         # bug 1485
5186         test_mkdir $DIR/$tdir
5187         cd $DIR/$tdir
5188         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5189 }
5190 run_test 50 "special situations: /proc symlinks  ==============="
5191
5192 test_51a() {    # was test_51
5193         # bug 1516 - create an empty entry right after ".." then split dir
5194         test_mkdir -c1 $DIR/$tdir
5195         touch $DIR/$tdir/foo
5196         $MCREATE $DIR/$tdir/bar
5197         rm $DIR/$tdir/foo
5198         createmany -m $DIR/$tdir/longfile 201
5199         FNUM=202
5200         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5201                 $MCREATE $DIR/$tdir/longfile$FNUM
5202                 FNUM=$(($FNUM + 1))
5203                 echo -n "+"
5204         done
5205         echo
5206         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5207 }
5208 run_test 51a "special situations: split htree with empty entry =="
5209
5210 cleanup_print_lfs_df () {
5211         trap 0
5212         $LFS df
5213         $LFS df -i
5214 }
5215
5216 test_51b() {
5217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5218
5219         local dir=$DIR/$tdir
5220         local nrdirs=$((65536 + 100))
5221
5222         # cleanup the directory
5223         rm -fr $dir
5224
5225         test_mkdir -c1 $dir
5226
5227         $LFS df
5228         $LFS df -i
5229         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5230         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5231         [[ $numfree -lt $nrdirs ]] &&
5232                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5233
5234         # need to check free space for the directories as well
5235         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5236         numfree=$(( blkfree / $(fs_inode_ksize) ))
5237         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5238
5239         trap cleanup_print_lfs_df EXIT
5240
5241         # create files
5242         createmany -d $dir/d $nrdirs || {
5243                 unlinkmany $dir/d $nrdirs
5244                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5245         }
5246
5247         # really created :
5248         nrdirs=$(ls -U $dir | wc -l)
5249
5250         # unlink all but 100 subdirectories, then check it still works
5251         local left=100
5252         local delete=$((nrdirs - left))
5253
5254         $LFS df
5255         $LFS df -i
5256
5257         # for ldiskfs the nlink count should be 1, but this is OSD specific
5258         # and so this is listed for informational purposes only
5259         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5260         unlinkmany -d $dir/d $delete ||
5261                 error "unlink of first $delete subdirs failed"
5262
5263         echo "nlink between: $(stat -c %h $dir)"
5264         local found=$(ls -U $dir | wc -l)
5265         [ $found -ne $left ] &&
5266                 error "can't find subdirs: found only $found, expected $left"
5267
5268         unlinkmany -d $dir/d $delete $left ||
5269                 error "unlink of second $left subdirs failed"
5270         # regardless of whether the backing filesystem tracks nlink accurately
5271         # or not, the nlink count shouldn't be more than "." and ".." here
5272         local after=$(stat -c %h $dir)
5273         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5274                 echo "nlink after: $after"
5275
5276         cleanup_print_lfs_df
5277 }
5278 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5279
5280 test_51d() {
5281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5282         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5283
5284         test_mkdir $DIR/$tdir
5285         createmany -o $DIR/$tdir/t- 1000
5286         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5287         for N in $(seq 0 $((OSTCOUNT - 1))); do
5288                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5289                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5290                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5291                         '($1 == '$N') { objs += 1 } \
5292                         END { printf("%0.0f", objs) }')
5293                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5294         done
5295         unlinkmany $DIR/$tdir/t- 1000
5296
5297         NLAST=0
5298         for N in $(seq 1 $((OSTCOUNT - 1))); do
5299                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5300                         error "OST $N has less objects vs OST $NLAST" \
5301                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5302                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5303                         error "OST $N has less objects vs OST $NLAST" \
5304                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5305
5306                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5307                         error "OST $N has less #0 objects vs OST $NLAST" \
5308                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5309                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5310                         error "OST $N has less #0 objects vs OST $NLAST" \
5311                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5312                 NLAST=$N
5313         done
5314         rm -f $TMP/$tfile
5315 }
5316 run_test 51d "check object distribution"
5317
5318 test_51e() {
5319         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5320                 skip_env "ldiskfs only test"
5321         fi
5322
5323         test_mkdir -c1 $DIR/$tdir
5324         test_mkdir -c1 $DIR/$tdir/d0
5325
5326         touch $DIR/$tdir/d0/foo
5327         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5328                 error "file exceed 65000 nlink limit!"
5329         unlinkmany $DIR/$tdir/d0/f- 65001
5330         return 0
5331 }
5332 run_test 51e "check file nlink limit"
5333
5334 test_51f() {
5335         test_mkdir $DIR/$tdir
5336
5337         local max=100000
5338         local ulimit_old=$(ulimit -n)
5339         local spare=20 # number of spare fd's for scripts/libraries, etc.
5340         local mdt=$($LFS getstripe -m $DIR/$tdir)
5341         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5342
5343         echo "MDT$mdt numfree=$numfree, max=$max"
5344         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5345         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5346                 while ! ulimit -n $((numfree + spare)); do
5347                         numfree=$((numfree * 3 / 4))
5348                 done
5349                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5350         else
5351                 echo "left ulimit at $ulimit_old"
5352         fi
5353
5354         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5355                 unlinkmany $DIR/$tdir/f $numfree
5356                 error "create+open $numfree files in $DIR/$tdir failed"
5357         }
5358         ulimit -n $ulimit_old
5359
5360         # if createmany exits at 120s there will be fewer than $numfree files
5361         unlinkmany $DIR/$tdir/f $numfree || true
5362 }
5363 run_test 51f "check many open files limit"
5364
5365 test_52a() {
5366         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5367         test_mkdir $DIR/$tdir
5368         touch $DIR/$tdir/foo
5369         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5370         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5371         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5372         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5373         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5374                                         error "link worked"
5375         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5376         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5377         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5378                                                      error "lsattr"
5379         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5380         cp -r $DIR/$tdir $TMP/
5381         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5382 }
5383 run_test 52a "append-only flag test (should return errors)"
5384
5385 test_52b() {
5386         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5387         test_mkdir $DIR/$tdir
5388         touch $DIR/$tdir/foo
5389         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5390         cat test > $DIR/$tdir/foo && error "cat test worked"
5391         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5392         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5393         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5394                                         error "link worked"
5395         echo foo >> $DIR/$tdir/foo && error "echo worked"
5396         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5397         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5398         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5399         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5400                                                         error "lsattr"
5401         chattr -i $DIR/$tdir/foo || error "chattr failed"
5402
5403         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5404 }
5405 run_test 52b "immutable flag test (should return errors) ======="
5406
5407 test_53() {
5408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5409         remote_mds_nodsh && skip "remote MDS with nodsh"
5410         remote_ost_nodsh && skip "remote OST with nodsh"
5411
5412         local param
5413         local param_seq
5414         local ostname
5415         local mds_last
5416         local mds_last_seq
5417         local ost_last
5418         local ost_last_seq
5419         local ost_last_id
5420         local ostnum
5421         local node
5422         local found=false
5423         local support_last_seq=true
5424
5425         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5426                 support_last_seq=false
5427
5428         # only test MDT0000
5429         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5430         local value
5431         for value in $(do_facet $SINGLEMDS \
5432                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5433                 param=$(echo ${value[0]} | cut -d "=" -f1)
5434                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5435
5436                 if $support_last_seq; then
5437                         param_seq=$(echo $param |
5438                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5439                         mds_last_seq=$(do_facet $SINGLEMDS \
5440                                        $LCTL get_param -n $param_seq)
5441                 fi
5442                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5443
5444                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5445                 node=$(facet_active_host ost$((ostnum+1)))
5446                 param="obdfilter.$ostname.last_id"
5447                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5448                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5449                         ost_last_id=$ost_last
5450
5451                         if $support_last_seq; then
5452                                 ost_last_id=$(echo $ost_last |
5453                                               awk -F':' '{print $2}' |
5454                                               sed -e "s/^0x//g")
5455                                 ost_last_seq=$(echo $ost_last |
5456                                                awk -F':' '{print $1}')
5457                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5458                         fi
5459
5460                         if [[ $ost_last_id != $mds_last ]]; then
5461                                 error "$ost_last_id != $mds_last"
5462                         else
5463                                 found=true
5464                                 break
5465                         fi
5466                 done
5467         done
5468         $found || error "can not match last_seq/last_id for $mdtosc"
5469         return 0
5470 }
5471 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5472
5473 test_54a() {
5474         perl -MSocket -e ';' || skip "no Socket perl module installed"
5475
5476         $SOCKETSERVER $DIR/socket ||
5477                 error "$SOCKETSERVER $DIR/socket failed: $?"
5478         $SOCKETCLIENT $DIR/socket ||
5479                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5480         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5481 }
5482 run_test 54a "unix domain socket test =========================="
5483
5484 test_54b() {
5485         f="$DIR/f54b"
5486         mknod $f c 1 3
5487         chmod 0666 $f
5488         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5489 }
5490 run_test 54b "char device works in lustre ======================"
5491
5492 find_loop_dev() {
5493         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5494         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5495         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5496
5497         for i in $(seq 3 7); do
5498                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5499                 LOOPDEV=$LOOPBASE$i
5500                 LOOPNUM=$i
5501                 break
5502         done
5503 }
5504
5505 cleanup_54c() {
5506         local rc=0
5507         loopdev="$DIR/loop54c"
5508
5509         trap 0
5510         $UMOUNT $DIR/$tdir || rc=$?
5511         losetup -d $loopdev || true
5512         losetup -d $LOOPDEV || true
5513         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5514         return $rc
5515 }
5516
5517 test_54c() {
5518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5519
5520         loopdev="$DIR/loop54c"
5521
5522         find_loop_dev
5523         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5524         trap cleanup_54c EXIT
5525         mknod $loopdev b 7 $LOOPNUM
5526         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5527         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5528         losetup $loopdev $DIR/$tfile ||
5529                 error "can't set up $loopdev for $DIR/$tfile"
5530         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5531         test_mkdir $DIR/$tdir
5532         mount -t ext2 $loopdev $DIR/$tdir ||
5533                 error "error mounting $loopdev on $DIR/$tdir"
5534         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5535                 error "dd write"
5536         df $DIR/$tdir
5537         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5538                 error "dd read"
5539         cleanup_54c
5540 }
5541 run_test 54c "block device works in lustre ====================="
5542
5543 test_54d() {
5544         f="$DIR/f54d"
5545         string="aaaaaa"
5546         mknod $f p
5547         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5548 }
5549 run_test 54d "fifo device works in lustre ======================"
5550
5551 test_54e() {
5552         f="$DIR/f54e"
5553         string="aaaaaa"
5554         cp -aL /dev/console $f
5555         echo $string > $f || error "echo $string to $f failed"
5556 }
5557 run_test 54e "console/tty device works in lustre ======================"
5558
5559 test_56a() {
5560         local numfiles=3
5561         local dir=$DIR/$tdir
5562
5563         rm -rf $dir
5564         test_mkdir -p $dir/dir
5565         for i in $(seq $numfiles); do
5566                 touch $dir/file$i
5567                 touch $dir/dir/file$i
5568         done
5569
5570         local numcomp=$($LFS getstripe --component-count $dir)
5571
5572         [[ $numcomp == 0 ]] && numcomp=1
5573
5574         # test lfs getstripe with --recursive
5575         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5576
5577         [[ $filenum -eq $((numfiles * 2)) ]] ||
5578                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5579         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5580         [[ $filenum -eq $numfiles ]] ||
5581                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5582         echo "$LFS getstripe showed obdidx or l_ost_idx"
5583
5584         # test lfs getstripe with file instead of dir
5585         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5586         [[ $filenum -eq 1 ]] ||
5587                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5588         echo "$LFS getstripe file1 passed"
5589
5590         #test lfs getstripe with --verbose
5591         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5592         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5593                 error "$LFS getstripe --verbose $dir: "\
5594                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5595         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5596                 error "$LFS getstripe $dir: showed lmm_magic"
5597
5598         #test lfs getstripe with -v prints lmm_fid
5599         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5600         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5601                 error "$LFS getstripe -v $dir: "\
5602                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5603         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5604                 error "$LFS getstripe $dir: showed lmm_fid by default"
5605         echo "$LFS getstripe --verbose passed"
5606
5607         #check for FID information
5608         local fid1=$($LFS getstripe --fid $dir/file1)
5609         local fid2=$($LFS getstripe --verbose $dir/file1 |
5610                      awk '/lmm_fid: / { print $2; exit; }')
5611         local fid3=$($LFS path2fid $dir/file1)
5612
5613         [ "$fid1" != "$fid2" ] &&
5614                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5615         [ "$fid1" != "$fid3" ] &&
5616                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5617         echo "$LFS getstripe --fid passed"
5618
5619         #test lfs getstripe with --obd
5620         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5621                 error "$LFS getstripe --obd wrong_uuid: should return error"
5622
5623         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5624
5625         local ostidx=1
5626         local obduuid=$(ostuuid_from_index $ostidx)
5627         local found=$($LFS getstripe -r --obd $obduuid $dir |
5628                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5629
5630         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5631         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5632                 ((filenum--))
5633         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5634                 ((filenum--))
5635
5636         [[ $found -eq $filenum ]] ||
5637                 error "$LFS getstripe --obd: found $found expect $filenum"
5638         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5639                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5640                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5641                 error "$LFS getstripe --obd: should not show file on other obd"
5642         echo "$LFS getstripe --obd passed"
5643 }
5644 run_test 56a "check $LFS getstripe"
5645
5646 test_56b() {
5647         local dir=$DIR/$tdir
5648         local numdirs=3
5649
5650         test_mkdir $dir
5651         for i in $(seq $numdirs); do
5652                 test_mkdir $dir/dir$i
5653         done
5654
5655         # test lfs getdirstripe default mode is non-recursion, which is
5656         # different from lfs getstripe
5657         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5658
5659         [[ $dircnt -eq 1 ]] ||
5660                 error "$LFS getdirstripe: found $dircnt, not 1"
5661         dircnt=$($LFS getdirstripe --recursive $dir |
5662                 grep -c lmv_stripe_count)
5663         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5664                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5665 }
5666 run_test 56b "check $LFS getdirstripe"
5667
5668 test_56c() {
5669         remote_ost_nodsh && skip "remote OST with nodsh"
5670
5671         local ost_idx=0
5672         local ost_name=$(ostname_from_index $ost_idx)
5673         local old_status=$(ost_dev_status $ost_idx)
5674         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5675
5676         [[ -z "$old_status" ]] ||
5677                 skip_env "OST $ost_name is in $old_status status"
5678
5679         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5680         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5681                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5682         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5683                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5684                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5685         fi
5686
5687         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5688                 error "$LFS df -v showing inactive devices"
5689         sleep_maxage
5690
5691         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5692
5693         [[ "$new_status" =~ "D" ]] ||
5694                 error "$ost_name status is '$new_status', missing 'D'"
5695         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5696                 [[ "$new_status" =~ "N" ]] ||
5697                         error "$ost_name status is '$new_status', missing 'N'"
5698         fi
5699         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5700                 [[ "$new_status" =~ "f" ]] ||
5701                         error "$ost_name status is '$new_status', missing 'f'"
5702         fi
5703
5704         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5705         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5706                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5707         [[ -z "$p" ]] && restore_lustre_params < $p || true
5708         sleep_maxage
5709
5710         new_status=$(ost_dev_status $ost_idx)
5711         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5712                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5713         # can't check 'f' as devices may actually be on flash
5714 }
5715 run_test 56c "check 'lfs df' showing device status"
5716
5717 test_56d() {
5718         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5719         local osts=$($LFS df -v $MOUNT | grep -c OST)
5720
5721         $LFS df $MOUNT
5722
5723         (( mdts == MDSCOUNT )) ||
5724                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5725         (( osts == OSTCOUNT )) ||
5726                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5727 }
5728 run_test 56d "'lfs df -v' prints only configured devices"
5729
5730 NUMFILES=3
5731 NUMDIRS=3
5732 setup_56() {
5733         local local_tdir="$1"
5734         local local_numfiles="$2"
5735         local local_numdirs="$3"
5736         local dir_params="$4"
5737         local dir_stripe_params="$5"
5738
5739         if [ ! -d "$local_tdir" ] ; then
5740                 test_mkdir -p $dir_stripe_params $local_tdir
5741                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5742                 for i in $(seq $local_numfiles) ; do
5743                         touch $local_tdir/file$i
5744                 done
5745                 for i in $(seq $local_numdirs) ; do
5746                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5747                         for j in $(seq $local_numfiles) ; do
5748                                 touch $local_tdir/dir$i/file$j
5749                         done
5750                 done
5751         fi
5752 }
5753
5754 setup_56_special() {
5755         local local_tdir=$1
5756         local local_numfiles=$2
5757         local local_numdirs=$3
5758
5759         setup_56 $local_tdir $local_numfiles $local_numdirs
5760
5761         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5762                 for i in $(seq $local_numfiles) ; do
5763                         mknod $local_tdir/loop${i}b b 7 $i
5764                         mknod $local_tdir/null${i}c c 1 3
5765                         ln -s $local_tdir/file1 $local_tdir/link${i}
5766                 done
5767                 for i in $(seq $local_numdirs) ; do
5768                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5769                         mknod $local_tdir/dir$i/null${i}c c 1 3
5770                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5771                 done
5772         fi
5773 }
5774
5775 test_56g() {
5776         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5777         local expected=$(($NUMDIRS + 2))
5778
5779         setup_56 $dir $NUMFILES $NUMDIRS
5780
5781         # test lfs find with -name
5782         for i in $(seq $NUMFILES) ; do
5783                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5784
5785                 [ $nums -eq $expected ] ||
5786                         error "lfs find -name '*$i' $dir wrong: "\
5787                               "found $nums, expected $expected"
5788         done
5789 }
5790 run_test 56g "check lfs find -name"
5791
5792 test_56h() {
5793         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5794         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5795
5796         setup_56 $dir $NUMFILES $NUMDIRS
5797
5798         # test lfs find with ! -name
5799         for i in $(seq $NUMFILES) ; do
5800                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5801
5802                 [ $nums -eq $expected ] ||
5803                         error "lfs find ! -name '*$i' $dir wrong: "\
5804                               "found $nums, expected $expected"
5805         done
5806 }
5807 run_test 56h "check lfs find ! -name"
5808
5809 test_56i() {
5810         local dir=$DIR/$tdir
5811
5812         test_mkdir $dir
5813
5814         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5815         local out=$($cmd)
5816
5817         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5818 }
5819 run_test 56i "check 'lfs find -ost UUID' skips directories"
5820
5821 test_56j() {
5822         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5823
5824         setup_56_special $dir $NUMFILES $NUMDIRS
5825
5826         local expected=$((NUMDIRS + 1))
5827         local cmd="$LFS find -type d $dir"
5828         local nums=$($cmd | wc -l)
5829
5830         [ $nums -eq $expected ] ||
5831                 error "'$cmd' wrong: found $nums, expected $expected"
5832 }
5833 run_test 56j "check lfs find -type d"
5834
5835 test_56k() {
5836         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5837
5838         setup_56_special $dir $NUMFILES $NUMDIRS
5839
5840         local expected=$(((NUMDIRS + 1) * NUMFILES))
5841         local cmd="$LFS find -type f $dir"
5842         local nums=$($cmd | wc -l)
5843
5844         [ $nums -eq $expected ] ||
5845                 error "'$cmd' wrong: found $nums, expected $expected"
5846 }
5847 run_test 56k "check lfs find -type f"
5848
5849 test_56l() {
5850         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5851
5852         setup_56_special $dir $NUMFILES $NUMDIRS
5853
5854         local expected=$((NUMDIRS + NUMFILES))
5855         local cmd="$LFS find -type b $dir"
5856         local nums=$($cmd | wc -l)
5857
5858         [ $nums -eq $expected ] ||
5859                 error "'$cmd' wrong: found $nums, expected $expected"
5860 }
5861 run_test 56l "check lfs find -type b"
5862
5863 test_56m() {
5864         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5865
5866         setup_56_special $dir $NUMFILES $NUMDIRS
5867
5868         local expected=$((NUMDIRS + NUMFILES))
5869         local cmd="$LFS find -type c $dir"
5870         local nums=$($cmd | wc -l)
5871         [ $nums -eq $expected ] ||
5872                 error "'$cmd' wrong: found $nums, expected $expected"
5873 }
5874 run_test 56m "check lfs find -type c"
5875
5876 test_56n() {
5877         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5878         setup_56_special $dir $NUMFILES $NUMDIRS
5879
5880         local expected=$((NUMDIRS + NUMFILES))
5881         local cmd="$LFS find -type l $dir"
5882         local nums=$($cmd | wc -l)
5883
5884         [ $nums -eq $expected ] ||
5885                 error "'$cmd' wrong: found $nums, expected $expected"
5886 }
5887 run_test 56n "check lfs find -type l"
5888
5889 test_56o() {
5890         local dir=$DIR/$tdir
5891
5892         setup_56 $dir $NUMFILES $NUMDIRS
5893         utime $dir/file1 > /dev/null || error "utime (1)"
5894         utime $dir/file2 > /dev/null || error "utime (2)"
5895         utime $dir/dir1 > /dev/null || error "utime (3)"
5896         utime $dir/dir2 > /dev/null || error "utime (4)"
5897         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5898         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5899
5900         local expected=4
5901         local nums=$($LFS find -mtime +0 $dir | wc -l)
5902
5903         [ $nums -eq $expected ] ||
5904                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5905
5906         expected=12
5907         cmd="$LFS find -mtime 0 $dir"
5908         nums=$($cmd | wc -l)
5909         [ $nums -eq $expected ] ||
5910                 error "'$cmd' wrong: found $nums, expected $expected"
5911 }
5912 run_test 56o "check lfs find -mtime for old files"
5913
5914 test_56ob() {
5915         local dir=$DIR/$tdir
5916         local expected=1
5917         local count=0
5918
5919         # just to make sure there is something that won't be found
5920         test_mkdir $dir
5921         touch $dir/$tfile.now
5922
5923         for age in year week day hour min; do
5924                 count=$((count + 1))
5925
5926                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5927                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5928                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5929
5930                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5931                 local nums=$($cmd | wc -l)
5932                 [ $nums -eq $expected ] ||
5933                         error "'$cmd' wrong: found $nums, expected $expected"
5934
5935                 cmd="$LFS find $dir -atime $count${age:0:1}"
5936                 nums=$($cmd | wc -l)
5937                 [ $nums -eq $expected ] ||
5938                         error "'$cmd' wrong: found $nums, expected $expected"
5939         done
5940
5941         sleep 2
5942         cmd="$LFS find $dir -ctime +1s -type f"
5943         nums=$($cmd | wc -l)
5944         (( $nums == $count * 2 + 1)) ||
5945                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
5946 }
5947 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5948
5949 test_newerXY_base() {
5950         local x=$1
5951         local y=$2
5952         local dir=$DIR/$tdir
5953         local ref
5954         local negref
5955
5956         if [ $y == "t" ]; then
5957                 if [ $x == "b" ]; then
5958                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5959                 else
5960                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5961                 fi
5962         else
5963                 ref=$DIR/$tfile.newer.$x$y
5964                 touch $ref || error "touch $ref failed"
5965         fi
5966         sleep 2
5967         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5968         sleep 2
5969         if [ $y == "t" ]; then
5970                 if [ $x == "b" ]; then
5971                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5972                 else
5973                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5974                 fi
5975         else
5976                 negref=$DIR/$tfile.negnewer.$x$y
5977                 touch $negref || error "touch $negref failed"
5978         fi
5979
5980         local cmd="$LFS find $dir -newer$x$y $ref"
5981         local nums=$(eval $cmd | wc -l)
5982         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5983
5984         [ $nums -eq $expected ] ||
5985                 error "'$cmd' wrong: found $nums, expected $expected"
5986
5987         cmd="$LFS find $dir ! -newer$x$y $negref"
5988         nums=$(eval $cmd | wc -l)
5989         [ $nums -eq $expected ] ||
5990                 error "'$cmd' wrong: found $nums, expected $expected"
5991
5992         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
5993         nums=$(eval $cmd | wc -l)
5994         [ $nums -eq $expected ] ||
5995                 error "'$cmd' wrong: found $nums, expected $expected"
5996
5997         rm -rf $DIR/*
5998 }
5999
6000 test_56oc() {
6001         test_newerXY_base "b" "t"
6002         test_newerXY_base "a" "a"
6003         test_newerXY_base "a" "m"
6004         test_newerXY_base "a" "c"
6005         test_newerXY_base "m" "a"
6006         test_newerXY_base "m" "m"
6007         test_newerXY_base "m" "c"
6008         test_newerXY_base "c" "a"
6009         test_newerXY_base "c" "m"
6010         test_newerXY_base "c" "c"
6011         test_newerXY_base "b" "b"
6012         test_newerXY_base "a" "t"
6013         test_newerXY_base "m" "t"
6014         test_newerXY_base "c" "t"
6015         test_newerXY_base "b" "t"
6016 }
6017 run_test 56oc "check lfs find -newerXY work"
6018
6019 btime_supported() {
6020         local dir=$DIR/$tdir
6021         local rc
6022
6023         mkdir -p $dir
6024         touch $dir/$tfile
6025         $LFS find $dir -btime -1d -type f
6026         rc=$?
6027         rm -rf $dir
6028         return $rc
6029 }
6030
6031 test_56od() {
6032         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6033                 ! btime_supported && skip "btime unsupported on MDS"
6034
6035         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6036                 ! btime_supported && skip "btime unsupported on clients"
6037
6038         local dir=$DIR/$tdir
6039         local ref=$DIR/$tfile.ref
6040         local negref=$DIR/$tfile.negref
6041
6042         mkdir $dir || error "mkdir $dir failed"
6043         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6044         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6045         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6046         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6047         touch $ref || error "touch $ref failed"
6048         # sleep 3 seconds at least
6049         sleep 3
6050
6051         local before=$(do_facet mds1 date +%s)
6052         local skew=$(($(date +%s) - before + 1))
6053
6054         if (( skew < 0 && skew > -5 )); then
6055                 sleep $((0 - skew + 1))
6056                 skew=0
6057         fi
6058
6059         # Set the dir stripe params to limit files all on MDT0,
6060         # otherwise we need to calc the max clock skew between
6061         # the client and MDTs.
6062         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6063         sleep 2
6064         touch $negref || error "touch $negref failed"
6065
6066         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6067         local nums=$($cmd | wc -l)
6068         local expected=$(((NUMFILES + 1) * NUMDIRS))
6069
6070         [ $nums -eq $expected ] ||
6071                 error "'$cmd' wrong: found $nums, expected $expected"
6072
6073         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6074         nums=$($cmd | wc -l)
6075         expected=$((NUMFILES + 1))
6076         [ $nums -eq $expected ] ||
6077                 error "'$cmd' wrong: found $nums, expected $expected"
6078
6079         [ $skew -lt 0 ] && return
6080
6081         local after=$(do_facet mds1 date +%s)
6082         local age=$((after - before + 1 + skew))
6083
6084         cmd="$LFS find $dir -btime -${age}s -type f"
6085         nums=$($cmd | wc -l)
6086         expected=$(((NUMFILES + 1) * NUMDIRS))
6087
6088         echo "Clock skew between client and server: $skew, age:$age"
6089         [ $nums -eq $expected ] ||
6090                 error "'$cmd' wrong: found $nums, expected $expected"
6091
6092         expected=$(($NUMDIRS + 1))
6093         cmd="$LFS find $dir -btime -${age}s -type d"
6094         nums=$($cmd | wc -l)
6095         [ $nums -eq $expected ] ||
6096                 error "'$cmd' wrong: found $nums, expected $expected"
6097         rm -f $ref $negref || error "Failed to remove $ref $negref"
6098 }
6099 run_test 56od "check lfs find -btime with units"
6100
6101 test_56p() {
6102         [ $RUNAS_ID -eq $UID ] &&
6103                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6104
6105         local dir=$DIR/$tdir
6106
6107         setup_56 $dir $NUMFILES $NUMDIRS
6108         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6109
6110         local expected=$NUMFILES
6111         local cmd="$LFS find -uid $RUNAS_ID $dir"
6112         local nums=$($cmd | wc -l)
6113
6114         [ $nums -eq $expected ] ||
6115                 error "'$cmd' wrong: found $nums, expected $expected"
6116
6117         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6118         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6119         nums=$($cmd | wc -l)
6120         [ $nums -eq $expected ] ||
6121                 error "'$cmd' wrong: found $nums, expected $expected"
6122 }
6123 run_test 56p "check lfs find -uid and ! -uid"
6124
6125 test_56q() {
6126         [ $RUNAS_ID -eq $UID ] &&
6127                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6128
6129         local dir=$DIR/$tdir
6130
6131         setup_56 $dir $NUMFILES $NUMDIRS
6132         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6133
6134         local expected=$NUMFILES
6135         local cmd="$LFS find -gid $RUNAS_GID $dir"
6136         local nums=$($cmd | wc -l)
6137
6138         [ $nums -eq $expected ] ||
6139                 error "'$cmd' wrong: found $nums, expected $expected"
6140
6141         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6142         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6143         nums=$($cmd | wc -l)
6144         [ $nums -eq $expected ] ||
6145                 error "'$cmd' wrong: found $nums, expected $expected"
6146 }
6147 run_test 56q "check lfs find -gid and ! -gid"
6148
6149 test_56r() {
6150         local dir=$DIR/$tdir
6151
6152         setup_56 $dir $NUMFILES $NUMDIRS
6153
6154         local expected=12
6155         local cmd="$LFS find -size 0 -type f -lazy $dir"
6156         local nums=$($cmd | wc -l)
6157
6158         [ $nums -eq $expected ] ||
6159                 error "'$cmd' wrong: found $nums, expected $expected"
6160         cmd="$LFS find -size 0 -type f $dir"
6161         nums=$($cmd | wc -l)
6162         [ $nums -eq $expected ] ||
6163                 error "'$cmd' wrong: found $nums, expected $expected"
6164
6165         expected=0
6166         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6167         nums=$($cmd | wc -l)
6168         [ $nums -eq $expected ] ||
6169                 error "'$cmd' wrong: found $nums, expected $expected"
6170         cmd="$LFS find ! -size 0 -type f $dir"
6171         nums=$($cmd | wc -l)
6172         [ $nums -eq $expected ] ||
6173                 error "'$cmd' wrong: found $nums, expected $expected"
6174
6175         echo "test" > $dir/$tfile
6176         echo "test2" > $dir/$tfile.2 && sync
6177         expected=1
6178         cmd="$LFS find -size 5 -type f -lazy $dir"
6179         nums=$($cmd | wc -l)
6180         [ $nums -eq $expected ] ||
6181                 error "'$cmd' wrong: found $nums, expected $expected"
6182         cmd="$LFS find -size 5 -type f $dir"
6183         nums=$($cmd | wc -l)
6184         [ $nums -eq $expected ] ||
6185                 error "'$cmd' wrong: found $nums, expected $expected"
6186
6187         expected=1
6188         cmd="$LFS find -size +5 -type f -lazy $dir"
6189         nums=$($cmd | wc -l)
6190         [ $nums -eq $expected ] ||
6191                 error "'$cmd' wrong: found $nums, expected $expected"
6192         cmd="$LFS find -size +5 -type f $dir"
6193         nums=$($cmd | wc -l)
6194         [ $nums -eq $expected ] ||
6195                 error "'$cmd' wrong: found $nums, expected $expected"
6196
6197         expected=2
6198         cmd="$LFS find -size +0 -type f -lazy $dir"
6199         nums=$($cmd | wc -l)
6200         [ $nums -eq $expected ] ||
6201                 error "'$cmd' wrong: found $nums, expected $expected"
6202         cmd="$LFS find -size +0 -type f $dir"
6203         nums=$($cmd | wc -l)
6204         [ $nums -eq $expected ] ||
6205                 error "'$cmd' wrong: found $nums, expected $expected"
6206
6207         expected=2
6208         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6209         nums=$($cmd | wc -l)
6210         [ $nums -eq $expected ] ||
6211                 error "'$cmd' wrong: found $nums, expected $expected"
6212         cmd="$LFS find ! -size -5 -type f $dir"
6213         nums=$($cmd | wc -l)
6214         [ $nums -eq $expected ] ||
6215                 error "'$cmd' wrong: found $nums, expected $expected"
6216
6217         expected=12
6218         cmd="$LFS find -size -5 -type f -lazy $dir"
6219         nums=$($cmd | wc -l)
6220         [ $nums -eq $expected ] ||
6221                 error "'$cmd' wrong: found $nums, expected $expected"
6222         cmd="$LFS find -size -5 -type f $dir"
6223         nums=$($cmd | wc -l)
6224         [ $nums -eq $expected ] ||
6225                 error "'$cmd' wrong: found $nums, expected $expected"
6226 }
6227 run_test 56r "check lfs find -size works"
6228
6229 test_56ra_sub() {
6230         local expected=$1
6231         local glimpses=$2
6232         local cmd="$3"
6233
6234         cancel_lru_locks $OSC
6235
6236         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6237         local nums=$($cmd | wc -l)
6238
6239         [ $nums -eq $expected ] ||
6240                 error "'$cmd' wrong: found $nums, expected $expected"
6241
6242         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6243
6244         if (( rpcs_before + glimpses != rpcs_after )); then
6245                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6246                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6247
6248                 if [[ $glimpses == 0 ]]; then
6249                         error "'$cmd' should not send glimpse RPCs to OST"
6250                 else
6251                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6252                 fi
6253         fi
6254 }
6255
6256 test_56ra() {
6257         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6258                 skip "MDS < 2.12.58 doesn't return LSOM data"
6259         local dir=$DIR/$tdir
6260
6261         [[ $OSC == "mdc" ]] && skip "DoM files" && return
6262
6263         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6264         # open and close all files to ensure LSOM is updated
6265         cancel_lru_locks $OSC
6266         find $dir -type f | xargs cat > /dev/null
6267
6268         #   expect_found  glimpse_rpcs  command_to_run
6269         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6270         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6271         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6272         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6273
6274         echo "test" > $dir/$tfile
6275         echo "test2" > $dir/$tfile.2 && sync
6276         cancel_lru_locks $OSC
6277         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6278
6279         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6280         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6281         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6282         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6283
6284         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6285         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6286         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6287         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6288         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6289         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6290 }
6291 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6292
6293 test_56rb() {
6294         local dir=$DIR/$tdir
6295         local tmp=$TMP/$tfile.log
6296         local mdt_idx;
6297
6298         test_mkdir -p $dir || error "failed to mkdir $dir"
6299         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6300                 error "failed to setstripe $dir/$tfile"
6301         mdt_idx=$($LFS getdirstripe -i $dir)
6302         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6303
6304         stack_trap "rm -f $tmp" EXIT
6305         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6306         ! grep -q obd_uuid $tmp ||
6307                 error "failed to find --size +100K --ost 0 $dir"
6308         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6309         ! grep -q obd_uuid $tmp ||
6310                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6311 }
6312 run_test 56rb "check lfs find --size --ost/--mdt works"
6313
6314 test_56s() { # LU-611 #LU-9369
6315         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6316
6317         local dir=$DIR/$tdir
6318         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6319
6320         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6321         for i in $(seq $NUMDIRS); do
6322                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6323         done
6324
6325         local expected=$NUMDIRS
6326         local cmd="$LFS find -c $OSTCOUNT $dir"
6327         local nums=$($cmd | wc -l)
6328
6329         [ $nums -eq $expected ] || {
6330                 $LFS getstripe -R $dir
6331                 error "'$cmd' wrong: found $nums, expected $expected"
6332         }
6333
6334         expected=$((NUMDIRS + onestripe))
6335         cmd="$LFS find -stripe-count +0 -type f $dir"
6336         nums=$($cmd | wc -l)
6337         [ $nums -eq $expected ] || {
6338                 $LFS getstripe -R $dir
6339                 error "'$cmd' wrong: found $nums, expected $expected"
6340         }
6341
6342         expected=$onestripe
6343         cmd="$LFS find -stripe-count 1 -type f $dir"
6344         nums=$($cmd | wc -l)
6345         [ $nums -eq $expected ] || {
6346                 $LFS getstripe -R $dir
6347                 error "'$cmd' wrong: found $nums, expected $expected"
6348         }
6349
6350         cmd="$LFS find -stripe-count -2 -type f $dir"
6351         nums=$($cmd | wc -l)
6352         [ $nums -eq $expected ] || {
6353                 $LFS getstripe -R $dir
6354                 error "'$cmd' wrong: found $nums, expected $expected"
6355         }
6356
6357         expected=0
6358         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6359         nums=$($cmd | wc -l)
6360         [ $nums -eq $expected ] || {
6361                 $LFS getstripe -R $dir
6362                 error "'$cmd' wrong: found $nums, expected $expected"
6363         }
6364 }
6365 run_test 56s "check lfs find -stripe-count works"
6366
6367 test_56t() { # LU-611 #LU-9369
6368         local dir=$DIR/$tdir
6369
6370         setup_56 $dir 0 $NUMDIRS
6371         for i in $(seq $NUMDIRS); do
6372                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6373         done
6374
6375         local expected=$NUMDIRS
6376         local cmd="$LFS find -S 8M $dir"
6377         local nums=$($cmd | wc -l)
6378
6379         [ $nums -eq $expected ] || {
6380                 $LFS getstripe -R $dir
6381                 error "'$cmd' wrong: found $nums, expected $expected"
6382         }
6383         rm -rf $dir
6384
6385         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6386
6387         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6388
6389         expected=$(((NUMDIRS + 1) * NUMFILES))
6390         cmd="$LFS find -stripe-size 512k -type f $dir"
6391         nums=$($cmd | wc -l)
6392         [ $nums -eq $expected ] ||
6393                 error "'$cmd' wrong: found $nums, expected $expected"
6394
6395         cmd="$LFS find -stripe-size +320k -type f $dir"
6396         nums=$($cmd | wc -l)
6397         [ $nums -eq $expected ] ||
6398                 error "'$cmd' wrong: found $nums, expected $expected"
6399
6400         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6401         cmd="$LFS find -stripe-size +200k -type f $dir"
6402         nums=$($cmd | wc -l)
6403         [ $nums -eq $expected ] ||
6404                 error "'$cmd' wrong: found $nums, expected $expected"
6405
6406         cmd="$LFS find -stripe-size -640k -type f $dir"
6407         nums=$($cmd | wc -l)
6408         [ $nums -eq $expected ] ||
6409                 error "'$cmd' wrong: found $nums, expected $expected"
6410
6411         expected=4
6412         cmd="$LFS find -stripe-size 256k -type f $dir"
6413         nums=$($cmd | wc -l)
6414         [ $nums -eq $expected ] ||
6415                 error "'$cmd' wrong: found $nums, expected $expected"
6416
6417         cmd="$LFS find -stripe-size -320k -type f $dir"
6418         nums=$($cmd | wc -l)
6419         [ $nums -eq $expected ] ||
6420                 error "'$cmd' wrong: found $nums, expected $expected"
6421
6422         expected=0
6423         cmd="$LFS find -stripe-size 1024k -type f $dir"
6424         nums=$($cmd | wc -l)
6425         [ $nums -eq $expected ] ||
6426                 error "'$cmd' wrong: found $nums, expected $expected"
6427 }
6428 run_test 56t "check lfs find -stripe-size works"
6429
6430 test_56u() { # LU-611
6431         local dir=$DIR/$tdir
6432
6433         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6434
6435         if [[ $OSTCOUNT -gt 1 ]]; then
6436                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6437                 onestripe=4
6438         else
6439                 onestripe=0
6440         fi
6441
6442         local expected=$(((NUMDIRS + 1) * NUMFILES))
6443         local cmd="$LFS find -stripe-index 0 -type f $dir"
6444         local nums=$($cmd | wc -l)
6445
6446         [ $nums -eq $expected ] ||
6447                 error "'$cmd' wrong: found $nums, expected $expected"
6448
6449         expected=$onestripe
6450         cmd="$LFS find -stripe-index 1 -type f $dir"
6451         nums=$($cmd | wc -l)
6452         [ $nums -eq $expected ] ||
6453                 error "'$cmd' wrong: found $nums, expected $expected"
6454
6455         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6456         nums=$($cmd | wc -l)
6457         [ $nums -eq $expected ] ||
6458                 error "'$cmd' wrong: found $nums, expected $expected"
6459
6460         expected=0
6461         # This should produce an error and not return any files
6462         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6463         nums=$($cmd 2>/dev/null | wc -l)
6464         [ $nums -eq $expected ] ||
6465                 error "'$cmd' wrong: found $nums, expected $expected"
6466
6467         if [[ $OSTCOUNT -gt 1 ]]; then
6468                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6469                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6470                 nums=$($cmd | wc -l)
6471                 [ $nums -eq $expected ] ||
6472                         error "'$cmd' wrong: found $nums, expected $expected"
6473         fi
6474 }
6475 run_test 56u "check lfs find -stripe-index works"
6476
6477 test_56v() {
6478         local mdt_idx=0
6479         local dir=$DIR/$tdir
6480
6481         setup_56 $dir $NUMFILES $NUMDIRS
6482
6483         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6484         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6485
6486         for file in $($LFS find -m $UUID $dir); do
6487                 file_midx=$($LFS getstripe -m $file)
6488                 [ $file_midx -eq $mdt_idx ] ||
6489                         error "lfs find -m $UUID != getstripe -m $file_midx"
6490         done
6491 }
6492 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6493
6494 test_56w() {
6495         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6497
6498         local dir=$DIR/$tdir
6499
6500         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6501
6502         local stripe_size=$($LFS getstripe -S -d $dir) ||
6503                 error "$LFS getstripe -S -d $dir failed"
6504         stripe_size=${stripe_size%% *}
6505
6506         local file_size=$((stripe_size * OSTCOUNT))
6507         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6508         local required_space=$((file_num * file_size))
6509         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6510                            head -n1)
6511         [[ $free_space -le $((required_space / 1024)) ]] &&
6512                 skip_env "need $required_space, have $free_space kbytes"
6513
6514         local dd_bs=65536
6515         local dd_count=$((file_size / dd_bs))
6516
6517         # write data into the files
6518         local i
6519         local j
6520         local file
6521
6522         for i in $(seq $NUMFILES); do
6523                 file=$dir/file$i
6524                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6525                         error "write data into $file failed"
6526         done
6527         for i in $(seq $NUMDIRS); do
6528                 for j in $(seq $NUMFILES); do
6529                         file=$dir/dir$i/file$j
6530                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6531                                 error "write data into $file failed"
6532                 done
6533         done
6534
6535         # $LFS_MIGRATE will fail if hard link migration is unsupported
6536         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6537                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6538                         error "creating links to $dir/dir1/file1 failed"
6539         fi
6540
6541         local expected=-1
6542
6543         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6544
6545         # lfs_migrate file
6546         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6547
6548         echo "$cmd"
6549         eval $cmd || error "$cmd failed"
6550
6551         check_stripe_count $dir/file1 $expected
6552
6553         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6554         then
6555                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6556                 # OST 1 if it is on OST 0. This file is small enough to
6557                 # be on only one stripe.
6558                 file=$dir/migr_1_ost
6559                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6560                         error "write data into $file failed"
6561                 local obdidx=$($LFS getstripe -i $file)
6562                 local oldmd5=$(md5sum $file)
6563                 local newobdidx=0
6564
6565                 [[ $obdidx -eq 0 ]] && newobdidx=1
6566                 cmd="$LFS migrate -i $newobdidx $file"
6567                 echo $cmd
6568                 eval $cmd || error "$cmd failed"
6569
6570                 local realobdix=$($LFS getstripe -i $file)
6571                 local newmd5=$(md5sum $file)
6572
6573                 [[ $newobdidx -ne $realobdix ]] &&
6574                         error "new OST is different (was=$obdidx, "\
6575                               "wanted=$newobdidx, got=$realobdix)"
6576                 [[ "$oldmd5" != "$newmd5" ]] &&
6577                         error "md5sum differ: $oldmd5, $newmd5"
6578         fi
6579
6580         # lfs_migrate dir
6581         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6582         echo "$cmd"
6583         eval $cmd || error "$cmd failed"
6584
6585         for j in $(seq $NUMFILES); do
6586                 check_stripe_count $dir/dir1/file$j $expected
6587         done
6588
6589         # lfs_migrate works with lfs find
6590         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6591              $LFS_MIGRATE -y -c $expected"
6592         echo "$cmd"
6593         eval $cmd || error "$cmd failed"
6594
6595         for i in $(seq 2 $NUMFILES); do
6596                 check_stripe_count $dir/file$i $expected
6597         done
6598         for i in $(seq 2 $NUMDIRS); do
6599                 for j in $(seq $NUMFILES); do
6600                 check_stripe_count $dir/dir$i/file$j $expected
6601                 done
6602         done
6603 }
6604 run_test 56w "check lfs_migrate -c stripe_count works"
6605
6606 test_56wb() {
6607         local file1=$DIR/$tdir/file1
6608         local create_pool=false
6609         local initial_pool=$($LFS getstripe -p $DIR)
6610         local pool_list=()
6611         local pool=""
6612
6613         echo -n "Creating test dir..."
6614         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6615         echo "done."
6616
6617         echo -n "Creating test file..."
6618         touch $file1 || error "cannot create file"
6619         echo "done."
6620
6621         echo -n "Detecting existing pools..."
6622         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6623
6624         if [ ${#pool_list[@]} -gt 0 ]; then
6625                 echo "${pool_list[@]}"
6626                 for thispool in "${pool_list[@]}"; do
6627                         if [[ -z "$initial_pool" ||
6628                               "$initial_pool" != "$thispool" ]]; then
6629                                 pool="$thispool"
6630                                 echo "Using existing pool '$pool'"
6631                                 break
6632                         fi
6633                 done
6634         else
6635                 echo "none detected."
6636         fi
6637         if [ -z "$pool" ]; then
6638                 pool=${POOL:-testpool}
6639                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6640                 echo -n "Creating pool '$pool'..."
6641                 create_pool=true
6642                 pool_add $pool &> /dev/null ||
6643                         error "pool_add failed"
6644                 echo "done."
6645
6646                 echo -n "Adding target to pool..."
6647                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6648                         error "pool_add_targets failed"
6649                 echo "done."
6650         fi
6651
6652         echo -n "Setting pool using -p option..."
6653         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6654                 error "migrate failed rc = $?"
6655         echo "done."
6656
6657         echo -n "Verifying test file is in pool after migrating..."
6658         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6659                 error "file was not migrated to pool $pool"
6660         echo "done."
6661
6662         echo -n "Removing test file from pool '$pool'..."
6663         # "lfs migrate $file" won't remove the file from the pool
6664         # until some striping information is changed.
6665         $LFS migrate -c 1 $file1 &> /dev/null ||
6666                 error "cannot remove from pool"
6667         [ "$($LFS getstripe -p $file1)" ] &&
6668                 error "pool still set"
6669         echo "done."
6670
6671         echo -n "Setting pool using --pool option..."
6672         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6673                 error "migrate failed rc = $?"
6674         echo "done."
6675
6676         # Clean up
6677         rm -f $file1
6678         if $create_pool; then
6679                 destroy_test_pools 2> /dev/null ||
6680                         error "destroy test pools failed"
6681         fi
6682 }
6683 run_test 56wb "check lfs_migrate pool support"
6684
6685 test_56wc() {
6686         local file1="$DIR/$tdir/file1"
6687         local parent_ssize
6688         local parent_scount
6689         local cur_ssize
6690         local cur_scount
6691         local orig_ssize
6692
6693         echo -n "Creating test dir..."
6694         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6695         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6696                 error "cannot set stripe by '-S 1M -c 1'"
6697         echo "done"
6698
6699         echo -n "Setting initial stripe for test file..."
6700         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6701                 error "cannot set stripe"
6702         cur_ssize=$($LFS getstripe -S "$file1")
6703         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6704         echo "done."
6705
6706         # File currently set to -S 512K -c 1
6707
6708         # Ensure -c and -S options are rejected when -R is set
6709         echo -n "Verifying incompatible options are detected..."
6710         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6711                 error "incompatible -c and -R options not detected"
6712         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6713                 error "incompatible -S and -R options not detected"
6714         echo "done."
6715
6716         # Ensure unrecognized options are passed through to 'lfs migrate'
6717         echo -n "Verifying -S option is passed through to lfs migrate..."
6718         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6719                 error "migration failed"
6720         cur_ssize=$($LFS getstripe -S "$file1")
6721         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6722         echo "done."
6723
6724         # File currently set to -S 1M -c 1
6725
6726         # Ensure long options are supported
6727         echo -n "Verifying long options supported..."
6728         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6729                 error "long option without argument not supported"
6730         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6731                 error "long option with argument not supported"
6732         cur_ssize=$($LFS getstripe -S "$file1")
6733         [ $cur_ssize -eq 524288 ] ||
6734                 error "migrate --stripe-size $cur_ssize != 524288"
6735         echo "done."
6736
6737         # File currently set to -S 512K -c 1
6738
6739         if [ "$OSTCOUNT" -gt 1 ]; then
6740                 echo -n "Verifying explicit stripe count can be set..."
6741                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6742                         error "migrate failed"
6743                 cur_scount=$($LFS getstripe -c "$file1")
6744                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6745                 echo "done."
6746         fi
6747
6748         # File currently set to -S 512K -c 1 or -S 512K -c 2
6749
6750         # Ensure parent striping is used if -R is set, and no stripe
6751         # count or size is specified
6752         echo -n "Setting stripe for parent directory..."
6753         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6754                 error "cannot set stripe '-S 2M -c 1'"
6755         echo "done."
6756
6757         echo -n "Verifying restripe option uses parent stripe settings..."
6758         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6759         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6760         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6761                 error "migrate failed"
6762         cur_ssize=$($LFS getstripe -S "$file1")
6763         [ $cur_ssize -eq $parent_ssize ] ||
6764                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6765         cur_scount=$($LFS getstripe -c "$file1")
6766         [ $cur_scount -eq $parent_scount ] ||
6767                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6768         echo "done."
6769
6770         # File currently set to -S 1M -c 1
6771
6772         # Ensure striping is preserved if -R is not set, and no stripe
6773         # count or size is specified
6774         echo -n "Verifying striping size preserved when not specified..."
6775         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6776         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6777                 error "cannot set stripe on parent directory"
6778         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6779                 error "migrate failed"
6780         cur_ssize=$($LFS getstripe -S "$file1")
6781         [ $cur_ssize -eq $orig_ssize ] ||
6782                 error "migrate by default $cur_ssize != $orig_ssize"
6783         echo "done."
6784
6785         # Ensure file name properly detected when final option has no argument
6786         echo -n "Verifying file name properly detected..."
6787         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6788                 error "file name interpreted as option argument"
6789         echo "done."
6790
6791         # Clean up
6792         rm -f "$file1"
6793 }
6794 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6795
6796 test_56wd() {
6797         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6798
6799         local file1=$DIR/$tdir/file1
6800
6801         echo -n "Creating test dir..."
6802         test_mkdir $DIR/$tdir || error "cannot create dir"
6803         echo "done."
6804
6805         echo -n "Creating test file..."
6806         touch $file1
6807         echo "done."
6808
6809         # Ensure 'lfs migrate' will fail by using a non-existent option,
6810         # and make sure rsync is not called to recover
6811         echo -n "Make sure --no-rsync option works..."
6812         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6813                 grep -q 'refusing to fall back to rsync' ||
6814                 error "rsync was called with --no-rsync set"
6815         echo "done."
6816
6817         # Ensure rsync is called without trying 'lfs migrate' first
6818         echo -n "Make sure --rsync option works..."
6819         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6820                 grep -q 'falling back to rsync' &&
6821                 error "lfs migrate was called with --rsync set"
6822         echo "done."
6823
6824         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6825         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6826                 grep -q 'at the same time' ||
6827                 error "--rsync and --no-rsync accepted concurrently"
6828         echo "done."
6829
6830         # Clean up
6831         rm -f $file1
6832 }
6833 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6834
6835 test_56we() {
6836         local td=$DIR/$tdir
6837         local tf=$td/$tfile
6838
6839         test_mkdir $td || error "cannot create $td"
6840         touch $tf || error "cannot touch $tf"
6841
6842         echo -n "Make sure --non-direct|-D works..."
6843         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6844                 grep -q "lfs migrate --non-direct" ||
6845                 error "--non-direct option cannot work correctly"
6846         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6847                 grep -q "lfs migrate -D" ||
6848                 error "-D option cannot work correctly"
6849         echo "done."
6850 }
6851 run_test 56we "check lfs_migrate --non-direct|-D support"
6852
6853 test_56x() {
6854         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6855         check_swap_layouts_support
6856
6857         local dir=$DIR/$tdir
6858         local ref1=/etc/passwd
6859         local file1=$dir/file1
6860
6861         test_mkdir $dir || error "creating dir $dir"
6862         $LFS setstripe -c 2 $file1
6863         cp $ref1 $file1
6864         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6865         stripe=$($LFS getstripe -c $file1)
6866         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6867         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6868
6869         # clean up
6870         rm -f $file1
6871 }
6872 run_test 56x "lfs migration support"
6873
6874 test_56xa() {
6875         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6876         check_swap_layouts_support
6877
6878         local dir=$DIR/$tdir/$testnum
6879
6880         test_mkdir -p $dir
6881
6882         local ref1=/etc/passwd
6883         local file1=$dir/file1
6884
6885         $LFS setstripe -c 2 $file1
6886         cp $ref1 $file1
6887         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6888
6889         local stripe=$($LFS getstripe -c $file1)
6890
6891         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6892         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6893
6894         # clean up
6895         rm -f $file1
6896 }
6897 run_test 56xa "lfs migration --block support"
6898
6899 check_migrate_links() {
6900         local dir="$1"
6901         local file1="$dir/file1"
6902         local begin="$2"
6903         local count="$3"
6904         local runas="$4"
6905         local total_count=$(($begin + $count - 1))
6906         local symlink_count=10
6907         local uniq_count=10
6908
6909         if [ ! -f "$file1" ]; then
6910                 echo -n "creating initial file..."
6911                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6912                         error "cannot setstripe initial file"
6913                 echo "done"
6914
6915                 echo -n "creating symlinks..."
6916                 for s in $(seq 1 $symlink_count); do
6917                         ln -s "$file1" "$dir/slink$s" ||
6918                                 error "cannot create symlinks"
6919                 done
6920                 echo "done"
6921
6922                 echo -n "creating nonlinked files..."
6923                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6924                         error "cannot create nonlinked files"
6925                 echo "done"
6926         fi
6927
6928         # create hard links
6929         if [ ! -f "$dir/file$total_count" ]; then
6930                 echo -n "creating hard links $begin:$total_count..."
6931                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6932                         /dev/null || error "cannot create hard links"
6933                 echo "done"
6934         fi
6935
6936         echo -n "checking number of hard links listed in xattrs..."
6937         local fid=$($LFS getstripe -F "$file1")
6938         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6939
6940         echo "${#paths[*]}"
6941         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6942                         skip "hard link list has unexpected size, skipping test"
6943         fi
6944         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6945                         error "link names should exceed xattrs size"
6946         fi
6947
6948         echo -n "migrating files..."
6949         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6950         local rc=$?
6951         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6952         echo "done"
6953
6954         # make sure all links have been properly migrated
6955         echo -n "verifying files..."
6956         fid=$($LFS getstripe -F "$file1") ||
6957                 error "cannot get fid for file $file1"
6958         for i in $(seq 2 $total_count); do
6959                 local fid2=$($LFS getstripe -F $dir/file$i)
6960
6961                 [ "$fid2" == "$fid" ] ||
6962                         error "migrated hard link has mismatched FID"
6963         done
6964
6965         # make sure hard links were properly detected, and migration was
6966         # performed only once for the entire link set; nonlinked files should
6967         # also be migrated
6968         local actual=$(grep -c 'done' <<< "$migrate_out")
6969         local expected=$(($uniq_count + 1))
6970
6971         [ "$actual" -eq  "$expected" ] ||
6972                 error "hard links individually migrated ($actual != $expected)"
6973
6974         # make sure the correct number of hard links are present
6975         local hardlinks=$(stat -c '%h' "$file1")
6976
6977         [ $hardlinks -eq $total_count ] ||
6978                 error "num hard links $hardlinks != $total_count"
6979         echo "done"
6980
6981         return 0
6982 }
6983
6984 test_56xb() {
6985         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6986                 skip "Need MDS version at least 2.10.55"
6987
6988         local dir="$DIR/$tdir"
6989
6990         test_mkdir "$dir" || error "cannot create dir $dir"
6991
6992         echo "testing lfs migrate mode when all links fit within xattrs"
6993         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6994
6995         echo "testing rsync mode when all links fit within xattrs"
6996         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6997
6998         echo "testing lfs migrate mode when all links do not fit within xattrs"
6999         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7000
7001         echo "testing rsync mode when all links do not fit within xattrs"
7002         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7003
7004         chown -R $RUNAS_ID $dir
7005         echo "testing non-root lfs migrate mode when not all links are in xattr"
7006         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7007
7008         # clean up
7009         rm -rf $dir
7010 }
7011 run_test 56xb "lfs migration hard link support"
7012
7013 test_56xc() {
7014         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7015
7016         local dir="$DIR/$tdir"
7017
7018         test_mkdir "$dir" || error "cannot create dir $dir"
7019
7020         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7021         echo -n "Setting initial stripe for 20MB test file..."
7022         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7023                 error "cannot setstripe 20MB file"
7024         echo "done"
7025         echo -n "Sizing 20MB test file..."
7026         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7027         echo "done"
7028         echo -n "Verifying small file autostripe count is 1..."
7029         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7030                 error "cannot migrate 20MB file"
7031         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7032                 error "cannot get stripe for $dir/20mb"
7033         [ $stripe_count -eq 1 ] ||
7034                 error "unexpected stripe count $stripe_count for 20MB file"
7035         rm -f "$dir/20mb"
7036         echo "done"
7037
7038         # Test 2: File is small enough to fit within the available space on
7039         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7040         # have at least an additional 1KB for each desired stripe for test 3
7041         echo -n "Setting stripe for 1GB test file..."
7042         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7043         echo "done"
7044         echo -n "Sizing 1GB test file..."
7045         # File size is 1GB + 3KB
7046         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7047         echo "done"
7048
7049         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7050         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7051         if (( avail > 524288 * OSTCOUNT )); then
7052                 echo -n "Migrating 1GB file..."
7053                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7054                         error "cannot migrate 1GB file"
7055                 echo "done"
7056                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7057                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7058                         error "cannot getstripe for 1GB file"
7059                 [ $stripe_count -eq 2 ] ||
7060                         error "unexpected stripe count $stripe_count != 2"
7061                 echo "done"
7062         fi
7063
7064         # Test 3: File is too large to fit within the available space on
7065         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7066         if [ $OSTCOUNT -ge 3 ]; then
7067                 # The required available space is calculated as
7068                 # file size (1GB + 3KB) / OST count (3).
7069                 local kb_per_ost=349526
7070
7071                 echo -n "Migrating 1GB file with limit..."
7072                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7073                         error "cannot migrate 1GB file with limit"
7074                 echo "done"
7075
7076                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7077                 echo -n "Verifying 1GB autostripe count with limited space..."
7078                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7079                         error "unexpected stripe count $stripe_count (min 3)"
7080                 echo "done"
7081         fi
7082
7083         # clean up
7084         rm -rf $dir
7085 }
7086 run_test 56xc "lfs migration autostripe"
7087
7088 test_56xd() {
7089         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7090
7091         local dir=$DIR/$tdir
7092         local f_mgrt=$dir/$tfile.mgrt
7093         local f_yaml=$dir/$tfile.yaml
7094         local f_copy=$dir/$tfile.copy
7095         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7096         local layout_copy="-c 2 -S 2M -i 1"
7097         local yamlfile=$dir/yamlfile
7098         local layout_before;
7099         local layout_after;
7100
7101         test_mkdir "$dir" || error "cannot create dir $dir"
7102         $LFS setstripe $layout_yaml $f_yaml ||
7103                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7104         $LFS getstripe --yaml $f_yaml > $yamlfile
7105         $LFS setstripe $layout_copy $f_copy ||
7106                 error "cannot setstripe $f_copy with layout $layout_copy"
7107         touch $f_mgrt
7108         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7109
7110         # 1. test option --yaml
7111         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7112                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7113         layout_before=$(get_layout_param $f_yaml)
7114         layout_after=$(get_layout_param $f_mgrt)
7115         [ "$layout_after" == "$layout_before" ] ||
7116                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7117
7118         # 2. test option --copy
7119         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7120                 error "cannot migrate $f_mgrt with --copy $f_copy"
7121         layout_before=$(get_layout_param $f_copy)
7122         layout_after=$(get_layout_param $f_mgrt)
7123         [ "$layout_after" == "$layout_before" ] ||
7124                 error "lfs_migrate --copy: $layout_after != $layout_before"
7125 }
7126 run_test 56xd "check lfs_migrate --yaml and --copy support"
7127
7128 test_56xe() {
7129         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7130
7131         local dir=$DIR/$tdir
7132         local f_comp=$dir/$tfile
7133         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7134         local layout_before=""
7135         local layout_after=""
7136
7137         test_mkdir "$dir" || error "cannot create dir $dir"
7138         $LFS setstripe $layout $f_comp ||
7139                 error "cannot setstripe $f_comp with layout $layout"
7140         layout_before=$(get_layout_param $f_comp)
7141         dd if=/dev/zero of=$f_comp bs=1M count=4
7142
7143         # 1. migrate a comp layout file by lfs_migrate
7144         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7145         layout_after=$(get_layout_param $f_comp)
7146         [ "$layout_before" == "$layout_after" ] ||
7147                 error "lfs_migrate: $layout_before != $layout_after"
7148
7149         # 2. migrate a comp layout file by lfs migrate
7150         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7151         layout_after=$(get_layout_param $f_comp)
7152         [ "$layout_before" == "$layout_after" ] ||
7153                 error "lfs migrate: $layout_before != $layout_after"
7154 }
7155 run_test 56xe "migrate a composite layout file"
7156
7157 test_56xf() {
7158         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7159
7160         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7161                 skip "Need server version at least 2.13.53"
7162
7163         local dir=$DIR/$tdir
7164         local f_comp=$dir/$tfile
7165         local layout="-E 1M -c1 -E -1 -c2"
7166         local fid_before=""
7167         local fid_after=""
7168
7169         test_mkdir "$dir" || error "cannot create dir $dir"
7170         $LFS setstripe $layout $f_comp ||
7171                 error "cannot setstripe $f_comp with layout $layout"
7172         fid_before=$($LFS getstripe --fid $f_comp)
7173         dd if=/dev/zero of=$f_comp bs=1M count=4
7174
7175         # 1. migrate a comp layout file to a comp layout
7176         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7177         fid_after=$($LFS getstripe --fid $f_comp)
7178         [ "$fid_before" == "$fid_after" ] ||
7179                 error "comp-to-comp migrate: $fid_before != $fid_after"
7180
7181         # 2. migrate a comp layout file to a plain layout
7182         $LFS migrate -c2 $f_comp ||
7183                 error "cannot migrate $f_comp by lfs migrate"
7184         fid_after=$($LFS getstripe --fid $f_comp)
7185         [ "$fid_before" == "$fid_after" ] ||
7186                 error "comp-to-plain migrate: $fid_before != $fid_after"
7187
7188         # 3. migrate a plain layout file to a comp layout
7189         $LFS migrate $layout $f_comp ||
7190                 error "cannot migrate $f_comp by lfs migrate"
7191         fid_after=$($LFS getstripe --fid $f_comp)
7192         [ "$fid_before" == "$fid_after" ] ||
7193                 error "plain-to-comp migrate: $fid_before != $fid_after"
7194 }
7195 run_test 56xf "FID is not lost during migration of a composite layout file"
7196
7197 test_56y() {
7198         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7199                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7200
7201         local res=""
7202         local dir=$DIR/$tdir
7203         local f1=$dir/file1
7204         local f2=$dir/file2
7205
7206         test_mkdir -p $dir || error "creating dir $dir"
7207         touch $f1 || error "creating std file $f1"
7208         $MULTIOP $f2 H2c || error "creating released file $f2"
7209
7210         # a directory can be raid0, so ask only for files
7211         res=$($LFS find $dir -L raid0 -type f | wc -l)
7212         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7213
7214         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7215         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7216
7217         # only files can be released, so no need to force file search
7218         res=$($LFS find $dir -L released)
7219         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7220
7221         res=$($LFS find $dir -type f \! -L released)
7222         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7223 }
7224 run_test 56y "lfs find -L raid0|released"
7225
7226 test_56z() { # LU-4824
7227         # This checks to make sure 'lfs find' continues after errors
7228         # There are two classes of errors that should be caught:
7229         # - If multiple paths are provided, all should be searched even if one
7230         #   errors out
7231         # - If errors are encountered during the search, it should not terminate
7232         #   early
7233         local dir=$DIR/$tdir
7234         local i
7235
7236         test_mkdir $dir
7237         for i in d{0..9}; do
7238                 test_mkdir $dir/$i
7239                 touch $dir/$i/$tfile
7240         done
7241         $LFS find $DIR/non_existent_dir $dir &&
7242                 error "$LFS find did not return an error"
7243         # Make a directory unsearchable. This should NOT be the last entry in
7244         # directory order.  Arbitrarily pick the 6th entry
7245         chmod 700 $($LFS find $dir -type d | sed '6!d')
7246
7247         $RUNAS $LFS find $DIR/non_existent $dir
7248         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7249
7250         # The user should be able to see 10 directories and 9 files
7251         (( count == 19 )) ||
7252                 error "$LFS find found $count != 19 entries after error"
7253 }
7254 run_test 56z "lfs find should continue after an error"
7255
7256 test_56aa() { # LU-5937
7257         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7258
7259         local dir=$DIR/$tdir
7260
7261         mkdir $dir
7262         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7263
7264         createmany -o $dir/striped_dir/${tfile}- 1024
7265         local dirs=$($LFS find --size +8k $dir/)
7266
7267         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7268 }
7269 run_test 56aa "lfs find --size under striped dir"
7270
7271 test_56ab() { # LU-10705
7272         test_mkdir $DIR/$tdir
7273         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7274         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7275         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7276         # Flush writes to ensure valid blocks.  Need to be more thorough for
7277         # ZFS, since blocks are not allocated/returned to client immediately.
7278         sync_all_data
7279         wait_zfs_commit ost1 2
7280         cancel_lru_locks osc
7281         ls -ls $DIR/$tdir
7282
7283         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7284
7285         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7286
7287         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7288         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7289
7290         rm -f $DIR/$tdir/$tfile.[123]
7291 }
7292 run_test 56ab "lfs find --blocks"
7293
7294 test_56ba() {
7295         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7296                 skip "Need MDS version at least 2.10.50"
7297
7298         # Create composite files with one component
7299         local dir=$DIR/$tdir
7300
7301         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7302         # Create composite files with three components
7303         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7304         # Create non-composite files
7305         createmany -o $dir/${tfile}- 10
7306
7307         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7308
7309         [[ $nfiles == 10 ]] ||
7310                 error "lfs find -E 1M found $nfiles != 10 files"
7311
7312         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7313         [[ $nfiles == 25 ]] ||
7314                 error "lfs find ! -E 1M found $nfiles != 25 files"
7315
7316         # All files have a component that starts at 0
7317         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7318         [[ $nfiles == 35 ]] ||
7319                 error "lfs find --component-start 0 - $nfiles != 35 files"
7320
7321         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7322         [[ $nfiles == 15 ]] ||
7323                 error "lfs find --component-start 2M - $nfiles != 15 files"
7324
7325         # All files created here have a componenet that does not starts at 2M
7326         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7327         [[ $nfiles == 35 ]] ||
7328                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7329
7330         # Find files with a specified number of components
7331         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7332         [[ $nfiles == 15 ]] ||
7333                 error "lfs find --component-count 3 - $nfiles != 15 files"
7334
7335         # Remember non-composite files have a component count of zero
7336         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7337         [[ $nfiles == 10 ]] ||
7338                 error "lfs find --component-count 0 - $nfiles != 10 files"
7339
7340         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7341         [[ $nfiles == 20 ]] ||
7342                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7343
7344         # All files have a flag called "init"
7345         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7346         [[ $nfiles == 35 ]] ||
7347                 error "lfs find --component-flags init - $nfiles != 35 files"
7348
7349         # Multi-component files will have a component not initialized
7350         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7351         [[ $nfiles == 15 ]] ||
7352                 error "lfs find !--component-flags init - $nfiles != 15 files"
7353
7354         rm -rf $dir
7355
7356 }
7357 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7358
7359 test_56ca() {
7360         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7361                 skip "Need MDS version at least 2.10.57"
7362
7363         local td=$DIR/$tdir
7364         local tf=$td/$tfile
7365         local dir
7366         local nfiles
7367         local cmd
7368         local i
7369         local j
7370
7371         # create mirrored directories and mirrored files
7372         mkdir $td || error "mkdir $td failed"
7373         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7374         createmany -o $tf- 10 || error "create $tf- failed"
7375
7376         for i in $(seq 2); do
7377                 dir=$td/dir$i
7378                 mkdir $dir || error "mkdir $dir failed"
7379                 $LFS mirror create -N$((3 + i)) $dir ||
7380                         error "create mirrored dir $dir failed"
7381                 createmany -o $dir/$tfile- 10 ||
7382                         error "create $dir/$tfile- failed"
7383         done
7384
7385         # change the states of some mirrored files
7386         echo foo > $tf-6
7387         for i in $(seq 2); do
7388                 dir=$td/dir$i
7389                 for j in $(seq 4 9); do
7390                         echo foo > $dir/$tfile-$j
7391                 done
7392         done
7393
7394         # find mirrored files with specific mirror count
7395         cmd="$LFS find --mirror-count 3 --type f $td"
7396         nfiles=$($cmd | wc -l)
7397         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7398
7399         cmd="$LFS find ! --mirror-count 3 --type f $td"
7400         nfiles=$($cmd | wc -l)
7401         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7402
7403         cmd="$LFS find --mirror-count +2 --type f $td"
7404         nfiles=$($cmd | wc -l)
7405         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7406
7407         cmd="$LFS find --mirror-count -6 --type f $td"
7408         nfiles=$($cmd | wc -l)
7409         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7410
7411         # find mirrored files with specific file state
7412         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7413         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7414
7415         cmd="$LFS find --mirror-state=ro --type f $td"
7416         nfiles=$($cmd | wc -l)
7417         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7418
7419         cmd="$LFS find ! --mirror-state=ro --type f $td"
7420         nfiles=$($cmd | wc -l)
7421         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7422
7423         cmd="$LFS find --mirror-state=wp --type f $td"
7424         nfiles=$($cmd | wc -l)
7425         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7426
7427         cmd="$LFS find ! --mirror-state=sp --type f $td"
7428         nfiles=$($cmd | wc -l)
7429         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7430 }
7431 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7432
7433 test_57a() {
7434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7435         # note test will not do anything if MDS is not local
7436         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7437                 skip_env "ldiskfs only test"
7438         fi
7439         remote_mds_nodsh && skip "remote MDS with nodsh"
7440
7441         local MNTDEV="osd*.*MDT*.mntdev"
7442         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7443         [ -z "$DEV" ] && error "can't access $MNTDEV"
7444         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7445                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7446                         error "can't access $DEV"
7447                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7448                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7449                 rm $TMP/t57a.dump
7450         done
7451 }
7452 run_test 57a "verify MDS filesystem created with large inodes =="
7453
7454 test_57b() {
7455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7456         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7457                 skip_env "ldiskfs only test"
7458         fi
7459         remote_mds_nodsh && skip "remote MDS with nodsh"
7460
7461         local dir=$DIR/$tdir
7462         local filecount=100
7463         local file1=$dir/f1
7464         local fileN=$dir/f$filecount
7465
7466         rm -rf $dir || error "removing $dir"
7467         test_mkdir -c1 $dir
7468         local mdtidx=$($LFS getstripe -m $dir)
7469         local mdtname=MDT$(printf %04x $mdtidx)
7470         local facet=mds$((mdtidx + 1))
7471
7472         echo "mcreating $filecount files"
7473         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7474
7475         # verify that files do not have EAs yet
7476         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7477                 error "$file1 has an EA"
7478         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7479                 error "$fileN has an EA"
7480
7481         sync
7482         sleep 1
7483         df $dir  #make sure we get new statfs data
7484         local mdsfree=$(do_facet $facet \
7485                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7486         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7487         local file
7488
7489         echo "opening files to create objects/EAs"
7490         for file in $(seq -f $dir/f%g 1 $filecount); do
7491                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7492                         error "opening $file"
7493         done
7494
7495         # verify that files have EAs now
7496         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7497         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7498
7499         sleep 1  #make sure we get new statfs data
7500         df $dir
7501         local mdsfree2=$(do_facet $facet \
7502                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7503         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7504
7505         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7506                 if [ "$mdsfree" != "$mdsfree2" ]; then
7507                         error "MDC before $mdcfree != after $mdcfree2"
7508                 else
7509                         echo "MDC before $mdcfree != after $mdcfree2"
7510                         echo "unable to confirm if MDS has large inodes"
7511                 fi
7512         fi
7513         rm -rf $dir
7514 }
7515 run_test 57b "default LOV EAs are stored inside large inodes ==="
7516
7517 test_58() {
7518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7519         [ -z "$(which wiretest 2>/dev/null)" ] &&
7520                         skip_env "could not find wiretest"
7521
7522         wiretest
7523 }
7524 run_test 58 "verify cross-platform wire constants =============="
7525
7526 test_59() {
7527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7528
7529         echo "touch 130 files"
7530         createmany -o $DIR/f59- 130
7531         echo "rm 130 files"
7532         unlinkmany $DIR/f59- 130
7533         sync
7534         # wait for commitment of removal
7535         wait_delete_completed
7536 }
7537 run_test 59 "verify cancellation of llog records async ========="
7538
7539 TEST60_HEAD="test_60 run $RANDOM"
7540 test_60a() {
7541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7542         remote_mgs_nodsh && skip "remote MGS with nodsh"
7543         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7544                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7545                         skip_env "missing subtest run-llog.sh"
7546
7547         log "$TEST60_HEAD - from kernel mode"
7548         do_facet mgs "$LCTL dk > /dev/null"
7549         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7550         do_facet mgs $LCTL dk > $TMP/$tfile
7551
7552         # LU-6388: test llog_reader
7553         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7554         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7555         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7556                         skip_env "missing llog_reader"
7557         local fstype=$(facet_fstype mgs)
7558         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7559                 skip_env "Only for ldiskfs or zfs type mgs"
7560
7561         local mntpt=$(facet_mntpt mgs)
7562         local mgsdev=$(mgsdevname 1)
7563         local fid_list
7564         local fid
7565         local rec_list
7566         local rec
7567         local rec_type
7568         local obj_file
7569         local path
7570         local seq
7571         local oid
7572         local pass=true
7573
7574         #get fid and record list
7575         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7576                 tail -n 4))
7577         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7578                 tail -n 4))
7579         #remount mgs as ldiskfs or zfs type
7580         stop mgs || error "stop mgs failed"
7581         mount_fstype mgs || error "remount mgs failed"
7582         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7583                 fid=${fid_list[i]}
7584                 rec=${rec_list[i]}
7585                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7586                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7587                 oid=$((16#$oid))
7588
7589                 case $fstype in
7590                         ldiskfs )
7591                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7592                         zfs )
7593                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7594                 esac
7595                 echo "obj_file is $obj_file"
7596                 do_facet mgs $llog_reader $obj_file
7597
7598                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7599                         awk '{ print $3 }' | sed -e "s/^type=//g")
7600                 if [ $rec_type != $rec ]; then
7601                         echo "FAILED test_60a wrong record type $rec_type," \
7602                               "should be $rec"
7603                         pass=false
7604                         break
7605                 fi
7606
7607                 #check obj path if record type is LLOG_LOGID_MAGIC
7608                 if [ "$rec" == "1064553b" ]; then
7609                         path=$(do_facet mgs $llog_reader $obj_file |
7610                                 grep "path=" | awk '{ print $NF }' |
7611                                 sed -e "s/^path=//g")
7612                         if [ $obj_file != $mntpt/$path ]; then
7613                                 echo "FAILED test_60a wrong obj path" \
7614                                       "$montpt/$path, should be $obj_file"
7615                                 pass=false
7616                                 break
7617                         fi
7618                 fi
7619         done
7620         rm -f $TMP/$tfile
7621         #restart mgs before "error", otherwise it will block the next test
7622         stop mgs || error "stop mgs failed"
7623         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7624         $pass || error "test failed, see FAILED test_60a messages for specifics"
7625 }
7626 run_test 60a "llog_test run from kernel module and test llog_reader"
7627
7628 test_60b() { # bug 6411
7629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7630
7631         dmesg > $DIR/$tfile
7632         LLOG_COUNT=$(do_facet mgs dmesg |
7633                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7634                           /llog_[a-z]*.c:[0-9]/ {
7635                                 if (marker)
7636                                         from_marker++
7637                                 from_begin++
7638                           }
7639                           END {
7640                                 if (marker)
7641                                         print from_marker
7642                                 else
7643                                         print from_begin
7644                           }")
7645
7646         [[ $LLOG_COUNT -gt 120 ]] &&
7647                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7648 }
7649 run_test 60b "limit repeated messages from CERROR/CWARN"
7650
7651 test_60c() {
7652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7653
7654         echo "create 5000 files"
7655         createmany -o $DIR/f60c- 5000
7656 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7657         lctl set_param fail_loc=0x80000137
7658         unlinkmany $DIR/f60c- 5000
7659         lctl set_param fail_loc=0
7660 }
7661 run_test 60c "unlink file when mds full"
7662
7663 test_60d() {
7664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7665
7666         SAVEPRINTK=$(lctl get_param -n printk)
7667         # verify "lctl mark" is even working"
7668         MESSAGE="test message ID $RANDOM $$"
7669         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7670         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7671
7672         lctl set_param printk=0 || error "set lnet.printk failed"
7673         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7674         MESSAGE="new test message ID $RANDOM $$"
7675         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7676         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7677         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7678
7679         lctl set_param -n printk="$SAVEPRINTK"
7680 }
7681 run_test 60d "test printk console message masking"
7682
7683 test_60e() {
7684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7685         remote_mds_nodsh && skip "remote MDS with nodsh"
7686
7687         touch $DIR/$tfile
7688 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7689         do_facet mds1 lctl set_param fail_loc=0x15b
7690         rm $DIR/$tfile
7691 }
7692 run_test 60e "no space while new llog is being created"
7693
7694 test_60g() {
7695         local pid
7696         local i
7697
7698         test_mkdir -c $MDSCOUNT $DIR/$tdir
7699
7700         (
7701                 local index=0
7702                 while true; do
7703                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7704                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7705                                 2>/dev/null
7706                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7707                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7708                         index=$((index + 1))
7709                 done
7710         ) &
7711
7712         pid=$!
7713
7714         for i in {0..100}; do
7715                 # define OBD_FAIL_OSD_TXN_START    0x19a
7716                 local index=$((i % MDSCOUNT + 1))
7717
7718                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7719                         > /dev/null
7720                 usleep 100
7721         done
7722
7723         kill -9 $pid
7724
7725         for i in $(seq $MDSCOUNT); do
7726                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7727         done
7728
7729         mkdir $DIR/$tdir/new || error "mkdir failed"
7730         rmdir $DIR/$tdir/new || error "rmdir failed"
7731
7732         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7733                 -t namespace
7734         for i in $(seq $MDSCOUNT); do
7735                 wait_update_facet mds$i "$LCTL get_param -n \
7736                         mdd.$(facet_svc mds$i).lfsck_namespace |
7737                         awk '/^status/ { print \\\$2 }'" "completed"
7738         done
7739
7740         ls -R $DIR/$tdir || error "ls failed"
7741         rm -rf $DIR/$tdir || error "rmdir failed"
7742 }
7743 run_test 60g "transaction abort won't cause MDT hung"
7744
7745 test_60h() {
7746         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7747                 skip "Need MDS version at least 2.12.52"
7748         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7749
7750         local f
7751
7752         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7753         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7754         for fail_loc in 0x80000188 0x80000189; do
7755                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7756                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7757                         error "mkdir $dir-$fail_loc failed"
7758                 for i in {0..10}; do
7759                         # create may fail on missing stripe
7760                         echo $i > $DIR/$tdir-$fail_loc/$i
7761                 done
7762                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7763                         error "getdirstripe $tdir-$fail_loc failed"
7764                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7765                         error "migrate $tdir-$fail_loc failed"
7766                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7767                         error "getdirstripe $tdir-$fail_loc failed"
7768                 pushd $DIR/$tdir-$fail_loc
7769                 for f in *; do
7770                         echo $f | cmp $f - || error "$f data mismatch"
7771                 done
7772                 popd
7773                 rm -rf $DIR/$tdir-$fail_loc
7774         done
7775 }
7776 run_test 60h "striped directory with missing stripes can be accessed"
7777
7778 test_61a() {
7779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7780
7781         f="$DIR/f61"
7782         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7783         cancel_lru_locks osc
7784         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7785         sync
7786 }
7787 run_test 61a "mmap() writes don't make sync hang ================"
7788
7789 test_61b() {
7790         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7791 }
7792 run_test 61b "mmap() of unstriped file is successful"
7793
7794 # bug 2330 - insufficient obd_match error checking causes LBUG
7795 test_62() {
7796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7797
7798         f="$DIR/f62"
7799         echo foo > $f
7800         cancel_lru_locks osc
7801         lctl set_param fail_loc=0x405
7802         cat $f && error "cat succeeded, expect -EIO"
7803         lctl set_param fail_loc=0
7804 }
7805 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7806 # match every page all of the time.
7807 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7808
7809 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7810 # Though this test is irrelevant anymore, it helped to reveal some
7811 # other grant bugs (LU-4482), let's keep it.
7812 test_63a() {   # was test_63
7813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7814
7815         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7816
7817         for i in `seq 10` ; do
7818                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7819                 sleep 5
7820                 kill $!
7821                 sleep 1
7822         done
7823
7824         rm -f $DIR/f63 || true
7825 }
7826 run_test 63a "Verify oig_wait interruption does not crash ======="
7827
7828 # bug 2248 - async write errors didn't return to application on sync
7829 # bug 3677 - async write errors left page locked
7830 test_63b() {
7831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7832
7833         debugsave
7834         lctl set_param debug=-1
7835
7836         # ensure we have a grant to do async writes
7837         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7838         rm $DIR/$tfile
7839
7840         sync    # sync lest earlier test intercept the fail_loc
7841
7842         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7843         lctl set_param fail_loc=0x80000406
7844         $MULTIOP $DIR/$tfile Owy && \
7845                 error "sync didn't return ENOMEM"
7846         sync; sleep 2; sync     # do a real sync this time to flush page
7847         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7848                 error "locked page left in cache after async error" || true
7849         debugrestore
7850 }
7851 run_test 63b "async write errors should be returned to fsync ==="
7852
7853 test_64a () {
7854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7855
7856         lfs df $DIR
7857         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7858 }
7859 run_test 64a "verify filter grant calculations (in kernel) ====="
7860
7861 test_64b () {
7862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7863
7864         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7865 }
7866 run_test 64b "check out-of-space detection on client"
7867
7868 test_64c() {
7869         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7870 }
7871 run_test 64c "verify grant shrink"
7872
7873 import_param() {
7874         local tgt=$1
7875         local param=$2
7876
7877         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7878 }
7879
7880 # this does exactly what osc_request.c:osc_announce_cached() does in
7881 # order to calculate max amount of grants to ask from server
7882 want_grant() {
7883         local tgt=$1
7884
7885         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7886         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7887
7888         ((rpc_in_flight++));
7889         nrpages=$((nrpages * rpc_in_flight))
7890
7891         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7892
7893         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7894
7895         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7896         local undirty=$((nrpages * PAGE_SIZE))
7897
7898         local max_extent_pages
7899         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7900         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7901         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7902         local grant_extent_tax
7903         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7904
7905         undirty=$((undirty + nrextents * grant_extent_tax))
7906
7907         echo $undirty
7908 }
7909
7910 # this is size of unit for grant allocation. It should be equal to
7911 # what tgt_grant.c:tgt_grant_chunk() calculates
7912 grant_chunk() {
7913         local tgt=$1
7914         local max_brw_size
7915         local grant_extent_tax
7916
7917         max_brw_size=$(import_param $tgt max_brw_size)
7918
7919         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7920
7921         echo $(((max_brw_size + grant_extent_tax) * 2))
7922 }
7923
7924 test_64d() {
7925         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7926                 skip "OST < 2.10.55 doesn't limit grants enough"
7927
7928         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7929
7930         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7931                 skip "no grant_param connect flag"
7932
7933         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7934
7935         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7936         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7937
7938
7939         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7940         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7941
7942         $LFS setstripe $DIR/$tfile -i 0 -c 1
7943         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7944         ddpid=$!
7945
7946         while kill -0 $ddpid; do
7947                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7948
7949                 if [[ $cur_grant -gt $max_cur_granted ]]; then
7950                         kill $ddpid
7951                         error "cur_grant $cur_grant > $max_cur_granted"
7952                 fi
7953
7954                 sleep 1
7955         done
7956 }
7957 run_test 64d "check grant limit exceed"
7958
7959 check_grants() {
7960         local tgt=$1
7961         local expected=$2
7962         local msg=$3
7963         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7964
7965         ((cur_grants == expected)) ||
7966                 error "$msg: grants mismatch: $cur_grants, expected $expected"
7967 }
7968
7969 round_up_p2() {
7970         echo $((($1 + $2 - 1) & ~($2 - 1)))
7971 }
7972
7973 test_64e() {
7974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7975         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
7976                 skip "Need OSS version at least 2.11.56"
7977
7978         # Remount client to reset grant
7979         remount_client $MOUNT || error "failed to remount client"
7980         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
7981
7982         local init_grants=$(import_param $osc_tgt initial_grant)
7983
7984         check_grants $osc_tgt $init_grants "init grants"
7985
7986         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
7987         local max_brw_size=$(import_param $osc_tgt max_brw_size)
7988         local gbs=$(import_param $osc_tgt grant_block_size)
7989
7990         # write random number of bytes from max_brw_size / 4 to max_brw_size
7991         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
7992         # align for direct io
7993         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
7994         # round to grant consumption unit
7995         local wb_round_up=$(round_up_p2 $write_bytes gbs)
7996
7997         local grants=$((wb_round_up + extent_tax))
7998
7999         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8000
8001         # define OBD_FAIL_TGT_NO_GRANT 0x725
8002         # make the server not grant more back
8003         do_facet ost1 $LCTL set_param fail_loc=0x725
8004         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8005
8006         do_facet ost1 $LCTL set_param fail_loc=0
8007
8008         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8009
8010         rm -f $DIR/$tfile || error "rm failed"
8011
8012         # Remount client to reset grant
8013         remount_client $MOUNT || error "failed to remount client"
8014         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8015
8016         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8017
8018         # define OBD_FAIL_TGT_NO_GRANT 0x725
8019         # make the server not grant more back
8020         do_facet ost1 $LCTL set_param fail_loc=0x725
8021         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8022         do_facet ost1 $LCTL set_param fail_loc=0
8023
8024         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8025 }
8026 run_test 64e "check grant consumption (no grant allocation)"
8027
8028 test_64f() {
8029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8030
8031         # Remount client to reset grant
8032         remount_client $MOUNT || error "failed to remount client"
8033         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8034
8035         local init_grants=$(import_param $osc_tgt initial_grant)
8036         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8037         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8038         local gbs=$(import_param $osc_tgt grant_block_size)
8039         local chunk=$(grant_chunk $osc_tgt)
8040
8041         # write random number of bytes from max_brw_size / 4 to max_brw_size
8042         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8043         # align for direct io
8044         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8045         # round to grant consumption unit
8046         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8047
8048         local grants=$((wb_round_up + extent_tax))
8049
8050         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8051         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8052                 error "error writing to $DIR/$tfile"
8053
8054         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8055                 "direct io with grant allocation"
8056
8057         rm -f $DIR/$tfile || error "rm failed"
8058
8059         # Remount client to reset grant
8060         remount_client $MOUNT || error "failed to remount client"
8061         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8062
8063         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8064
8065         local cmd="oO_WRONLY:w${write_bytes}_yc"
8066
8067         $MULTIOP $DIR/$tfile $cmd &
8068         MULTIPID=$!
8069         sleep 1
8070
8071         check_grants $osc_tgt $((init_grants - grants)) \
8072                 "buffered io, not write rpc"
8073
8074         kill -USR1 $MULTIPID
8075         wait
8076
8077         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8078                 "buffered io, one RPC"
8079 }
8080 run_test 64f "check grant consumption (with grant allocation)"
8081
8082 # bug 1414 - set/get directories' stripe info
8083 test_65a() {
8084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8085
8086         test_mkdir $DIR/$tdir
8087         touch $DIR/$tdir/f1
8088         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8089 }
8090 run_test 65a "directory with no stripe info"
8091
8092 test_65b() {
8093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8094
8095         test_mkdir $DIR/$tdir
8096         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8097
8098         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8099                                                 error "setstripe"
8100         touch $DIR/$tdir/f2
8101         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8102 }
8103 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8104
8105 test_65c() {
8106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8107         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8108
8109         test_mkdir $DIR/$tdir
8110         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8111
8112         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8113                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8114         touch $DIR/$tdir/f3
8115         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8116 }
8117 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8118
8119 test_65d() {
8120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8121
8122         test_mkdir $DIR/$tdir
8123         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8124         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8125
8126         if [[ $STRIPECOUNT -le 0 ]]; then
8127                 sc=1
8128         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8129                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8130                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8131         else
8132                 sc=$(($STRIPECOUNT - 1))
8133         fi
8134         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8135         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8136         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8137                 error "lverify failed"
8138 }
8139 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8140
8141 test_65e() {
8142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8143
8144         test_mkdir $DIR/$tdir
8145
8146         $LFS setstripe $DIR/$tdir || error "setstripe"
8147         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8148                                         error "no stripe info failed"
8149         touch $DIR/$tdir/f6
8150         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8151 }
8152 run_test 65e "directory setstripe defaults"
8153
8154 test_65f() {
8155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8156
8157         test_mkdir $DIR/${tdir}f
8158         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8159                 error "setstripe succeeded" || true
8160 }
8161 run_test 65f "dir setstripe permission (should return error) ==="
8162
8163 test_65g() {
8164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8165
8166         test_mkdir $DIR/$tdir
8167         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8168
8169         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8170                 error "setstripe -S failed"
8171         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8172         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8173                 error "delete default stripe failed"
8174 }
8175 run_test 65g "directory setstripe -d"
8176
8177 test_65h() {
8178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8179
8180         test_mkdir $DIR/$tdir
8181         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8182
8183         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8184                 error "setstripe -S failed"
8185         test_mkdir $DIR/$tdir/dd1
8186         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8187                 error "stripe info inherit failed"
8188 }
8189 run_test 65h "directory stripe info inherit ===================="
8190
8191 test_65i() {
8192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8193
8194         save_layout_restore_at_exit $MOUNT
8195
8196         # bug6367: set non-default striping on root directory
8197         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8198
8199         # bug12836: getstripe on -1 default directory striping
8200         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8201
8202         # bug12836: getstripe -v on -1 default directory striping
8203         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8204
8205         # bug12836: new find on -1 default directory striping
8206         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8207 }
8208 run_test 65i "various tests to set root directory striping"
8209
8210 test_65j() { # bug6367
8211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8212
8213         sync; sleep 1
8214
8215         # if we aren't already remounting for each test, do so for this test
8216         if [ "$I_MOUNTED" = "yes" ]; then
8217                 cleanup || error "failed to unmount"
8218                 setup
8219         fi
8220
8221         save_layout_restore_at_exit $MOUNT
8222
8223         $LFS setstripe -d $MOUNT || error "setstripe failed"
8224 }
8225 run_test 65j "set default striping on root directory (bug 6367)="
8226
8227 cleanup_65k() {
8228         rm -rf $DIR/$tdir
8229         wait_delete_completed
8230         do_facet $SINGLEMDS "lctl set_param -n \
8231                 osp.$ost*MDT0000.max_create_count=$max_count"
8232         do_facet $SINGLEMDS "lctl set_param -n \
8233                 osp.$ost*MDT0000.create_count=$count"
8234         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8235         echo $INACTIVE_OSC "is Activate"
8236
8237         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8238 }
8239
8240 test_65k() { # bug11679
8241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8242         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8243         remote_mds_nodsh && skip "remote MDS with nodsh"
8244
8245         local disable_precreate=true
8246         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8247                 disable_precreate=false
8248
8249         echo "Check OST status: "
8250         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8251                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8252
8253         for OSC in $MDS_OSCS; do
8254                 echo $OSC "is active"
8255                 do_facet $SINGLEMDS lctl --device %$OSC activate
8256         done
8257
8258         for INACTIVE_OSC in $MDS_OSCS; do
8259                 local ost=$(osc_to_ost $INACTIVE_OSC)
8260                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8261                                lov.*md*.target_obd |
8262                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8263
8264                 mkdir -p $DIR/$tdir
8265                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8266                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8267
8268                 echo "Deactivate: " $INACTIVE_OSC
8269                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8270
8271                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8272                               osp.$ost*MDT0000.create_count")
8273                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8274                                   osp.$ost*MDT0000.max_create_count")
8275                 $disable_precreate &&
8276                         do_facet $SINGLEMDS "lctl set_param -n \
8277                                 osp.$ost*MDT0000.max_create_count=0"
8278
8279                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8280                         [ -f $DIR/$tdir/$idx ] && continue
8281                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8282                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8283                                 { cleanup_65k;
8284                                   error "setstripe $idx should succeed"; }
8285                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8286                 done
8287                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8288                 rmdir $DIR/$tdir
8289
8290                 do_facet $SINGLEMDS "lctl set_param -n \
8291                         osp.$ost*MDT0000.max_create_count=$max_count"
8292                 do_facet $SINGLEMDS "lctl set_param -n \
8293                         osp.$ost*MDT0000.create_count=$count"
8294                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8295                 echo $INACTIVE_OSC "is Activate"
8296
8297                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8298         done
8299 }
8300 run_test 65k "validate manual striping works properly with deactivated OSCs"
8301
8302 test_65l() { # bug 12836
8303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8304
8305         test_mkdir -p $DIR/$tdir/test_dir
8306         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8307         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8308 }
8309 run_test 65l "lfs find on -1 stripe dir ========================"
8310
8311 test_65m() {
8312         local layout=$(save_layout $MOUNT)
8313         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8314                 restore_layout $MOUNT $layout
8315                 error "setstripe should fail by non-root users"
8316         }
8317         true
8318 }
8319 run_test 65m "normal user can't set filesystem default stripe"
8320
8321 test_65n() {
8322         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8323         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8324                 skip "Need MDS version at least 2.12.50"
8325         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8326
8327         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8328         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8329         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8330
8331         local root_layout=$(save_layout $MOUNT)
8332         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8333
8334         # new subdirectory under root directory should not inherit
8335         # the default layout from root
8336         local dir1=$MOUNT/$tdir-1
8337         mkdir $dir1 || error "mkdir $dir1 failed"
8338         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8339                 error "$dir1 shouldn't have LOV EA"
8340
8341         # delete the default layout on root directory
8342         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8343
8344         local dir2=$MOUNT/$tdir-2
8345         mkdir $dir2 || error "mkdir $dir2 failed"
8346         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8347                 error "$dir2 shouldn't have LOV EA"
8348
8349         # set a new striping pattern on root directory
8350         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8351         local new_def_stripe_size=$((def_stripe_size * 2))
8352         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8353                 error "set stripe size on $MOUNT failed"
8354
8355         # new file created in $dir2 should inherit the new stripe size from
8356         # the filesystem default
8357         local file2=$dir2/$tfile-2
8358         touch $file2 || error "touch $file2 failed"
8359
8360         local file2_stripe_size=$($LFS getstripe -S $file2)
8361         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8362                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8363
8364         local dir3=$MOUNT/$tdir-3
8365         mkdir $dir3 || error "mkdir $dir3 failed"
8366         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8367         # the root layout, which is the actual default layout that will be used
8368         # when new files are created in $dir3.
8369         local dir3_layout=$(get_layout_param $dir3)
8370         local root_dir_layout=$(get_layout_param $MOUNT)
8371         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8372                 error "$dir3 should show the default layout from $MOUNT"
8373
8374         # set OST pool on root directory
8375         local pool=$TESTNAME
8376         pool_add $pool || error "add $pool failed"
8377         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8378                 error "add targets to $pool failed"
8379
8380         $LFS setstripe -p $pool $MOUNT ||
8381                 error "set OST pool on $MOUNT failed"
8382
8383         # new file created in $dir3 should inherit the pool from
8384         # the filesystem default
8385         local file3=$dir3/$tfile-3
8386         touch $file3 || error "touch $file3 failed"
8387
8388         local file3_pool=$($LFS getstripe -p $file3)
8389         [[ "$file3_pool" = "$pool" ]] ||
8390                 error "$file3 didn't inherit OST pool $pool"
8391
8392         local dir4=$MOUNT/$tdir-4
8393         mkdir $dir4 || error "mkdir $dir4 failed"
8394         local dir4_layout=$(get_layout_param $dir4)
8395         root_dir_layout=$(get_layout_param $MOUNT)
8396         echo "$LFS getstripe -d $dir4"
8397         $LFS getstripe -d $dir4
8398         echo "$LFS getstripe -d $MOUNT"
8399         $LFS getstripe -d $MOUNT
8400         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8401                 error "$dir4 should show the default layout from $MOUNT"
8402
8403         # new file created in $dir4 should inherit the pool from
8404         # the filesystem default
8405         local file4=$dir4/$tfile-4
8406         touch $file4 || error "touch $file4 failed"
8407
8408         local file4_pool=$($LFS getstripe -p $file4)
8409         [[ "$file4_pool" = "$pool" ]] ||
8410                 error "$file4 didn't inherit OST pool $pool"
8411
8412         # new subdirectory under non-root directory should inherit
8413         # the default layout from its parent directory
8414         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8415                 error "set directory layout on $dir4 failed"
8416
8417         local dir5=$dir4/$tdir-5
8418         mkdir $dir5 || error "mkdir $dir5 failed"
8419
8420         dir4_layout=$(get_layout_param $dir4)
8421         local dir5_layout=$(get_layout_param $dir5)
8422         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8423                 error "$dir5 should inherit the default layout from $dir4"
8424
8425         # though subdir under ROOT doesn't inherit default layout, but
8426         # its sub dir/file should be created with default layout.
8427         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8428         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8429                 skip "Need MDS version at least 2.12.59"
8430
8431         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8432         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8433         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8434
8435         if [ $default_lmv_hash == "none" ]; then
8436                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8437         else
8438                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8439                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8440         fi
8441
8442         $LFS setdirstripe -D -c 2 $MOUNT ||
8443                 error "setdirstripe -D -c 2 failed"
8444         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8445         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8446         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8447 }
8448 run_test 65n "don't inherit default layout from root for new subdirectories"
8449
8450 # bug 2543 - update blocks count on client
8451 test_66() {
8452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8453
8454         COUNT=${COUNT:-8}
8455         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8456         sync; sync_all_data; sync; sync_all_data
8457         cancel_lru_locks osc
8458         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8459         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8460 }
8461 run_test 66 "update inode blocks count on client ==============="
8462
8463 meminfo() {
8464         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8465 }
8466
8467 swap_used() {
8468         swapon -s | awk '($1 == "'$1'") { print $4 }'
8469 }
8470
8471 # bug5265, obdfilter oa2dentry return -ENOENT
8472 # #define OBD_FAIL_SRV_ENOENT 0x217
8473 test_69() {
8474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8475         remote_ost_nodsh && skip "remote OST with nodsh"
8476
8477         f="$DIR/$tfile"
8478         $LFS setstripe -c 1 -i 0 $f
8479
8480         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8481
8482         do_facet ost1 lctl set_param fail_loc=0x217
8483         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8484         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8485
8486         do_facet ost1 lctl set_param fail_loc=0
8487         $DIRECTIO write $f 0 2 || error "write error"
8488
8489         cancel_lru_locks osc
8490         $DIRECTIO read $f 0 1 || error "read error"
8491
8492         do_facet ost1 lctl set_param fail_loc=0x217
8493         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8494
8495         do_facet ost1 lctl set_param fail_loc=0
8496         rm -f $f
8497 }
8498 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8499
8500 test_71() {
8501         test_mkdir $DIR/$tdir
8502         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8503         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8504 }
8505 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8506
8507 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8509         [ "$RUNAS_ID" = "$UID" ] &&
8510                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8511         # Check that testing environment is properly set up. Skip if not
8512         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8513                 skip_env "User $RUNAS_ID does not exist - skipping"
8514
8515         touch $DIR/$tfile
8516         chmod 777 $DIR/$tfile
8517         chmod ug+s $DIR/$tfile
8518         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8519                 error "$RUNAS dd $DIR/$tfile failed"
8520         # See if we are still setuid/sgid
8521         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8522                 error "S/gid is not dropped on write"
8523         # Now test that MDS is updated too
8524         cancel_lru_locks mdc
8525         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8526                 error "S/gid is not dropped on MDS"
8527         rm -f $DIR/$tfile
8528 }
8529 run_test 72a "Test that remove suid works properly (bug5695) ===="
8530
8531 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8532         local perm
8533
8534         [ "$RUNAS_ID" = "$UID" ] &&
8535                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8536         [ "$RUNAS_ID" -eq 0 ] &&
8537                 skip_env "RUNAS_ID = 0 -- skipping"
8538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8539         # Check that testing environment is properly set up. Skip if not
8540         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8541                 skip_env "User $RUNAS_ID does not exist - skipping"
8542
8543         touch $DIR/${tfile}-f{g,u}
8544         test_mkdir $DIR/${tfile}-dg
8545         test_mkdir $DIR/${tfile}-du
8546         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8547         chmod g+s $DIR/${tfile}-{f,d}g
8548         chmod u+s $DIR/${tfile}-{f,d}u
8549         for perm in 777 2777 4777; do
8550                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8551                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8552                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8553                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8554         done
8555         true
8556 }
8557 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8558
8559 # bug 3462 - multiple simultaneous MDC requests
8560 test_73() {
8561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8562
8563         test_mkdir $DIR/d73-1
8564         test_mkdir $DIR/d73-2
8565         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8566         pid1=$!
8567
8568         lctl set_param fail_loc=0x80000129
8569         $MULTIOP $DIR/d73-1/f73-2 Oc &
8570         sleep 1
8571         lctl set_param fail_loc=0
8572
8573         $MULTIOP $DIR/d73-2/f73-3 Oc &
8574         pid3=$!
8575
8576         kill -USR1 $pid1
8577         wait $pid1 || return 1
8578
8579         sleep 25
8580
8581         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8582         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8583         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8584
8585         rm -rf $DIR/d73-*
8586 }
8587 run_test 73 "multiple MDC requests (should not deadlock)"
8588
8589 test_74a() { # bug 6149, 6184
8590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8591
8592         touch $DIR/f74a
8593         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8594         #
8595         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8596         # will spin in a tight reconnection loop
8597         $LCTL set_param fail_loc=0x8000030e
8598         # get any lock that won't be difficult - lookup works.
8599         ls $DIR/f74a
8600         $LCTL set_param fail_loc=0
8601         rm -f $DIR/f74a
8602         true
8603 }
8604 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8605
8606 test_74b() { # bug 13310
8607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8608
8609         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8610         #
8611         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8612         # will spin in a tight reconnection loop
8613         $LCTL set_param fail_loc=0x8000030e
8614         # get a "difficult" lock
8615         touch $DIR/f74b
8616         $LCTL set_param fail_loc=0
8617         rm -f $DIR/f74b
8618         true
8619 }
8620 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8621
8622 test_74c() {
8623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8624
8625         #define OBD_FAIL_LDLM_NEW_LOCK
8626         $LCTL set_param fail_loc=0x319
8627         touch $DIR/$tfile && error "touch successful"
8628         $LCTL set_param fail_loc=0
8629         true
8630 }
8631 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8632
8633 num_inodes() {
8634         [ -f /sys/kernel/slab/lustre_inode_cache/shrink ] &&
8635                 echo 1 > /sys/kernel/slab/lustre_inode_cache/shrink
8636         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
8637 }
8638
8639 test_76() { # Now for bug 20433, added originally in bug 1443
8640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8641
8642         cancel_lru_locks osc
8643         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8644         local before=$(num_inodes)
8645         local count=$((512 * cpus))
8646         [ "$SLOW" = "no" ] && count=$((64 * cpus))
8647
8648         echo "before inodes: $before"
8649         for i in $(seq $count); do
8650                 touch $DIR/$tfile
8651                 rm -f $DIR/$tfile
8652         done
8653         cancel_lru_locks osc
8654         local after=$(num_inodes)
8655         echo "after inodes: $after"
8656         while (( after > before + 8 * ${cpus:-1} )); do
8657                 sleep 1
8658                 after=$(num_inodes)
8659                 wait=$((wait + 1))
8660                 (( wait % 5 == 0 )) && echo "wait $wait seconds inodes: $after"
8661                 if (( wait > 30 )); then
8662                         error "inode slab grew from $before to $after"
8663                 fi
8664         done
8665 }
8666 run_test 76 "confirm clients recycle inodes properly ===="
8667
8668
8669 export ORIG_CSUM=""
8670 set_checksums()
8671 {
8672         # Note: in sptlrpc modes which enable its own bulk checksum, the
8673         # original crc32_le bulk checksum will be automatically disabled,
8674         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8675         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8676         # In this case set_checksums() will not be no-op, because sptlrpc
8677         # bulk checksum will be enabled all through the test.
8678
8679         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8680         lctl set_param -n osc.*.checksums $1
8681         return 0
8682 }
8683
8684 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8685                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8686 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8687                              tr -d [] | head -n1)}
8688 set_checksum_type()
8689 {
8690         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8691         rc=$?
8692         log "set checksum type to $1, rc = $rc"
8693         return $rc
8694 }
8695
8696 get_osc_checksum_type()
8697 {
8698         # arugment 1: OST name, like OST0000
8699         ost=$1
8700         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8701                         sed 's/.*\[\(.*\)\].*/\1/g')
8702         rc=$?
8703         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8704         echo $checksum_type
8705 }
8706
8707 F77_TMP=$TMP/f77-temp
8708 F77SZ=8
8709 setup_f77() {
8710         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8711                 error "error writing to $F77_TMP"
8712 }
8713
8714 test_77a() { # bug 10889
8715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8716         $GSS && skip_env "could not run with gss"
8717
8718         [ ! -f $F77_TMP ] && setup_f77
8719         set_checksums 1
8720         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8721         set_checksums 0
8722         rm -f $DIR/$tfile
8723 }
8724 run_test 77a "normal checksum read/write operation"
8725
8726 test_77b() { # bug 10889
8727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8728         $GSS && skip_env "could not run with gss"
8729
8730         [ ! -f $F77_TMP ] && setup_f77
8731         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8732         $LCTL set_param fail_loc=0x80000409
8733         set_checksums 1
8734
8735         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8736                 error "dd error: $?"
8737         $LCTL set_param fail_loc=0
8738
8739         for algo in $CKSUM_TYPES; do
8740                 cancel_lru_locks osc
8741                 set_checksum_type $algo
8742                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8743                 $LCTL set_param fail_loc=0x80000408
8744                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8745                 $LCTL set_param fail_loc=0
8746         done
8747         set_checksums 0
8748         set_checksum_type $ORIG_CSUM_TYPE
8749         rm -f $DIR/$tfile
8750 }
8751 run_test 77b "checksum error on client write, read"
8752
8753 cleanup_77c() {
8754         trap 0
8755         set_checksums 0
8756         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8757         $check_ost &&
8758                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8759         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8760         $check_ost && [ -n "$ost_file_prefix" ] &&
8761                 do_facet ost1 rm -f ${ost_file_prefix}\*
8762 }
8763
8764 test_77c() {
8765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8766         $GSS && skip_env "could not run with gss"
8767         remote_ost_nodsh && skip "remote OST with nodsh"
8768
8769         local bad1
8770         local osc_file_prefix
8771         local osc_file
8772         local check_ost=false
8773         local ost_file_prefix
8774         local ost_file
8775         local orig_cksum
8776         local dump_cksum
8777         local fid
8778
8779         # ensure corruption will occur on first OSS/OST
8780         $LFS setstripe -i 0 $DIR/$tfile
8781
8782         [ ! -f $F77_TMP ] && setup_f77
8783         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8784                 error "dd write error: $?"
8785         fid=$($LFS path2fid $DIR/$tfile)
8786
8787         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8788         then
8789                 check_ost=true
8790                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8791                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8792         else
8793                 echo "OSS do not support bulk pages dump upon error"
8794         fi
8795
8796         osc_file_prefix=$($LCTL get_param -n debug_path)
8797         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8798
8799         trap cleanup_77c EXIT
8800
8801         set_checksums 1
8802         # enable bulk pages dump upon error on Client
8803         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8804         # enable bulk pages dump upon error on OSS
8805         $check_ost &&
8806                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8807
8808         # flush Client cache to allow next read to reach OSS
8809         cancel_lru_locks osc
8810
8811         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8812         $LCTL set_param fail_loc=0x80000408
8813         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8814         $LCTL set_param fail_loc=0
8815
8816         rm -f $DIR/$tfile
8817
8818         # check cksum dump on Client
8819         osc_file=$(ls ${osc_file_prefix}*)
8820         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8821         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8822         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8823         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8824         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8825                      cksum)
8826         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8827         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8828                 error "dump content does not match on Client"
8829
8830         $check_ost || skip "No need to check cksum dump on OSS"
8831
8832         # check cksum dump on OSS
8833         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8834         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8835         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8836         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8837         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8838                 error "dump content does not match on OSS"
8839
8840         cleanup_77c
8841 }
8842 run_test 77c "checksum error on client read with debug"
8843
8844 test_77d() { # bug 10889
8845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8846         $GSS && skip_env "could not run with gss"
8847
8848         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8849         $LCTL set_param fail_loc=0x80000409
8850         set_checksums 1
8851         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8852                 error "direct write: rc=$?"
8853         $LCTL set_param fail_loc=0
8854         set_checksums 0
8855
8856         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8857         $LCTL set_param fail_loc=0x80000408
8858         set_checksums 1
8859         cancel_lru_locks osc
8860         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8861                 error "direct read: rc=$?"
8862         $LCTL set_param fail_loc=0
8863         set_checksums 0
8864 }
8865 run_test 77d "checksum error on OST direct write, read"
8866
8867 test_77f() { # bug 10889
8868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8869         $GSS && skip_env "could not run with gss"
8870
8871         set_checksums 1
8872         for algo in $CKSUM_TYPES; do
8873                 cancel_lru_locks osc
8874                 set_checksum_type $algo
8875                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8876                 $LCTL set_param fail_loc=0x409
8877                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8878                         error "direct write succeeded"
8879                 $LCTL set_param fail_loc=0
8880         done
8881         set_checksum_type $ORIG_CSUM_TYPE
8882         set_checksums 0
8883 }
8884 run_test 77f "repeat checksum error on write (expect error)"
8885
8886 test_77g() { # bug 10889
8887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8888         $GSS && skip_env "could not run with gss"
8889         remote_ost_nodsh && skip "remote OST with nodsh"
8890
8891         [ ! -f $F77_TMP ] && setup_f77
8892
8893         local file=$DIR/$tfile
8894         stack_trap "rm -f $file" EXIT
8895
8896         $LFS setstripe -c 1 -i 0 $file
8897         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8898         do_facet ost1 lctl set_param fail_loc=0x8000021a
8899         set_checksums 1
8900         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8901                 error "write error: rc=$?"
8902         do_facet ost1 lctl set_param fail_loc=0
8903         set_checksums 0
8904
8905         cancel_lru_locks osc
8906         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8907         do_facet ost1 lctl set_param fail_loc=0x8000021b
8908         set_checksums 1
8909         cmp $F77_TMP $file || error "file compare failed"
8910         do_facet ost1 lctl set_param fail_loc=0
8911         set_checksums 0
8912 }
8913 run_test 77g "checksum error on OST write, read"
8914
8915 test_77k() { # LU-10906
8916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8917         $GSS && skip_env "could not run with gss"
8918
8919         local cksum_param="osc.$FSNAME*.checksums"
8920         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8921         local checksum
8922         local i
8923
8924         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8925         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
8926         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
8927
8928         for i in 0 1; do
8929                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8930                         error "failed to set checksum=$i on MGS"
8931                 wait_update $HOSTNAME "$get_checksum" $i
8932                 #remount
8933                 echo "remount client, checksum should be $i"
8934                 remount_client $MOUNT || error "failed to remount client"
8935                 checksum=$(eval $get_checksum)
8936                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8937         done
8938         # remove persistent param to avoid races with checksum mountopt below
8939         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8940                 error "failed to delete checksum on MGS"
8941
8942         for opt in "checksum" "nochecksum"; do
8943                 #remount with mount option
8944                 echo "remount client with option $opt, checksum should be $i"
8945                 umount_client $MOUNT || error "failed to umount client"
8946                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8947                         error "failed to mount client with option '$opt'"
8948                 checksum=$(eval $get_checksum)
8949                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8950                 i=$((i - 1))
8951         done
8952
8953         remount_client $MOUNT || error "failed to remount client"
8954 }
8955 run_test 77k "enable/disable checksum correctly"
8956
8957 test_77l() {
8958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8959         $GSS && skip_env "could not run with gss"
8960
8961         set_checksums 1
8962         stack_trap "set_checksums $ORIG_CSUM" EXIT
8963         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8964
8965         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8966
8967         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8968         for algo in $CKSUM_TYPES; do
8969                 set_checksum_type $algo || error "fail to set checksum type $algo"
8970                 osc_algo=$(get_osc_checksum_type OST0000)
8971                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8972
8973                 # no locks, no reqs to let the connection idle
8974                 cancel_lru_locks osc
8975                 lru_resize_disable osc
8976                 wait_osc_import_state client ost1 IDLE
8977
8978                 # ensure ost1 is connected
8979                 stat $DIR/$tfile >/dev/null || error "can't stat"
8980                 wait_osc_import_state client ost1 FULL
8981
8982                 osc_algo=$(get_osc_checksum_type OST0000)
8983                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8984         done
8985         return 0
8986 }
8987 run_test 77l "preferred checksum type is remembered after reconnected"
8988
8989 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8990 rm -f $F77_TMP
8991 unset F77_TMP
8992
8993 cleanup_test_78() {
8994         trap 0
8995         rm -f $DIR/$tfile
8996 }
8997
8998 test_78() { # bug 10901
8999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9000         remote_ost || skip_env "local OST"
9001
9002         NSEQ=5
9003         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9004         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9005         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9006         echo "MemTotal: $MEMTOTAL"
9007
9008         # reserve 256MB of memory for the kernel and other running processes,
9009         # and then take 1/2 of the remaining memory for the read/write buffers.
9010         if [ $MEMTOTAL -gt 512 ] ;then
9011                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9012         else
9013                 # for those poor memory-starved high-end clusters...
9014                 MEMTOTAL=$((MEMTOTAL / 2))
9015         fi
9016         echo "Mem to use for directio: $MEMTOTAL"
9017
9018         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9019         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9020         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9021         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9022                 head -n1)
9023         echo "Smallest OST: $SMALLESTOST"
9024         [[ $SMALLESTOST -lt 10240 ]] &&
9025                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9026
9027         trap cleanup_test_78 EXIT
9028
9029         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9030                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9031
9032         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9033         echo "File size: $F78SIZE"
9034         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9035         for i in $(seq 1 $NSEQ); do
9036                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9037                 echo directIO rdwr round $i of $NSEQ
9038                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9039         done
9040
9041         cleanup_test_78
9042 }
9043 run_test 78 "handle large O_DIRECT writes correctly ============"
9044
9045 test_79() { # bug 12743
9046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9047
9048         wait_delete_completed
9049
9050         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9051         BKFREE=$(calc_osc_kbytes kbytesfree)
9052         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9053
9054         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9055         DFTOTAL=`echo $STRING | cut -d, -f1`
9056         DFUSED=`echo $STRING  | cut -d, -f2`
9057         DFAVAIL=`echo $STRING | cut -d, -f3`
9058         DFFREE=$(($DFTOTAL - $DFUSED))
9059
9060         ALLOWANCE=$((64 * $OSTCOUNT))
9061
9062         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9063            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9064                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9065         fi
9066         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9067            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9068                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9069         fi
9070         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9071            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9072                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9073         fi
9074 }
9075 run_test 79 "df report consistency check ======================="
9076
9077 test_80() { # bug 10718
9078         remote_ost_nodsh && skip "remote OST with nodsh"
9079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9080
9081         # relax strong synchronous semantics for slow backends like ZFS
9082         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9083                 local soc="obdfilter.*.sync_lock_cancel"
9084                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9085
9086                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9087                 if [ -z "$save" ]; then
9088                         soc="obdfilter.*.sync_on_lock_cancel"
9089                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9090                 fi
9091
9092                 if [ "$save" != "never" ]; then
9093                         local hosts=$(comma_list $(osts_nodes))
9094
9095                         do_nodes $hosts $LCTL set_param $soc=never
9096                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9097                 fi
9098         fi
9099
9100         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9101         sync; sleep 1; sync
9102         local before=$(date +%s)
9103         cancel_lru_locks osc
9104         local after=$(date +%s)
9105         local diff=$((after - before))
9106         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9107
9108         rm -f $DIR/$tfile
9109 }
9110 run_test 80 "Page eviction is equally fast at high offsets too"
9111
9112 test_81a() { # LU-456
9113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9114         remote_ost_nodsh && skip "remote OST with nodsh"
9115
9116         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9117         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9118         do_facet ost1 lctl set_param fail_loc=0x80000228
9119
9120         # write should trigger a retry and success
9121         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9122         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9123         RC=$?
9124         if [ $RC -ne 0 ] ; then
9125                 error "write should success, but failed for $RC"
9126         fi
9127 }
9128 run_test 81a "OST should retry write when get -ENOSPC ==============="
9129
9130 test_81b() { # LU-456
9131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9132         remote_ost_nodsh && skip "remote OST with nodsh"
9133
9134         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9135         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9136         do_facet ost1 lctl set_param fail_loc=0x228
9137
9138         # write should retry several times and return -ENOSPC finally
9139         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9140         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9141         RC=$?
9142         ENOSPC=28
9143         if [ $RC -ne $ENOSPC ] ; then
9144                 error "dd should fail for -ENOSPC, but succeed."
9145         fi
9146 }
9147 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9148
9149 test_99() {
9150         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9151
9152         test_mkdir $DIR/$tdir.cvsroot
9153         chown $RUNAS_ID $DIR/$tdir.cvsroot
9154
9155         cd $TMP
9156         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9157
9158         cd /etc/init.d
9159         # some versions of cvs import exit(1) when asked to import links or
9160         # files they can't read.  ignore those files.
9161         local toignore=$(find . -type l -printf '-I %f\n' -o \
9162                          ! -perm /4 -printf '-I %f\n')
9163         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9164                 $tdir.reposname vtag rtag
9165
9166         cd $DIR
9167         test_mkdir $DIR/$tdir.reposname
9168         chown $RUNAS_ID $DIR/$tdir.reposname
9169         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9170
9171         cd $DIR/$tdir.reposname
9172         $RUNAS touch foo99
9173         $RUNAS cvs add -m 'addmsg' foo99
9174         $RUNAS cvs update
9175         $RUNAS cvs commit -m 'nomsg' foo99
9176         rm -fr $DIR/$tdir.cvsroot
9177 }
9178 run_test 99 "cvs strange file/directory operations"
9179
9180 test_100() {
9181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9182         [[ "$NETTYPE" =~ tcp ]] ||
9183                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9184         remote_ost_nodsh && skip "remote OST with nodsh"
9185         remote_mds_nodsh && skip "remote MDS with nodsh"
9186         remote_servers ||
9187                 skip "useless for local single node setup"
9188
9189         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9190                 [ "$PROT" != "tcp" ] && continue
9191                 RPORT=$(echo $REMOTE | cut -d: -f2)
9192                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9193
9194                 rc=0
9195                 LPORT=`echo $LOCAL | cut -d: -f2`
9196                 if [ $LPORT -ge 1024 ]; then
9197                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9198                         netstat -tna
9199                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9200                 fi
9201         done
9202         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9203 }
9204 run_test 100 "check local port using privileged port ==========="
9205
9206 function get_named_value()
9207 {
9208     local tag
9209
9210     tag=$1
9211     while read ;do
9212         line=$REPLY
9213         case $line in
9214         $tag*)
9215             echo $line | sed "s/^$tag[ ]*//"
9216             break
9217             ;;
9218         esac
9219     done
9220 }
9221
9222 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9223                    awk '/^max_cached_mb/ { print $2 }')
9224
9225 cleanup_101a() {
9226         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9227         trap 0
9228 }
9229
9230 test_101a() {
9231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9232
9233         local s
9234         local discard
9235         local nreads=10000
9236         local cache_limit=32
9237
9238         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9239         trap cleanup_101a EXIT
9240         $LCTL set_param -n llite.*.read_ahead_stats 0
9241         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9242
9243         #
9244         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9245         #
9246         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9247         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9248
9249         discard=0
9250         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9251                 get_named_value 'read but discarded' | cut -d" " -f1); do
9252                         discard=$(($discard + $s))
9253         done
9254         cleanup_101a
9255
9256         $LCTL get_param osc.*-osc*.rpc_stats
9257         $LCTL get_param llite.*.read_ahead_stats
9258
9259         # Discard is generally zero, but sometimes a few random reads line up
9260         # and trigger larger readahead, which is wasted & leads to discards.
9261         if [[ $(($discard)) -gt $nreads ]]; then
9262                 error "too many ($discard) discarded pages"
9263         fi
9264         rm -f $DIR/$tfile || true
9265 }
9266 run_test 101a "check read-ahead for random reads"
9267
9268 setup_test101bc() {
9269         test_mkdir $DIR/$tdir
9270         local ssize=$1
9271         local FILE_LENGTH=$2
9272         STRIPE_OFFSET=0
9273
9274         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9275
9276         local list=$(comma_list $(osts_nodes))
9277         set_osd_param $list '' read_cache_enable 0
9278         set_osd_param $list '' writethrough_cache_enable 0
9279
9280         trap cleanup_test101bc EXIT
9281         # prepare the read-ahead file
9282         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9283
9284         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9285                                 count=$FILE_SIZE_MB 2> /dev/null
9286
9287 }
9288
9289 cleanup_test101bc() {
9290         trap 0
9291         rm -rf $DIR/$tdir
9292         rm -f $DIR/$tfile
9293
9294         local list=$(comma_list $(osts_nodes))
9295         set_osd_param $list '' read_cache_enable 1
9296         set_osd_param $list '' writethrough_cache_enable 1
9297 }
9298
9299 calc_total() {
9300         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9301 }
9302
9303 ra_check_101() {
9304         local READ_SIZE=$1
9305         local STRIPE_SIZE=$2
9306         local FILE_LENGTH=$3
9307         local RA_INC=1048576
9308         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9309         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9310                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9311         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9312                         get_named_value 'read but discarded' |
9313                         cut -d" " -f1 | calc_total)
9314         if [[ $DISCARD -gt $discard_limit ]]; then
9315                 $LCTL get_param llite.*.read_ahead_stats
9316                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9317         else
9318                 echo "Read-ahead success for size ${READ_SIZE}"
9319         fi
9320 }
9321
9322 test_101b() {
9323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9324         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9325
9326         local STRIPE_SIZE=1048576
9327         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9328
9329         if [ $SLOW == "yes" ]; then
9330                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9331         else
9332                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9333         fi
9334
9335         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9336
9337         # prepare the read-ahead file
9338         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9339         cancel_lru_locks osc
9340         for BIDX in 2 4 8 16 32 64 128 256
9341         do
9342                 local BSIZE=$((BIDX*4096))
9343                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9344                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9345                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9346                 $LCTL set_param -n llite.*.read_ahead_stats 0
9347                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9348                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9349                 cancel_lru_locks osc
9350                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9351         done
9352         cleanup_test101bc
9353         true
9354 }
9355 run_test 101b "check stride-io mode read-ahead ================="
9356
9357 test_101c() {
9358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9359
9360         local STRIPE_SIZE=1048576
9361         local FILE_LENGTH=$((STRIPE_SIZE*100))
9362         local nreads=10000
9363         local rsize=65536
9364         local osc_rpc_stats
9365
9366         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9367
9368         cancel_lru_locks osc
9369         $LCTL set_param osc.*.rpc_stats 0
9370         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9371         $LCTL get_param osc.*.rpc_stats
9372         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9373                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9374                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9375                 local size
9376
9377                 if [ $lines -le 20 ]; then
9378                         echo "continue debug"
9379                         continue
9380                 fi
9381                 for size in 1 2 4 8; do
9382                         local rpc=$(echo "$stats" |
9383                                     awk '($1 == "'$size':") {print $2; exit; }')
9384                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9385                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9386                 done
9387                 echo "$osc_rpc_stats check passed!"
9388         done
9389         cleanup_test101bc
9390         true
9391 }
9392 run_test 101c "check stripe_size aligned read-ahead ================="
9393
9394 test_101d() {
9395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9396
9397         local file=$DIR/$tfile
9398         local sz_MB=${FILESIZE_101d:-80}
9399         local ra_MB=${READAHEAD_MB:-40}
9400
9401         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9402         [ $free_MB -lt $sz_MB ] &&
9403                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9404
9405         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9406         $LFS setstripe -c -1 $file || error "setstripe failed"
9407
9408         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9409         echo Cancel LRU locks on lustre client to flush the client cache
9410         cancel_lru_locks osc
9411
9412         echo Disable read-ahead
9413         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9414         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9415         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9416         $LCTL get_param -n llite.*.max_read_ahead_mb
9417
9418         echo "Reading the test file $file with read-ahead disabled"
9419         local sz_KB=$((sz_MB * 1024 / 4))
9420         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9421         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9422         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9423                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9424
9425         echo "Cancel LRU locks on lustre client to flush the client cache"
9426         cancel_lru_locks osc
9427         echo Enable read-ahead with ${ra_MB}MB
9428         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9429
9430         echo "Reading the test file $file with read-ahead enabled"
9431         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9432                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9433
9434         echo "read-ahead disabled time read $raOFF"
9435         echo "read-ahead enabled time read $raON"
9436
9437         rm -f $file
9438         wait_delete_completed
9439
9440         # use awk for this check instead of bash because it handles decimals
9441         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9442                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9443 }
9444 run_test 101d "file read with and without read-ahead enabled"
9445
9446 test_101e() {
9447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9448
9449         local file=$DIR/$tfile
9450         local size_KB=500  #KB
9451         local count=100
9452         local bsize=1024
9453
9454         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9455         local need_KB=$((count * size_KB))
9456         [[ $free_KB -le $need_KB ]] &&
9457                 skip_env "Need free space $need_KB, have $free_KB"
9458
9459         echo "Creating $count ${size_KB}K test files"
9460         for ((i = 0; i < $count; i++)); do
9461                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9462         done
9463
9464         echo "Cancel LRU locks on lustre client to flush the client cache"
9465         cancel_lru_locks $OSC
9466
9467         echo "Reset readahead stats"
9468         $LCTL set_param -n llite.*.read_ahead_stats 0
9469
9470         for ((i = 0; i < $count; i++)); do
9471                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9472         done
9473
9474         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9475                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9476
9477         for ((i = 0; i < $count; i++)); do
9478                 rm -rf $file.$i 2>/dev/null
9479         done
9480
9481         #10000 means 20% reads are missing in readahead
9482         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9483 }
9484 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9485
9486 test_101f() {
9487         which iozone || skip_env "no iozone installed"
9488
9489         local old_debug=$($LCTL get_param debug)
9490         old_debug=${old_debug#*=}
9491         $LCTL set_param debug="reada mmap"
9492
9493         # create a test file
9494         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9495
9496         echo Cancel LRU locks on lustre client to flush the client cache
9497         cancel_lru_locks osc
9498
9499         echo Reset readahead stats
9500         $LCTL set_param -n llite.*.read_ahead_stats 0
9501
9502         echo mmap read the file with small block size
9503         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9504                 > /dev/null 2>&1
9505
9506         echo checking missing pages
9507         $LCTL get_param llite.*.read_ahead_stats
9508         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9509                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9510
9511         $LCTL set_param debug="$old_debug"
9512         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9513         rm -f $DIR/$tfile
9514 }
9515 run_test 101f "check mmap read performance"
9516
9517 test_101g_brw_size_test() {
9518         local mb=$1
9519         local pages=$((mb * 1048576 / PAGE_SIZE))
9520         local file=$DIR/$tfile
9521
9522         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9523                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9524         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9525                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9526                         return 2
9527         done
9528
9529         stack_trap "rm -f $file" EXIT
9530         $LCTL set_param -n osc.*.rpc_stats=0
9531
9532         # 10 RPCs should be enough for the test
9533         local count=10
9534         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9535                 { error "dd write ${mb} MB blocks failed"; return 3; }
9536         cancel_lru_locks osc
9537         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9538                 { error "dd write ${mb} MB blocks failed"; return 4; }
9539
9540         # calculate number of full-sized read and write RPCs
9541         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9542                 sed -n '/pages per rpc/,/^$/p' |
9543                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9544                 END { print reads,writes }'))
9545         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
9546                 return 5
9547         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
9548                 return 6
9549
9550         return 0
9551 }
9552
9553 test_101g() {
9554         remote_ost_nodsh && skip "remote OST with nodsh"
9555
9556         local rpcs
9557         local osts=$(get_facets OST)
9558         local list=$(comma_list $(osts_nodes))
9559         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9560         local brw_size="obdfilter.*.brw_size"
9561
9562         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9563
9564         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9565
9566         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9567                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9568                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9569            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9570                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9571                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9572
9573                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9574                         suffix="M"
9575
9576                 if [[ $orig_mb -lt 16 ]]; then
9577                         save_lustre_params $osts "$brw_size" > $p
9578                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9579                                 error "set 16MB RPC size failed"
9580
9581                         echo "remount client to enable new RPC size"
9582                         remount_client $MOUNT || error "remount_client failed"
9583                 fi
9584
9585                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9586                 # should be able to set brw_size=12, but no rpc_stats for that
9587                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9588         fi
9589
9590         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9591
9592         if [[ $orig_mb -lt 16 ]]; then
9593                 restore_lustre_params < $p
9594                 remount_client $MOUNT || error "remount_client restore failed"
9595         fi
9596
9597         rm -f $p $DIR/$tfile
9598 }
9599 run_test 101g "Big bulk(4/16 MiB) readahead"
9600
9601 test_101h() {
9602         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9603
9604         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9605                 error "dd 70M file failed"
9606         echo Cancel LRU locks on lustre client to flush the client cache
9607         cancel_lru_locks osc
9608
9609         echo "Reset readahead stats"
9610         $LCTL set_param -n llite.*.read_ahead_stats 0
9611
9612         echo "Read 10M of data but cross 64M bundary"
9613         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9614         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9615                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9616         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9617         rm -f $p $DIR/$tfile
9618 }
9619 run_test 101h "Readahead should cover current read window"
9620
9621 test_101i() {
9622         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9623                 error "dd 10M file failed"
9624
9625         local max_per_file_mb=$($LCTL get_param -n \
9626                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9627         cancel_lru_locks osc
9628         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9629         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9630                 error "set max_read_ahead_per_file_mb to 1 failed"
9631
9632         echo "Reset readahead stats"
9633         $LCTL set_param llite.*.read_ahead_stats=0
9634
9635         dd if=$DIR/$tfile of=/dev/null bs=2M
9636
9637         $LCTL get_param llite.*.read_ahead_stats
9638         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9639                      awk '/misses/ { print $2 }')
9640         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9641         rm -f $DIR/$tfile
9642 }
9643 run_test 101i "allow current readahead to exceed reservation"
9644
9645 test_101j() {
9646         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9647                 error "setstripe $DIR/$tfile failed"
9648         local file_size=$((1048576 * 16))
9649         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9650         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9651
9652         echo Disable read-ahead
9653         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9654
9655         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9656         for blk in $PAGE_SIZE 1048576 $file_size; do
9657                 cancel_lru_locks osc
9658                 echo "Reset readahead stats"
9659                 $LCTL set_param -n llite.*.read_ahead_stats=0
9660                 local count=$(($file_size / $blk))
9661                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9662                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9663                              get_named_value 'failed to fast read' |
9664                              cut -d" " -f1 | calc_total)
9665                 $LCTL get_param -n llite.*.read_ahead_stats
9666                 [ $miss -eq $count ] || error "expected $count got $miss"
9667         done
9668
9669         rm -f $p $DIR/$tfile
9670 }
9671 run_test 101j "A complete read block should be submitted when no RA"
9672
9673 setup_test102() {
9674         test_mkdir $DIR/$tdir
9675         chown $RUNAS_ID $DIR/$tdir
9676         STRIPE_SIZE=65536
9677         STRIPE_OFFSET=1
9678         STRIPE_COUNT=$OSTCOUNT
9679         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9680
9681         trap cleanup_test102 EXIT
9682         cd $DIR
9683         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9684         cd $DIR/$tdir
9685         for num in 1 2 3 4; do
9686                 for count in $(seq 1 $STRIPE_COUNT); do
9687                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9688                                 local size=`expr $STRIPE_SIZE \* $num`
9689                                 local file=file"$num-$idx-$count"
9690                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9691                         done
9692                 done
9693         done
9694
9695         cd $DIR
9696         $1 tar cf $TMP/f102.tar $tdir --xattrs
9697 }
9698
9699 cleanup_test102() {
9700         trap 0
9701         rm -f $TMP/f102.tar
9702         rm -rf $DIR/d0.sanity/d102
9703 }
9704
9705 test_102a() {
9706         [ "$UID" != 0 ] && skip "must run as root"
9707         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9708                 skip_env "must have user_xattr"
9709
9710         [ -z "$(which setfattr 2>/dev/null)" ] &&
9711                 skip_env "could not find setfattr"
9712
9713         local testfile=$DIR/$tfile
9714
9715         touch $testfile
9716         echo "set/get xattr..."
9717         setfattr -n trusted.name1 -v value1 $testfile ||
9718                 error "setfattr -n trusted.name1=value1 $testfile failed"
9719         getfattr -n trusted.name1 $testfile 2> /dev/null |
9720           grep "trusted.name1=.value1" ||
9721                 error "$testfile missing trusted.name1=value1"
9722
9723         setfattr -n user.author1 -v author1 $testfile ||
9724                 error "setfattr -n user.author1=author1 $testfile failed"
9725         getfattr -n user.author1 $testfile 2> /dev/null |
9726           grep "user.author1=.author1" ||
9727                 error "$testfile missing trusted.author1=author1"
9728
9729         echo "listxattr..."
9730         setfattr -n trusted.name2 -v value2 $testfile ||
9731                 error "$testfile unable to set trusted.name2"
9732         setfattr -n trusted.name3 -v value3 $testfile ||
9733                 error "$testfile unable to set trusted.name3"
9734         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9735             grep "trusted.name" | wc -l) -eq 3 ] ||
9736                 error "$testfile missing 3 trusted.name xattrs"
9737
9738         setfattr -n user.author2 -v author2 $testfile ||
9739                 error "$testfile unable to set user.author2"
9740         setfattr -n user.author3 -v author3 $testfile ||
9741                 error "$testfile unable to set user.author3"
9742         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9743             grep "user.author" | wc -l) -eq 3 ] ||
9744                 error "$testfile missing 3 user.author xattrs"
9745
9746         echo "remove xattr..."
9747         setfattr -x trusted.name1 $testfile ||
9748                 error "$testfile error deleting trusted.name1"
9749         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9750                 error "$testfile did not delete trusted.name1 xattr"
9751
9752         setfattr -x user.author1 $testfile ||
9753                 error "$testfile error deleting user.author1"
9754         echo "set lustre special xattr ..."
9755         $LFS setstripe -c1 $testfile
9756         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9757                 awk -F "=" '/trusted.lov/ { print $2 }' )
9758         setfattr -n "trusted.lov" -v $lovea $testfile ||
9759                 error "$testfile doesn't ignore setting trusted.lov again"
9760         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9761                 error "$testfile allow setting invalid trusted.lov"
9762         rm -f $testfile
9763 }
9764 run_test 102a "user xattr test =================================="
9765
9766 check_102b_layout() {
9767         local layout="$*"
9768         local testfile=$DIR/$tfile
9769
9770         echo "test layout '$layout'"
9771         $LFS setstripe $layout $testfile || error "setstripe failed"
9772         $LFS getstripe -y $testfile
9773
9774         echo "get/set/list trusted.lov xattr ..." # b=10930
9775         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9776         [[ "$value" =~ "trusted.lov" ]] ||
9777                 error "can't get trusted.lov from $testfile"
9778         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9779                 error "getstripe failed"
9780
9781         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9782
9783         value=$(cut -d= -f2 <<<$value)
9784         # LU-13168: truncated xattr should fail if short lov_user_md header
9785         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9786                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9787         for len in $lens; do
9788                 echo "setfattr $len $testfile.2"
9789                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9790                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9791         done
9792         local stripe_size=$($LFS getstripe -S $testfile.2)
9793         local stripe_count=$($LFS getstripe -c $testfile.2)
9794         [[ $stripe_size -eq 65536 ]] ||
9795                 error "stripe size $stripe_size != 65536"
9796         [[ $stripe_count -eq $stripe_count_orig ]] ||
9797                 error "stripe count $stripe_count != $stripe_count_orig"
9798         rm $testfile $testfile.2
9799 }
9800
9801 test_102b() {
9802         [ -z "$(which setfattr 2>/dev/null)" ] &&
9803                 skip_env "could not find setfattr"
9804         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9805
9806         # check plain layout
9807         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9808
9809         # and also check composite layout
9810         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9811
9812 }
9813 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9814
9815 test_102c() {
9816         [ -z "$(which setfattr 2>/dev/null)" ] &&
9817                 skip_env "could not find setfattr"
9818         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9819
9820         # b10930: get/set/list lustre.lov xattr
9821         echo "get/set/list lustre.lov xattr ..."
9822         test_mkdir $DIR/$tdir
9823         chown $RUNAS_ID $DIR/$tdir
9824         local testfile=$DIR/$tdir/$tfile
9825         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9826                 error "setstripe failed"
9827         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9828                 error "getstripe failed"
9829         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9830         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9831
9832         local testfile2=${testfile}2
9833         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9834                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9835
9836         $RUNAS $MCREATE $testfile2
9837         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9838         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9839         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9840         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9841         [ $stripe_count -eq $STRIPECOUNT ] ||
9842                 error "stripe count $stripe_count != $STRIPECOUNT"
9843 }
9844 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9845
9846 compare_stripe_info1() {
9847         local stripe_index_all_zero=true
9848
9849         for num in 1 2 3 4; do
9850                 for count in $(seq 1 $STRIPE_COUNT); do
9851                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9852                                 local size=$((STRIPE_SIZE * num))
9853                                 local file=file"$num-$offset-$count"
9854                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9855                                 [[ $stripe_size -ne $size ]] &&
9856                                     error "$file: size $stripe_size != $size"
9857                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9858                                 # allow fewer stripes to be created, ORI-601
9859                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9860                                     error "$file: count $stripe_count != $count"
9861                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9862                                 [[ $stripe_index -ne 0 ]] &&
9863                                         stripe_index_all_zero=false
9864                         done
9865                 done
9866         done
9867         $stripe_index_all_zero &&
9868                 error "all files are being extracted starting from OST index 0"
9869         return 0
9870 }
9871
9872 have_xattrs_include() {
9873         tar --help | grep -q xattrs-include &&
9874                 echo --xattrs-include="lustre.*"
9875 }
9876
9877 test_102d() {
9878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9880
9881         XINC=$(have_xattrs_include)
9882         setup_test102
9883         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9884         cd $DIR/$tdir/$tdir
9885         compare_stripe_info1
9886 }
9887 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9888
9889 test_102f() {
9890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9891         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9892
9893         XINC=$(have_xattrs_include)
9894         setup_test102
9895         test_mkdir $DIR/$tdir.restore
9896         cd $DIR
9897         tar cf - --xattrs $tdir | tar xf - \
9898                 -C $DIR/$tdir.restore --xattrs $XINC
9899         cd $DIR/$tdir.restore/$tdir
9900         compare_stripe_info1
9901 }
9902 run_test 102f "tar copy files, not keep osts"
9903
9904 grow_xattr() {
9905         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9906                 skip "must have user_xattr"
9907         [ -z "$(which setfattr 2>/dev/null)" ] &&
9908                 skip_env "could not find setfattr"
9909         [ -z "$(which getfattr 2>/dev/null)" ] &&
9910                 skip_env "could not find getfattr"
9911
9912         local xsize=${1:-1024}  # in bytes
9913         local file=$DIR/$tfile
9914         local value="$(generate_string $xsize)"
9915         local xbig=trusted.big
9916         local toobig=$2
9917
9918         touch $file
9919         log "save $xbig on $file"
9920         if [ -z "$toobig" ]
9921         then
9922                 setfattr -n $xbig -v $value $file ||
9923                         error "saving $xbig on $file failed"
9924         else
9925                 setfattr -n $xbig -v $value $file &&
9926                         error "saving $xbig on $file succeeded"
9927                 return 0
9928         fi
9929
9930         local orig=$(get_xattr_value $xbig $file)
9931         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9932
9933         local xsml=trusted.sml
9934         log "save $xsml on $file"
9935         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9936
9937         local new=$(get_xattr_value $xbig $file)
9938         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9939
9940         log "grow $xsml on $file"
9941         setfattr -n $xsml -v "$value" $file ||
9942                 error "growing $xsml on $file failed"
9943
9944         new=$(get_xattr_value $xbig $file)
9945         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9946         log "$xbig still valid after growing $xsml"
9947
9948         rm -f $file
9949 }
9950
9951 test_102h() { # bug 15777
9952         grow_xattr 1024
9953 }
9954 run_test 102h "grow xattr from inside inode to external block"
9955
9956 test_102ha() {
9957         large_xattr_enabled || skip_env "ea_inode feature disabled"
9958
9959         echo "setting xattr of max xattr size: $(max_xattr_size)"
9960         grow_xattr $(max_xattr_size)
9961
9962         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9963         echo "This should fail:"
9964         grow_xattr $(($(max_xattr_size) + 10)) 1
9965 }
9966 run_test 102ha "grow xattr from inside inode to external inode"
9967
9968 test_102i() { # bug 17038
9969         [ -z "$(which getfattr 2>/dev/null)" ] &&
9970                 skip "could not find getfattr"
9971
9972         touch $DIR/$tfile
9973         ln -s $DIR/$tfile $DIR/${tfile}link
9974         getfattr -n trusted.lov $DIR/$tfile ||
9975                 error "lgetxattr on $DIR/$tfile failed"
9976         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9977                 grep -i "no such attr" ||
9978                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9979         rm -f $DIR/$tfile $DIR/${tfile}link
9980 }
9981 run_test 102i "lgetxattr test on symbolic link ============"
9982
9983 test_102j() {
9984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9985         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9986
9987         XINC=$(have_xattrs_include)
9988         setup_test102 "$RUNAS"
9989         chown $RUNAS_ID $DIR/$tdir
9990         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9991         cd $DIR/$tdir/$tdir
9992         compare_stripe_info1 "$RUNAS"
9993 }
9994 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9995
9996 test_102k() {
9997         [ -z "$(which setfattr 2>/dev/null)" ] &&
9998                 skip "could not find setfattr"
9999
10000         touch $DIR/$tfile
10001         # b22187 just check that does not crash for regular file.
10002         setfattr -n trusted.lov $DIR/$tfile
10003         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10004         local test_kdir=$DIR/$tdir
10005         test_mkdir $test_kdir
10006         local default_size=$($LFS getstripe -S $test_kdir)
10007         local default_count=$($LFS getstripe -c $test_kdir)
10008         local default_offset=$($LFS getstripe -i $test_kdir)
10009         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10010                 error 'dir setstripe failed'
10011         setfattr -n trusted.lov $test_kdir
10012         local stripe_size=$($LFS getstripe -S $test_kdir)
10013         local stripe_count=$($LFS getstripe -c $test_kdir)
10014         local stripe_offset=$($LFS getstripe -i $test_kdir)
10015         [ $stripe_size -eq $default_size ] ||
10016                 error "stripe size $stripe_size != $default_size"
10017         [ $stripe_count -eq $default_count ] ||
10018                 error "stripe count $stripe_count != $default_count"
10019         [ $stripe_offset -eq $default_offset ] ||
10020                 error "stripe offset $stripe_offset != $default_offset"
10021         rm -rf $DIR/$tfile $test_kdir
10022 }
10023 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10024
10025 test_102l() {
10026         [ -z "$(which getfattr 2>/dev/null)" ] &&
10027                 skip "could not find getfattr"
10028
10029         # LU-532 trusted. xattr is invisible to non-root
10030         local testfile=$DIR/$tfile
10031
10032         touch $testfile
10033
10034         echo "listxattr as user..."
10035         chown $RUNAS_ID $testfile
10036         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10037             grep -q "trusted" &&
10038                 error "$testfile trusted xattrs are user visible"
10039
10040         return 0;
10041 }
10042 run_test 102l "listxattr size test =================================="
10043
10044 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10045         local path=$DIR/$tfile
10046         touch $path
10047
10048         listxattr_size_check $path || error "listattr_size_check $path failed"
10049 }
10050 run_test 102m "Ensure listxattr fails on small bufffer ========"
10051
10052 cleanup_test102
10053
10054 getxattr() { # getxattr path name
10055         # Return the base64 encoding of the value of xattr name on path.
10056         local path=$1
10057         local name=$2
10058
10059         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10060         # file: $path
10061         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10062         #
10063         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10064
10065         getfattr --absolute-names --encoding=base64 --name=$name $path |
10066                 awk -F= -v name=$name '$1 == name {
10067                         print substr($0, index($0, "=") + 1);
10068         }'
10069 }
10070
10071 test_102n() { # LU-4101 mdt: protect internal xattrs
10072         [ -z "$(which setfattr 2>/dev/null)" ] &&
10073                 skip "could not find setfattr"
10074         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10075         then
10076                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10077         fi
10078
10079         local file0=$DIR/$tfile.0
10080         local file1=$DIR/$tfile.1
10081         local xattr0=$TMP/$tfile.0
10082         local xattr1=$TMP/$tfile.1
10083         local namelist="lov lma lmv link fid version som hsm"
10084         local name
10085         local value
10086
10087         rm -rf $file0 $file1 $xattr0 $xattr1
10088         touch $file0 $file1
10089
10090         # Get 'before' xattrs of $file1.
10091         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10092
10093         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10094                 namelist+=" lfsck_namespace"
10095         for name in $namelist; do
10096                 # Try to copy xattr from $file0 to $file1.
10097                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10098
10099                 setfattr --name=trusted.$name --value="$value" $file1 ||
10100                         error "setxattr 'trusted.$name' failed"
10101
10102                 # Try to set a garbage xattr.
10103                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10104
10105                 if [[ x$name == "xlov" ]]; then
10106                         setfattr --name=trusted.lov --value="$value" $file1 &&
10107                         error "setxattr invalid 'trusted.lov' success"
10108                 else
10109                         setfattr --name=trusted.$name --value="$value" $file1 ||
10110                                 error "setxattr invalid 'trusted.$name' failed"
10111                 fi
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         done
10118
10119         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10120         then
10121                 name="lfsck_ns"
10122                 # Try to copy xattr from $file0 to $file1.
10123                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10124
10125                 setfattr --name=trusted.$name --value="$value" $file1 ||
10126                         error "setxattr 'trusted.$name' failed"
10127
10128                 # Try to set a garbage xattr.
10129                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10130
10131                 setfattr --name=trusted.$name --value="$value" $file1 ||
10132                         error "setxattr 'trusted.$name' failed"
10133
10134                 # Try to remove the xattr from $file1. We don't care if this
10135                 # appears to succeed or fail, we just don't want there to be
10136                 # any changes or crashes.
10137                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10138         fi
10139
10140         # Get 'after' xattrs of file1.
10141         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10142
10143         if ! diff $xattr0 $xattr1; then
10144                 error "before and after xattrs of '$file1' differ"
10145         fi
10146
10147         rm -rf $file0 $file1 $xattr0 $xattr1
10148
10149         return 0
10150 }
10151 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10152
10153 test_102p() { # LU-4703 setxattr did not check ownership
10154         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10155                 skip "MDS needs to be at least 2.5.56"
10156
10157         local testfile=$DIR/$tfile
10158
10159         touch $testfile
10160
10161         echo "setfacl as user..."
10162         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10163         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10164
10165         echo "setfattr as user..."
10166         setfacl -m "u:$RUNAS_ID:---" $testfile
10167         $RUNAS setfattr -x system.posix_acl_access $testfile
10168         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10169 }
10170 run_test 102p "check setxattr(2) correctly fails without permission"
10171
10172 test_102q() {
10173         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10174                 skip "MDS needs to be at least 2.6.92"
10175
10176         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10177 }
10178 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10179
10180 test_102r() {
10181         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10182                 skip "MDS needs to be at least 2.6.93"
10183
10184         touch $DIR/$tfile || error "touch"
10185         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10186         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10187         rm $DIR/$tfile || error "rm"
10188
10189         #normal directory
10190         mkdir -p $DIR/$tdir || error "mkdir"
10191         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10192         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10193         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10194                 error "$testfile error deleting user.author1"
10195         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10196                 grep "user.$(basename $tdir)" &&
10197                 error "$tdir did not delete user.$(basename $tdir)"
10198         rmdir $DIR/$tdir || error "rmdir"
10199
10200         #striped directory
10201         test_mkdir $DIR/$tdir
10202         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10203         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10204         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10205                 error "$testfile error deleting user.author1"
10206         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10207                 grep "user.$(basename $tdir)" &&
10208                 error "$tdir did not delete user.$(basename $tdir)"
10209         rmdir $DIR/$tdir || error "rm striped dir"
10210 }
10211 run_test 102r "set EAs with empty values"
10212
10213 test_102s() {
10214         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10215                 skip "MDS needs to be at least 2.11.52"
10216
10217         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10218
10219         save_lustre_params client "llite.*.xattr_cache" > $save
10220
10221         for cache in 0 1; do
10222                 lctl set_param llite.*.xattr_cache=$cache
10223
10224                 rm -f $DIR/$tfile
10225                 touch $DIR/$tfile || error "touch"
10226                 for prefix in lustre security system trusted user; do
10227                         # Note getxattr() may fail with 'Operation not
10228                         # supported' or 'No such attribute' depending
10229                         # on prefix and cache.
10230                         getfattr -n $prefix.n102s $DIR/$tfile &&
10231                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10232                 done
10233         done
10234
10235         restore_lustre_params < $save
10236 }
10237 run_test 102s "getting nonexistent xattrs should fail"
10238
10239 test_102t() {
10240         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10241                 skip "MDS needs to be at least 2.11.52"
10242
10243         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10244
10245         save_lustre_params client "llite.*.xattr_cache" > $save
10246
10247         for cache in 0 1; do
10248                 lctl set_param llite.*.xattr_cache=$cache
10249
10250                 for buf_size in 0 256; do
10251                         rm -f $DIR/$tfile
10252                         touch $DIR/$tfile || error "touch"
10253                         setfattr -n user.multiop $DIR/$tfile
10254                         $MULTIOP $DIR/$tfile oa$buf_size ||
10255                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10256                 done
10257         done
10258
10259         restore_lustre_params < $save
10260 }
10261 run_test 102t "zero length xattr values handled correctly"
10262
10263 run_acl_subtest()
10264 {
10265     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10266     return $?
10267 }
10268
10269 test_103a() {
10270         [ "$UID" != 0 ] && skip "must run as root"
10271         $GSS && skip_env "could not run under gss"
10272         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10273                 skip_env "must have acl enabled"
10274         [ -z "$(which setfacl 2>/dev/null)" ] &&
10275                 skip_env "could not find setfacl"
10276         remote_mds_nodsh && skip "remote MDS with nodsh"
10277
10278         gpasswd -a daemon bin                           # LU-5641
10279         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10280
10281         declare -a identity_old
10282
10283         for num in $(seq $MDSCOUNT); do
10284                 switch_identity $num true || identity_old[$num]=$?
10285         done
10286
10287         SAVE_UMASK=$(umask)
10288         umask 0022
10289         mkdir -p $DIR/$tdir
10290         cd $DIR/$tdir
10291
10292         echo "performing cp ..."
10293         run_acl_subtest cp || error "run_acl_subtest cp failed"
10294         echo "performing getfacl-noacl..."
10295         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10296         echo "performing misc..."
10297         run_acl_subtest misc || error  "misc test failed"
10298         echo "performing permissions..."
10299         run_acl_subtest permissions || error "permissions failed"
10300         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10301         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10302                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10303                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10304         then
10305                 echo "performing permissions xattr..."
10306                 run_acl_subtest permissions_xattr ||
10307                         error "permissions_xattr failed"
10308         fi
10309         echo "performing setfacl..."
10310         run_acl_subtest setfacl || error  "setfacl test failed"
10311
10312         # inheritance test got from HP
10313         echo "performing inheritance..."
10314         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10315         chmod +x make-tree || error "chmod +x failed"
10316         run_acl_subtest inheritance || error "inheritance test failed"
10317         rm -f make-tree
10318
10319         echo "LU-974 ignore umask when acl is enabled..."
10320         run_acl_subtest 974 || error "LU-974 umask test failed"
10321         if [ $MDSCOUNT -ge 2 ]; then
10322                 run_acl_subtest 974_remote ||
10323                         error "LU-974 umask test failed under remote dir"
10324         fi
10325
10326         echo "LU-2561 newly created file is same size as directory..."
10327         if [ "$mds1_FSTYPE" != "zfs" ]; then
10328                 run_acl_subtest 2561 || error "LU-2561 test failed"
10329         else
10330                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10331         fi
10332
10333         run_acl_subtest 4924 || error "LU-4924 test failed"
10334
10335         cd $SAVE_PWD
10336         umask $SAVE_UMASK
10337
10338         for num in $(seq $MDSCOUNT); do
10339                 if [ "${identity_old[$num]}" = 1 ]; then
10340                         switch_identity $num false || identity_old[$num]=$?
10341                 fi
10342         done
10343 }
10344 run_test 103a "acl test"
10345
10346 test_103b() {
10347         declare -a pids
10348         local U
10349
10350         for U in {0..511}; do
10351                 {
10352                 local O=$(printf "%04o" $U)
10353
10354                 umask $(printf "%04o" $((511 ^ $O)))
10355                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10356                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10357
10358                 (( $S == ($O & 0666) )) ||
10359                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10360
10361                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10362                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10363                 (( $S == ($O & 0666) )) ||
10364                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10365
10366                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10367                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10368                 (( $S == ($O & 0666) )) ||
10369                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10370                 rm -f $DIR/$tfile.[smp]$0
10371                 } &
10372                 local pid=$!
10373
10374                 # limit the concurrently running threads to 64. LU-11878
10375                 local idx=$((U % 64))
10376                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10377                 pids[idx]=$pid
10378         done
10379         wait
10380 }
10381 run_test 103b "umask lfs setstripe"
10382
10383 test_103c() {
10384         mkdir -p $DIR/$tdir
10385         cp -rp $DIR/$tdir $DIR/$tdir.bak
10386
10387         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10388                 error "$DIR/$tdir shouldn't contain default ACL"
10389         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10390                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10391         true
10392 }
10393 run_test 103c "'cp -rp' won't set empty acl"
10394
10395 test_104a() {
10396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10397
10398         touch $DIR/$tfile
10399         lfs df || error "lfs df failed"
10400         lfs df -ih || error "lfs df -ih failed"
10401         lfs df -h $DIR || error "lfs df -h $DIR failed"
10402         lfs df -i $DIR || error "lfs df -i $DIR failed"
10403         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10404         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10405
10406         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10407         lctl --device %$OSC deactivate
10408         lfs df || error "lfs df with deactivated OSC failed"
10409         lctl --device %$OSC activate
10410         # wait the osc back to normal
10411         wait_osc_import_ready client ost
10412
10413         lfs df || error "lfs df with reactivated OSC failed"
10414         rm -f $DIR/$tfile
10415 }
10416 run_test 104a "lfs df [-ih] [path] test ========================="
10417
10418 test_104b() {
10419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10420         [ $RUNAS_ID -eq $UID ] &&
10421                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10422
10423         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10424                         grep "Permission denied" | wc -l)))
10425         if [ $denied_cnt -ne 0 ]; then
10426                 error "lfs check servers test failed"
10427         fi
10428 }
10429 run_test 104b "$RUNAS lfs check servers test ===================="
10430
10431 test_105a() {
10432         # doesn't work on 2.4 kernels
10433         touch $DIR/$tfile
10434         if $(flock_is_enabled); then
10435                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10436         else
10437                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10438         fi
10439         rm -f $DIR/$tfile
10440 }
10441 run_test 105a "flock when mounted without -o flock test ========"
10442
10443 test_105b() {
10444         touch $DIR/$tfile
10445         if $(flock_is_enabled); then
10446                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10447         else
10448                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10449         fi
10450         rm -f $DIR/$tfile
10451 }
10452 run_test 105b "fcntl when mounted without -o flock test ========"
10453
10454 test_105c() {
10455         touch $DIR/$tfile
10456         if $(flock_is_enabled); then
10457                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10458         else
10459                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10460         fi
10461         rm -f $DIR/$tfile
10462 }
10463 run_test 105c "lockf when mounted without -o flock test"
10464
10465 test_105d() { # bug 15924
10466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10467
10468         test_mkdir $DIR/$tdir
10469         flock_is_enabled || skip_env "mount w/o flock enabled"
10470         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10471         $LCTL set_param fail_loc=0x80000315
10472         flocks_test 2 $DIR/$tdir
10473 }
10474 run_test 105d "flock race (should not freeze) ========"
10475
10476 test_105e() { # bug 22660 && 22040
10477         flock_is_enabled || skip_env "mount w/o flock enabled"
10478
10479         touch $DIR/$tfile
10480         flocks_test 3 $DIR/$tfile
10481 }
10482 run_test 105e "Two conflicting flocks from same process"
10483
10484 test_106() { #bug 10921
10485         test_mkdir $DIR/$tdir
10486         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10487         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10488 }
10489 run_test 106 "attempt exec of dir followed by chown of that dir"
10490
10491 test_107() {
10492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10493
10494         CDIR=`pwd`
10495         local file=core
10496
10497         cd $DIR
10498         rm -f $file
10499
10500         local save_pattern=$(sysctl -n kernel.core_pattern)
10501         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10502         sysctl -w kernel.core_pattern=$file
10503         sysctl -w kernel.core_uses_pid=0
10504
10505         ulimit -c unlimited
10506         sleep 60 &
10507         SLEEPPID=$!
10508
10509         sleep 1
10510
10511         kill -s 11 $SLEEPPID
10512         wait $SLEEPPID
10513         if [ -e $file ]; then
10514                 size=`stat -c%s $file`
10515                 [ $size -eq 0 ] && error "Fail to create core file $file"
10516         else
10517                 error "Fail to create core file $file"
10518         fi
10519         rm -f $file
10520         sysctl -w kernel.core_pattern=$save_pattern
10521         sysctl -w kernel.core_uses_pid=$save_uses_pid
10522         cd $CDIR
10523 }
10524 run_test 107 "Coredump on SIG"
10525
10526 test_110() {
10527         test_mkdir $DIR/$tdir
10528         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10529         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10530                 error "mkdir with 256 char should fail, but did not"
10531         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10532                 error "create with 255 char failed"
10533         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10534                 error "create with 256 char should fail, but did not"
10535
10536         ls -l $DIR/$tdir
10537         rm -rf $DIR/$tdir
10538 }
10539 run_test 110 "filename length checking"
10540
10541 #
10542 # Purpose: To verify dynamic thread (OSS) creation.
10543 #
10544 test_115() {
10545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10546         remote_ost_nodsh && skip "remote OST with nodsh"
10547
10548         # Lustre does not stop service threads once they are started.
10549         # Reset number of running threads to default.
10550         stopall
10551         setupall
10552
10553         local OSTIO_pre
10554         local save_params="$TMP/sanity-$TESTNAME.parameters"
10555
10556         # Get ll_ost_io count before I/O
10557         OSTIO_pre=$(do_facet ost1 \
10558                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10559         # Exit if lustre is not running (ll_ost_io not running).
10560         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10561
10562         echo "Starting with $OSTIO_pre threads"
10563         local thread_max=$((OSTIO_pre * 2))
10564         local rpc_in_flight=$((thread_max * 2))
10565         # Number of I/O Process proposed to be started.
10566         local nfiles
10567         local facets=$(get_facets OST)
10568
10569         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10570         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10571
10572         # Set in_flight to $rpc_in_flight
10573         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10574                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10575         nfiles=${rpc_in_flight}
10576         # Set ost thread_max to $thread_max
10577         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10578
10579         # 5 Minutes should be sufficient for max number of OSS
10580         # threads(thread_max) to be created.
10581         local timeout=300
10582
10583         # Start I/O.
10584         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10585         test_mkdir $DIR/$tdir
10586         for i in $(seq $nfiles); do
10587                 local file=$DIR/$tdir/${tfile}-$i
10588                 $LFS setstripe -c -1 -i 0 $file
10589                 ($WTL $file $timeout)&
10590         done
10591
10592         # I/O Started - Wait for thread_started to reach thread_max or report
10593         # error if thread_started is more than thread_max.
10594         echo "Waiting for thread_started to reach thread_max"
10595         local thread_started=0
10596         local end_time=$((SECONDS + timeout))
10597
10598         while [ $SECONDS -le $end_time ] ; do
10599                 echo -n "."
10600                 # Get ost i/o thread_started count.
10601                 thread_started=$(do_facet ost1 \
10602                         "$LCTL get_param \
10603                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10604                 # Break out if thread_started is equal/greater than thread_max
10605                 if [[ $thread_started -ge $thread_max ]]; then
10606                         echo ll_ost_io thread_started $thread_started, \
10607                                 equal/greater than thread_max $thread_max
10608                         break
10609                 fi
10610                 sleep 1
10611         done
10612
10613         # Cleanup - We have the numbers, Kill i/o jobs if running.
10614         jobcount=($(jobs -p))
10615         for i in $(seq 0 $((${#jobcount[@]}-1)))
10616         do
10617                 kill -9 ${jobcount[$i]}
10618                 if [ $? -ne 0 ] ; then
10619                         echo Warning: \
10620                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10621                 fi
10622         done
10623
10624         # Cleanup files left by WTL binary.
10625         for i in $(seq $nfiles); do
10626                 local file=$DIR/$tdir/${tfile}-$i
10627                 rm -rf $file
10628                 if [ $? -ne 0 ] ; then
10629                         echo "Warning: Failed to delete file $file"
10630                 fi
10631         done
10632
10633         restore_lustre_params <$save_params
10634         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10635
10636         # Error out if no new thread has started or Thread started is greater
10637         # than thread max.
10638         if [[ $thread_started -le $OSTIO_pre ||
10639                         $thread_started -gt $thread_max ]]; then
10640                 error "ll_ost_io: thread_started $thread_started" \
10641                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10642                       "No new thread started or thread started greater " \
10643                       "than thread_max."
10644         fi
10645 }
10646 run_test 115 "verify dynamic thread creation===================="
10647
10648 free_min_max () {
10649         wait_delete_completed
10650         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10651         echo "OST kbytes available: ${AVAIL[@]}"
10652         MAXV=${AVAIL[0]}
10653         MAXI=0
10654         MINV=${AVAIL[0]}
10655         MINI=0
10656         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10657                 #echo OST $i: ${AVAIL[i]}kb
10658                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10659                         MAXV=${AVAIL[i]}
10660                         MAXI=$i
10661                 fi
10662                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10663                         MINV=${AVAIL[i]}
10664                         MINI=$i
10665                 fi
10666         done
10667         echo "Min free space: OST $MINI: $MINV"
10668         echo "Max free space: OST $MAXI: $MAXV"
10669 }
10670
10671 test_116a() { # was previously test_116()
10672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10673         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10674         remote_mds_nodsh && skip "remote MDS with nodsh"
10675
10676         echo -n "Free space priority "
10677         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10678                 head -n1
10679         declare -a AVAIL
10680         free_min_max
10681
10682         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10683         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10684         trap simple_cleanup_common EXIT
10685
10686         # Check if we need to generate uneven OSTs
10687         test_mkdir -p $DIR/$tdir/OST${MINI}
10688         local FILL=$((MINV / 4))
10689         local DIFF=$((MAXV - MINV))
10690         local DIFF2=$((DIFF * 100 / MINV))
10691
10692         local threshold=$(do_facet $SINGLEMDS \
10693                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10694         threshold=${threshold%%%}
10695         echo -n "Check for uneven OSTs: "
10696         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10697
10698         if [[ $DIFF2 -gt $threshold ]]; then
10699                 echo "ok"
10700                 echo "Don't need to fill OST$MINI"
10701         else
10702                 # generate uneven OSTs. Write 2% over the QOS threshold value
10703                 echo "no"
10704                 DIFF=$((threshold - DIFF2 + 2))
10705                 DIFF2=$((MINV * DIFF / 100))
10706                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10707                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10708                         error "setstripe failed"
10709                 DIFF=$((DIFF2 / 2048))
10710                 i=0
10711                 while [ $i -lt $DIFF ]; do
10712                         i=$((i + 1))
10713                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10714                                 bs=2M count=1 2>/dev/null
10715                         echo -n .
10716                 done
10717                 echo .
10718                 sync
10719                 sleep_maxage
10720                 free_min_max
10721         fi
10722
10723         DIFF=$((MAXV - MINV))
10724         DIFF2=$((DIFF * 100 / MINV))
10725         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10726         if [ $DIFF2 -gt $threshold ]; then
10727                 echo "ok"
10728         else
10729                 echo "failed - QOS mode won't be used"
10730                 simple_cleanup_common
10731                 skip "QOS imbalance criteria not met"
10732         fi
10733
10734         MINI1=$MINI
10735         MINV1=$MINV
10736         MAXI1=$MAXI
10737         MAXV1=$MAXV
10738
10739         # now fill using QOS
10740         $LFS setstripe -c 1 $DIR/$tdir
10741         FILL=$((FILL / 200))
10742         if [ $FILL -gt 600 ]; then
10743                 FILL=600
10744         fi
10745         echo "writing $FILL files to QOS-assigned OSTs"
10746         i=0
10747         while [ $i -lt $FILL ]; do
10748                 i=$((i + 1))
10749                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10750                         count=1 2>/dev/null
10751                 echo -n .
10752         done
10753         echo "wrote $i 200k files"
10754         sync
10755         sleep_maxage
10756
10757         echo "Note: free space may not be updated, so measurements might be off"
10758         free_min_max
10759         DIFF2=$((MAXV - MINV))
10760         echo "free space delta: orig $DIFF final $DIFF2"
10761         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10762         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10763         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10764         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10765         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10766         if [[ $DIFF -gt 0 ]]; then
10767                 FILL=$((DIFF2 * 100 / DIFF - 100))
10768                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10769         fi
10770
10771         # Figure out which files were written where
10772         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10773                awk '/'$MINI1': / {print $2; exit}')
10774         echo $UUID
10775         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10776         echo "$MINC files created on smaller OST $MINI1"
10777         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10778                awk '/'$MAXI1': / {print $2; exit}')
10779         echo $UUID
10780         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10781         echo "$MAXC files created on larger OST $MAXI1"
10782         if [[ $MINC -gt 0 ]]; then
10783                 FILL=$((MAXC * 100 / MINC - 100))
10784                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10785         fi
10786         [[ $MAXC -gt $MINC ]] ||
10787                 error_ignore LU-9 "stripe QOS didn't balance free space"
10788         simple_cleanup_common
10789 }
10790 run_test 116a "stripe QOS: free space balance ==================="
10791
10792 test_116b() { # LU-2093
10793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10794         remote_mds_nodsh && skip "remote MDS with nodsh"
10795
10796 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10797         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10798                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10799         [ -z "$old_rr" ] && skip "no QOS"
10800         do_facet $SINGLEMDS lctl set_param \
10801                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10802         mkdir -p $DIR/$tdir
10803         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10804         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10805         do_facet $SINGLEMDS lctl set_param fail_loc=0
10806         rm -rf $DIR/$tdir
10807         do_facet $SINGLEMDS lctl set_param \
10808                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10809 }
10810 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10811
10812 test_117() # bug 10891
10813 {
10814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10815
10816         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10817         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10818         lctl set_param fail_loc=0x21e
10819         > $DIR/$tfile || error "truncate failed"
10820         lctl set_param fail_loc=0
10821         echo "Truncate succeeded."
10822         rm -f $DIR/$tfile
10823 }
10824 run_test 117 "verify osd extend =========="
10825
10826 NO_SLOW_RESENDCOUNT=4
10827 export OLD_RESENDCOUNT=""
10828 set_resend_count () {
10829         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10830         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10831         lctl set_param -n $PROC_RESENDCOUNT $1
10832         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10833 }
10834
10835 # for reduce test_118* time (b=14842)
10836 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10837
10838 # Reset async IO behavior after error case
10839 reset_async() {
10840         FILE=$DIR/reset_async
10841
10842         # Ensure all OSCs are cleared
10843         $LFS setstripe -c -1 $FILE
10844         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10845         sync
10846         rm $FILE
10847 }
10848
10849 test_118a() #bug 11710
10850 {
10851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10852
10853         reset_async
10854
10855         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10856         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10857         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10858
10859         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10860                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10861                 return 1;
10862         fi
10863         rm -f $DIR/$tfile
10864 }
10865 run_test 118a "verify O_SYNC works =========="
10866
10867 test_118b()
10868 {
10869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10870         remote_ost_nodsh && skip "remote OST with nodsh"
10871
10872         reset_async
10873
10874         #define OBD_FAIL_SRV_ENOENT 0x217
10875         set_nodes_failloc "$(osts_nodes)" 0x217
10876         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10877         RC=$?
10878         set_nodes_failloc "$(osts_nodes)" 0
10879         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10880         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10881                     grep -c writeback)
10882
10883         if [[ $RC -eq 0 ]]; then
10884                 error "Must return error due to dropped pages, rc=$RC"
10885                 return 1;
10886         fi
10887
10888         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10889                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10890                 return 1;
10891         fi
10892
10893         echo "Dirty pages not leaked on ENOENT"
10894
10895         # Due to the above error the OSC will issue all RPCs syncronously
10896         # until a subsequent RPC completes successfully without error.
10897         $MULTIOP $DIR/$tfile Ow4096yc
10898         rm -f $DIR/$tfile
10899
10900         return 0
10901 }
10902 run_test 118b "Reclaim dirty pages on fatal error =========="
10903
10904 test_118c()
10905 {
10906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10907
10908         # for 118c, restore the original resend count, LU-1940
10909         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10910                                 set_resend_count $OLD_RESENDCOUNT
10911         remote_ost_nodsh && skip "remote OST with nodsh"
10912
10913         reset_async
10914
10915         #define OBD_FAIL_OST_EROFS               0x216
10916         set_nodes_failloc "$(osts_nodes)" 0x216
10917
10918         # multiop should block due to fsync until pages are written
10919         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10920         MULTIPID=$!
10921         sleep 1
10922
10923         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10924                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10925         fi
10926
10927         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10928                     grep -c writeback)
10929         if [[ $WRITEBACK -eq 0 ]]; then
10930                 error "No page in writeback, writeback=$WRITEBACK"
10931         fi
10932
10933         set_nodes_failloc "$(osts_nodes)" 0
10934         wait $MULTIPID
10935         RC=$?
10936         if [[ $RC -ne 0 ]]; then
10937                 error "Multiop fsync failed, rc=$RC"
10938         fi
10939
10940         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10941         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10942                     grep -c writeback)
10943         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10944                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10945         fi
10946
10947         rm -f $DIR/$tfile
10948         echo "Dirty pages flushed via fsync on EROFS"
10949         return 0
10950 }
10951 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10952
10953 # continue to use small resend count to reduce test_118* time (b=14842)
10954 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10955
10956 test_118d()
10957 {
10958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10959         remote_ost_nodsh && skip "remote OST with nodsh"
10960
10961         reset_async
10962
10963         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10964         set_nodes_failloc "$(osts_nodes)" 0x214
10965         # multiop should block due to fsync until pages are written
10966         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10967         MULTIPID=$!
10968         sleep 1
10969
10970         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10971                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10972         fi
10973
10974         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10975                     grep -c writeback)
10976         if [[ $WRITEBACK -eq 0 ]]; then
10977                 error "No page in writeback, writeback=$WRITEBACK"
10978         fi
10979
10980         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10981         set_nodes_failloc "$(osts_nodes)" 0
10982
10983         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10984         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10985                     grep -c writeback)
10986         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10987                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10988         fi
10989
10990         rm -f $DIR/$tfile
10991         echo "Dirty pages gaurenteed flushed via fsync"
10992         return 0
10993 }
10994 run_test 118d "Fsync validation inject a delay of the bulk =========="
10995
10996 test_118f() {
10997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10998
10999         reset_async
11000
11001         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11002         lctl set_param fail_loc=0x8000040a
11003
11004         # Should simulate EINVAL error which is fatal
11005         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11006         RC=$?
11007         if [[ $RC -eq 0 ]]; then
11008                 error "Must return error due to dropped pages, rc=$RC"
11009         fi
11010
11011         lctl set_param fail_loc=0x0
11012
11013         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11014         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11015         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11016                     grep -c writeback)
11017         if [[ $LOCKED -ne 0 ]]; then
11018                 error "Locked pages remain in cache, locked=$LOCKED"
11019         fi
11020
11021         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11022                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11023         fi
11024
11025         rm -f $DIR/$tfile
11026         echo "No pages locked after fsync"
11027
11028         reset_async
11029         return 0
11030 }
11031 run_test 118f "Simulate unrecoverable OSC side error =========="
11032
11033 test_118g() {
11034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11035
11036         reset_async
11037
11038         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11039         lctl set_param fail_loc=0x406
11040
11041         # simulate local -ENOMEM
11042         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11043         RC=$?
11044
11045         lctl set_param fail_loc=0
11046         if [[ $RC -eq 0 ]]; then
11047                 error "Must return error due to dropped pages, rc=$RC"
11048         fi
11049
11050         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11051         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11052         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11053                         grep -c writeback)
11054         if [[ $LOCKED -ne 0 ]]; then
11055                 error "Locked pages remain in cache, locked=$LOCKED"
11056         fi
11057
11058         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11059                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11060         fi
11061
11062         rm -f $DIR/$tfile
11063         echo "No pages locked after fsync"
11064
11065         reset_async
11066         return 0
11067 }
11068 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11069
11070 test_118h() {
11071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11072         remote_ost_nodsh && skip "remote OST with nodsh"
11073
11074         reset_async
11075
11076         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11077         set_nodes_failloc "$(osts_nodes)" 0x20e
11078         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11079         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11080         RC=$?
11081
11082         set_nodes_failloc "$(osts_nodes)" 0
11083         if [[ $RC -eq 0 ]]; then
11084                 error "Must return error due to dropped pages, rc=$RC"
11085         fi
11086
11087         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11088         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11089         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11090                     grep -c writeback)
11091         if [[ $LOCKED -ne 0 ]]; then
11092                 error "Locked pages remain in cache, locked=$LOCKED"
11093         fi
11094
11095         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11096                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11097         fi
11098
11099         rm -f $DIR/$tfile
11100         echo "No pages locked after fsync"
11101
11102         return 0
11103 }
11104 run_test 118h "Verify timeout in handling recoverables errors  =========="
11105
11106 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11107
11108 test_118i() {
11109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11110         remote_ost_nodsh && skip "remote OST with nodsh"
11111
11112         reset_async
11113
11114         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11115         set_nodes_failloc "$(osts_nodes)" 0x20e
11116
11117         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11118         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11119         PID=$!
11120         sleep 5
11121         set_nodes_failloc "$(osts_nodes)" 0
11122
11123         wait $PID
11124         RC=$?
11125         if [[ $RC -ne 0 ]]; then
11126                 error "got error, but should be not, rc=$RC"
11127         fi
11128
11129         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11130         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11131         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11132         if [[ $LOCKED -ne 0 ]]; then
11133                 error "Locked pages remain in cache, locked=$LOCKED"
11134         fi
11135
11136         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11137                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11138         fi
11139
11140         rm -f $DIR/$tfile
11141         echo "No pages locked after fsync"
11142
11143         return 0
11144 }
11145 run_test 118i "Fix error before timeout in recoverable error  =========="
11146
11147 [ "$SLOW" = "no" ] && set_resend_count 4
11148
11149 test_118j() {
11150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11151         remote_ost_nodsh && skip "remote OST with nodsh"
11152
11153         reset_async
11154
11155         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11156         set_nodes_failloc "$(osts_nodes)" 0x220
11157
11158         # return -EIO from OST
11159         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11160         RC=$?
11161         set_nodes_failloc "$(osts_nodes)" 0x0
11162         if [[ $RC -eq 0 ]]; then
11163                 error "Must return error due to dropped pages, rc=$RC"
11164         fi
11165
11166         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11167         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11168         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11169         if [[ $LOCKED -ne 0 ]]; then
11170                 error "Locked pages remain in cache, locked=$LOCKED"
11171         fi
11172
11173         # in recoverable error on OST we want resend and stay until it finished
11174         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11175                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11176         fi
11177
11178         rm -f $DIR/$tfile
11179         echo "No pages locked after fsync"
11180
11181         return 0
11182 }
11183 run_test 118j "Simulate unrecoverable OST side error =========="
11184
11185 test_118k()
11186 {
11187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11188         remote_ost_nodsh && skip "remote OSTs with nodsh"
11189
11190         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11191         set_nodes_failloc "$(osts_nodes)" 0x20e
11192         test_mkdir $DIR/$tdir
11193
11194         for ((i=0;i<10;i++)); do
11195                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11196                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11197                 SLEEPPID=$!
11198                 sleep 0.500s
11199                 kill $SLEEPPID
11200                 wait $SLEEPPID
11201         done
11202
11203         set_nodes_failloc "$(osts_nodes)" 0
11204         rm -rf $DIR/$tdir
11205 }
11206 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11207
11208 test_118l() # LU-646
11209 {
11210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11211
11212         test_mkdir $DIR/$tdir
11213         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11214         rm -rf $DIR/$tdir
11215 }
11216 run_test 118l "fsync dir"
11217
11218 test_118m() # LU-3066
11219 {
11220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11221
11222         test_mkdir $DIR/$tdir
11223         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11224         rm -rf $DIR/$tdir
11225 }
11226 run_test 118m "fdatasync dir ========="
11227
11228 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11229
11230 test_118n()
11231 {
11232         local begin
11233         local end
11234
11235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11236         remote_ost_nodsh && skip "remote OSTs with nodsh"
11237
11238         # Sleep to avoid a cached response.
11239         #define OBD_STATFS_CACHE_SECONDS 1
11240         sleep 2
11241
11242         # Inject a 10 second delay in the OST_STATFS handler.
11243         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11244         set_nodes_failloc "$(osts_nodes)" 0x242
11245
11246         begin=$SECONDS
11247         stat --file-system $MOUNT > /dev/null
11248         end=$SECONDS
11249
11250         set_nodes_failloc "$(osts_nodes)" 0
11251
11252         if ((end - begin > 20)); then
11253             error "statfs took $((end - begin)) seconds, expected 10"
11254         fi
11255 }
11256 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11257
11258 test_119a() # bug 11737
11259 {
11260         BSIZE=$((512 * 1024))
11261         directio write $DIR/$tfile 0 1 $BSIZE
11262         # We ask to read two blocks, which is more than a file size.
11263         # directio will indicate an error when requested and actual
11264         # sizes aren't equeal (a normal situation in this case) and
11265         # print actual read amount.
11266         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11267         if [ "$NOB" != "$BSIZE" ]; then
11268                 error "read $NOB bytes instead of $BSIZE"
11269         fi
11270         rm -f $DIR/$tfile
11271 }
11272 run_test 119a "Short directIO read must return actual read amount"
11273
11274 test_119b() # bug 11737
11275 {
11276         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11277
11278         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11279         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11280         sync
11281         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11282                 error "direct read failed"
11283         rm -f $DIR/$tfile
11284 }
11285 run_test 119b "Sparse directIO read must return actual read amount"
11286
11287 test_119c() # bug 13099
11288 {
11289         BSIZE=1048576
11290         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11291         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11292         rm -f $DIR/$tfile
11293 }
11294 run_test 119c "Testing for direct read hitting hole"
11295
11296 test_119d() # bug 15950
11297 {
11298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11299
11300         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11301         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11302         BSIZE=1048576
11303         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11304         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11305         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11306         lctl set_param fail_loc=0x40d
11307         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11308         pid_dio=$!
11309         sleep 1
11310         cat $DIR/$tfile > /dev/null &
11311         lctl set_param fail_loc=0
11312         pid_reads=$!
11313         wait $pid_dio
11314         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11315         sleep 2
11316         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11317         error "the read rpcs have not completed in 2s"
11318         rm -f $DIR/$tfile
11319         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11320 }
11321 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11322
11323 test_120a() {
11324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11325         remote_mds_nodsh && skip "remote MDS with nodsh"
11326         test_mkdir -i0 -c1 $DIR/$tdir
11327         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11328                 skip_env "no early lock cancel on server"
11329
11330         lru_resize_disable mdc
11331         lru_resize_disable osc
11332         cancel_lru_locks mdc
11333         # asynchronous object destroy at MDT could cause bl ast to client
11334         cancel_lru_locks osc
11335
11336         stat $DIR/$tdir > /dev/null
11337         can1=$(do_facet mds1 \
11338                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11339                awk '/ldlm_cancel/ {print $2}')
11340         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11341                awk '/ldlm_bl_callback/ {print $2}')
11342         test_mkdir -i0 -c1 $DIR/$tdir/d1
11343         can2=$(do_facet mds1 \
11344                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11345                awk '/ldlm_cancel/ {print $2}')
11346         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11347                awk '/ldlm_bl_callback/ {print $2}')
11348         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11349         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11350         lru_resize_enable mdc
11351         lru_resize_enable osc
11352 }
11353 run_test 120a "Early Lock Cancel: mkdir test"
11354
11355 test_120b() {
11356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11357         remote_mds_nodsh && skip "remote MDS with nodsh"
11358         test_mkdir $DIR/$tdir
11359         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11360                 skip_env "no early lock cancel on server"
11361
11362         lru_resize_disable mdc
11363         lru_resize_disable osc
11364         cancel_lru_locks mdc
11365         stat $DIR/$tdir > /dev/null
11366         can1=$(do_facet $SINGLEMDS \
11367                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11368                awk '/ldlm_cancel/ {print $2}')
11369         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11370                awk '/ldlm_bl_callback/ {print $2}')
11371         touch $DIR/$tdir/f1
11372         can2=$(do_facet $SINGLEMDS \
11373                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11374                awk '/ldlm_cancel/ {print $2}')
11375         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11376                awk '/ldlm_bl_callback/ {print $2}')
11377         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11378         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11379         lru_resize_enable mdc
11380         lru_resize_enable osc
11381 }
11382 run_test 120b "Early Lock Cancel: create test"
11383
11384 test_120c() {
11385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11386         remote_mds_nodsh && skip "remote MDS with nodsh"
11387         test_mkdir -i0 -c1 $DIR/$tdir
11388         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11389                 skip "no early lock cancel on server"
11390
11391         lru_resize_disable mdc
11392         lru_resize_disable osc
11393         test_mkdir -i0 -c1 $DIR/$tdir/d1
11394         test_mkdir -i0 -c1 $DIR/$tdir/d2
11395         touch $DIR/$tdir/d1/f1
11396         cancel_lru_locks mdc
11397         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11398         can1=$(do_facet mds1 \
11399                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11400                awk '/ldlm_cancel/ {print $2}')
11401         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11402                awk '/ldlm_bl_callback/ {print $2}')
11403         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11404         can2=$(do_facet mds1 \
11405                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11406                awk '/ldlm_cancel/ {print $2}')
11407         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11408                awk '/ldlm_bl_callback/ {print $2}')
11409         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11410         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11411         lru_resize_enable mdc
11412         lru_resize_enable osc
11413 }
11414 run_test 120c "Early Lock Cancel: link test"
11415
11416 test_120d() {
11417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11418         remote_mds_nodsh && skip "remote MDS with nodsh"
11419         test_mkdir -i0 -c1 $DIR/$tdir
11420         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11421                 skip_env "no early lock cancel on server"
11422
11423         lru_resize_disable mdc
11424         lru_resize_disable osc
11425         touch $DIR/$tdir
11426         cancel_lru_locks mdc
11427         stat $DIR/$tdir > /dev/null
11428         can1=$(do_facet mds1 \
11429                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11430                awk '/ldlm_cancel/ {print $2}')
11431         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11432                awk '/ldlm_bl_callback/ {print $2}')
11433         chmod a+x $DIR/$tdir
11434         can2=$(do_facet mds1 \
11435                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11436                awk '/ldlm_cancel/ {print $2}')
11437         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11438                awk '/ldlm_bl_callback/ {print $2}')
11439         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11440         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11441         lru_resize_enable mdc
11442         lru_resize_enable osc
11443 }
11444 run_test 120d "Early Lock Cancel: setattr test"
11445
11446 test_120e() {
11447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11448         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11449                 skip_env "no early lock cancel on server"
11450         remote_mds_nodsh && skip "remote MDS with nodsh"
11451
11452         local dlmtrace_set=false
11453
11454         test_mkdir -i0 -c1 $DIR/$tdir
11455         lru_resize_disable mdc
11456         lru_resize_disable osc
11457         ! $LCTL get_param debug | grep -q dlmtrace &&
11458                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11459         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11460         cancel_lru_locks mdc
11461         cancel_lru_locks osc
11462         dd if=$DIR/$tdir/f1 of=/dev/null
11463         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11464         # XXX client can not do early lock cancel of OST lock
11465         # during unlink (LU-4206), so cancel osc lock now.
11466         sleep 2
11467         cancel_lru_locks osc
11468         can1=$(do_facet mds1 \
11469                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11470                awk '/ldlm_cancel/ {print $2}')
11471         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11472                awk '/ldlm_bl_callback/ {print $2}')
11473         unlink $DIR/$tdir/f1
11474         sleep 5
11475         can2=$(do_facet mds1 \
11476                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11477                awk '/ldlm_cancel/ {print $2}')
11478         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11479                awk '/ldlm_bl_callback/ {print $2}')
11480         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11481                 $LCTL dk $TMP/cancel.debug.txt
11482         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11483                 $LCTL dk $TMP/blocking.debug.txt
11484         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11485         lru_resize_enable mdc
11486         lru_resize_enable osc
11487 }
11488 run_test 120e "Early Lock Cancel: unlink test"
11489
11490 test_120f() {
11491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11492         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11493                 skip_env "no early lock cancel on server"
11494         remote_mds_nodsh && skip "remote MDS with nodsh"
11495
11496         test_mkdir -i0 -c1 $DIR/$tdir
11497         lru_resize_disable mdc
11498         lru_resize_disable osc
11499         test_mkdir -i0 -c1 $DIR/$tdir/d1
11500         test_mkdir -i0 -c1 $DIR/$tdir/d2
11501         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11502         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11503         cancel_lru_locks mdc
11504         cancel_lru_locks osc
11505         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11506         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11507         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11508         # XXX client can not do early lock cancel of OST lock
11509         # during rename (LU-4206), so cancel osc lock now.
11510         sleep 2
11511         cancel_lru_locks osc
11512         can1=$(do_facet mds1 \
11513                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11514                awk '/ldlm_cancel/ {print $2}')
11515         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11516                awk '/ldlm_bl_callback/ {print $2}')
11517         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11518         sleep 5
11519         can2=$(do_facet mds1 \
11520                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11521                awk '/ldlm_cancel/ {print $2}')
11522         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11523                awk '/ldlm_bl_callback/ {print $2}')
11524         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11525         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11526         lru_resize_enable mdc
11527         lru_resize_enable osc
11528 }
11529 run_test 120f "Early Lock Cancel: rename test"
11530
11531 test_120g() {
11532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11533         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11534                 skip_env "no early lock cancel on server"
11535         remote_mds_nodsh && skip "remote MDS with nodsh"
11536
11537         lru_resize_disable mdc
11538         lru_resize_disable osc
11539         count=10000
11540         echo create $count files
11541         test_mkdir $DIR/$tdir
11542         cancel_lru_locks mdc
11543         cancel_lru_locks osc
11544         t0=$(date +%s)
11545
11546         can0=$(do_facet $SINGLEMDS \
11547                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11548                awk '/ldlm_cancel/ {print $2}')
11549         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11550                awk '/ldlm_bl_callback/ {print $2}')
11551         createmany -o $DIR/$tdir/f $count
11552         sync
11553         can1=$(do_facet $SINGLEMDS \
11554                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11555                awk '/ldlm_cancel/ {print $2}')
11556         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11557                awk '/ldlm_bl_callback/ {print $2}')
11558         t1=$(date +%s)
11559         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11560         echo rm $count files
11561         rm -r $DIR/$tdir
11562         sync
11563         can2=$(do_facet $SINGLEMDS \
11564                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11565                awk '/ldlm_cancel/ {print $2}')
11566         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11567                awk '/ldlm_bl_callback/ {print $2}')
11568         t2=$(date +%s)
11569         echo total: $count removes in $((t2-t1))
11570         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11571         sleep 2
11572         # wait for commitment of removal
11573         lru_resize_enable mdc
11574         lru_resize_enable osc
11575 }
11576 run_test 120g "Early Lock Cancel: performance test"
11577
11578 test_121() { #bug #10589
11579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11580
11581         rm -rf $DIR/$tfile
11582         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11583 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11584         lctl set_param fail_loc=0x310
11585         cancel_lru_locks osc > /dev/null
11586         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11587         lctl set_param fail_loc=0
11588         [[ $reads -eq $writes ]] ||
11589                 error "read $reads blocks, must be $writes blocks"
11590 }
11591 run_test 121 "read cancel race ========="
11592
11593 test_123a_base() { # was test 123, statahead(bug 11401)
11594         local lsx="$1"
11595
11596         SLOWOK=0
11597         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11598                 log "testing UP system. Performance may be lower than expected."
11599                 SLOWOK=1
11600         fi
11601
11602         rm -rf $DIR/$tdir
11603         test_mkdir $DIR/$tdir
11604         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11605         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11606         MULT=10
11607         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11608                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11609
11610                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11611                 lctl set_param -n llite.*.statahead_max 0
11612                 lctl get_param llite.*.statahead_max
11613                 cancel_lru_locks mdc
11614                 cancel_lru_locks osc
11615                 stime=$(date +%s)
11616                 time $lsx $DIR/$tdir | wc -l
11617                 etime=$(date +%s)
11618                 delta=$((etime - stime))
11619                 log "$lsx $i files without statahead: $delta sec"
11620                 lctl set_param llite.*.statahead_max=$max
11621
11622                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11623                         grep "statahead wrong:" | awk '{print $3}')
11624                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11625                 cancel_lru_locks mdc
11626                 cancel_lru_locks osc
11627                 stime=$(date +%s)
11628                 time $lsx $DIR/$tdir | wc -l
11629                 etime=$(date +%s)
11630                 delta_sa=$((etime - stime))
11631                 log "$lsx $i files with statahead: $delta_sa sec"
11632                 lctl get_param -n llite.*.statahead_stats
11633                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11634                         grep "statahead wrong:" | awk '{print $3}')
11635
11636                 [[ $swrong -lt $ewrong ]] &&
11637                         log "statahead was stopped, maybe too many locks held!"
11638                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11639
11640                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11641                         max=$(lctl get_param -n llite.*.statahead_max |
11642                                 head -n 1)
11643                         lctl set_param -n llite.*.statahead_max 0
11644                         lctl get_param llite.*.statahead_max
11645                         cancel_lru_locks mdc
11646                         cancel_lru_locks osc
11647                         stime=$(date +%s)
11648                         time $lsx $DIR/$tdir | wc -l
11649                         etime=$(date +%s)
11650                         delta=$((etime - stime))
11651                         log "$lsx $i files again without statahead: $delta sec"
11652                         lctl set_param llite.*.statahead_max=$max
11653                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11654                                 if [  $SLOWOK -eq 0 ]; then
11655                                         error "$lsx $i files is slower with statahead!"
11656                                 else
11657                                         log "$lsx $i files is slower with statahead!"
11658                                 fi
11659                                 break
11660                         fi
11661                 fi
11662
11663                 [ $delta -gt 20 ] && break
11664                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11665                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11666         done
11667         log "$lsx done"
11668
11669         stime=$(date +%s)
11670         rm -r $DIR/$tdir
11671         sync
11672         etime=$(date +%s)
11673         delta=$((etime - stime))
11674         log "rm -r $DIR/$tdir/: $delta seconds"
11675         log "rm done"
11676         lctl get_param -n llite.*.statahead_stats
11677 }
11678
11679 test_123aa() {
11680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11681
11682         test_123a_base "ls -l"
11683 }
11684 run_test 123aa "verify statahead work"
11685
11686 test_123ab() {
11687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11688
11689         statx_supported || skip_env "Test must be statx() syscall supported"
11690
11691         test_123a_base "$STATX -l"
11692 }
11693 run_test 123ab "verify statahead work by using statx"
11694
11695 test_123ac() {
11696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11697
11698         statx_supported || skip_env "Test must be statx() syscall supported"
11699
11700         local rpcs_before
11701         local rpcs_after
11702         local agl_before
11703         local agl_after
11704
11705         cancel_lru_locks $OSC
11706         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11707         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11708                 awk '/agl.total:/ {print $3}')
11709         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11710         test_123a_base "$STATX --cached=always -D"
11711         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11712                 awk '/agl.total:/ {print $3}')
11713         [ $agl_before -eq $agl_after ] ||
11714                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11715         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11716         [ $rpcs_after -eq $rpcs_before ] ||
11717                 error "$STATX should not send glimpse RPCs to $OSC"
11718 }
11719 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11720
11721 test_123b () { # statahead(bug 15027)
11722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11723
11724         test_mkdir $DIR/$tdir
11725         createmany -o $DIR/$tdir/$tfile-%d 1000
11726
11727         cancel_lru_locks mdc
11728         cancel_lru_locks osc
11729
11730 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11731         lctl set_param fail_loc=0x80000803
11732         ls -lR $DIR/$tdir > /dev/null
11733         log "ls done"
11734         lctl set_param fail_loc=0x0
11735         lctl get_param -n llite.*.statahead_stats
11736         rm -r $DIR/$tdir
11737         sync
11738
11739 }
11740 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11741
11742 test_123c() {
11743         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11744
11745         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11746         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11747         touch $DIR/$tdir.1/{1..3}
11748         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11749
11750         remount_client $MOUNT
11751
11752         $MULTIOP $DIR/$tdir.0 Q
11753
11754         # let statahead to complete
11755         ls -l $DIR/$tdir.0 > /dev/null
11756
11757         testid=$(echo $TESTNAME | tr '_' ' ')
11758         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11759                 error "statahead warning" || true
11760 }
11761 run_test 123c "Can not initialize inode warning on DNE statahead"
11762
11763 test_124a() {
11764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11765         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11766                 skip_env "no lru resize on server"
11767
11768         local NR=2000
11769
11770         test_mkdir $DIR/$tdir
11771
11772         log "create $NR files at $DIR/$tdir"
11773         createmany -o $DIR/$tdir/f $NR ||
11774                 error "failed to create $NR files in $DIR/$tdir"
11775
11776         cancel_lru_locks mdc
11777         ls -l $DIR/$tdir > /dev/null
11778
11779         local NSDIR=""
11780         local LRU_SIZE=0
11781         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11782                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11783                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11784                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11785                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11786                         log "NSDIR=$NSDIR"
11787                         log "NS=$(basename $NSDIR)"
11788                         break
11789                 fi
11790         done
11791
11792         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11793                 skip "Not enough cached locks created!"
11794         fi
11795         log "LRU=$LRU_SIZE"
11796
11797         local SLEEP=30
11798
11799         # We know that lru resize allows one client to hold $LIMIT locks
11800         # for 10h. After that locks begin to be killed by client.
11801         local MAX_HRS=10
11802         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11803         log "LIMIT=$LIMIT"
11804         if [ $LIMIT -lt $LRU_SIZE ]; then
11805                 skip "Limit is too small $LIMIT"
11806         fi
11807
11808         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11809         # killing locks. Some time was spent for creating locks. This means
11810         # that up to the moment of sleep finish we must have killed some of
11811         # them (10-100 locks). This depends on how fast ther were created.
11812         # Many of them were touched in almost the same moment and thus will
11813         # be killed in groups.
11814         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11815
11816         # Use $LRU_SIZE_B here to take into account real number of locks
11817         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11818         local LRU_SIZE_B=$LRU_SIZE
11819         log "LVF=$LVF"
11820         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11821         log "OLD_LVF=$OLD_LVF"
11822         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11823
11824         # Let's make sure that we really have some margin. Client checks
11825         # cached locks every 10 sec.
11826         SLEEP=$((SLEEP+20))
11827         log "Sleep ${SLEEP} sec"
11828         local SEC=0
11829         while ((SEC<$SLEEP)); do
11830                 echo -n "..."
11831                 sleep 5
11832                 SEC=$((SEC+5))
11833                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11834                 echo -n "$LRU_SIZE"
11835         done
11836         echo ""
11837         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11838         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11839
11840         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11841                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11842                 unlinkmany $DIR/$tdir/f $NR
11843                 return
11844         }
11845
11846         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11847         log "unlink $NR files at $DIR/$tdir"
11848         unlinkmany $DIR/$tdir/f $NR
11849 }
11850 run_test 124a "lru resize ======================================="
11851
11852 get_max_pool_limit()
11853 {
11854         local limit=$($LCTL get_param \
11855                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11856         local max=0
11857         for l in $limit; do
11858                 if [[ $l -gt $max ]]; then
11859                         max=$l
11860                 fi
11861         done
11862         echo $max
11863 }
11864
11865 test_124b() {
11866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11867         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11868                 skip_env "no lru resize on server"
11869
11870         LIMIT=$(get_max_pool_limit)
11871
11872         NR=$(($(default_lru_size)*20))
11873         if [[ $NR -gt $LIMIT ]]; then
11874                 log "Limit lock number by $LIMIT locks"
11875                 NR=$LIMIT
11876         fi
11877
11878         IFree=$(mdsrate_inodes_available)
11879         if [ $IFree -lt $NR ]; then
11880                 log "Limit lock number by $IFree inodes"
11881                 NR=$IFree
11882         fi
11883
11884         lru_resize_disable mdc
11885         test_mkdir -p $DIR/$tdir/disable_lru_resize
11886
11887         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11888         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11889         cancel_lru_locks mdc
11890         stime=`date +%s`
11891         PID=""
11892         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11893         PID="$PID $!"
11894         sleep 2
11895         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11896         PID="$PID $!"
11897         sleep 2
11898         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11899         PID="$PID $!"
11900         wait $PID
11901         etime=`date +%s`
11902         nolruresize_delta=$((etime-stime))
11903         log "ls -la time: $nolruresize_delta seconds"
11904         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11905         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11906
11907         lru_resize_enable mdc
11908         test_mkdir -p $DIR/$tdir/enable_lru_resize
11909
11910         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11911         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11912         cancel_lru_locks mdc
11913         stime=`date +%s`
11914         PID=""
11915         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11916         PID="$PID $!"
11917         sleep 2
11918         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11919         PID="$PID $!"
11920         sleep 2
11921         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11922         PID="$PID $!"
11923         wait $PID
11924         etime=`date +%s`
11925         lruresize_delta=$((etime-stime))
11926         log "ls -la time: $lruresize_delta seconds"
11927         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11928
11929         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11930                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11931         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11932                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11933         else
11934                 log "lru resize performs the same with no lru resize"
11935         fi
11936         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11937 }
11938 run_test 124b "lru resize (performance test) ======================="
11939
11940 test_124c() {
11941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11942         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11943                 skip_env "no lru resize on server"
11944
11945         # cache ununsed locks on client
11946         local nr=100
11947         cancel_lru_locks mdc
11948         test_mkdir $DIR/$tdir
11949         createmany -o $DIR/$tdir/f $nr ||
11950                 error "failed to create $nr files in $DIR/$tdir"
11951         ls -l $DIR/$tdir > /dev/null
11952
11953         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11954         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11955         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11956         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11957         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11958
11959         # set lru_max_age to 1 sec
11960         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11961         echo "sleep $((recalc_p * 2)) seconds..."
11962         sleep $((recalc_p * 2))
11963
11964         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11965         # restore lru_max_age
11966         $LCTL set_param -n $nsdir.lru_max_age $max_age
11967         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11968         unlinkmany $DIR/$tdir/f $nr
11969 }
11970 run_test 124c "LRUR cancel very aged locks"
11971
11972 test_124d() {
11973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11974         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11975                 skip_env "no lru resize on server"
11976
11977         # cache ununsed locks on client
11978         local nr=100
11979
11980         lru_resize_disable mdc
11981         stack_trap "lru_resize_enable mdc" EXIT
11982
11983         cancel_lru_locks mdc
11984
11985         # asynchronous object destroy at MDT could cause bl ast to client
11986         test_mkdir $DIR/$tdir
11987         createmany -o $DIR/$tdir/f $nr ||
11988                 error "failed to create $nr files in $DIR/$tdir"
11989         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11990
11991         ls -l $DIR/$tdir > /dev/null
11992
11993         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11994         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11995         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11996         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11997
11998         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11999
12000         # set lru_max_age to 1 sec
12001         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12002         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12003
12004         echo "sleep $((recalc_p * 2)) seconds..."
12005         sleep $((recalc_p * 2))
12006
12007         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12008
12009         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12010 }
12011 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12012
12013 test_125() { # 13358
12014         $LCTL get_param -n llite.*.client_type | grep -q local ||
12015                 skip "must run as local client"
12016         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12017                 skip_env "must have acl enabled"
12018         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12019
12020         test_mkdir $DIR/$tdir
12021         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12022         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12023         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12024 }
12025 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12026
12027 test_126() { # bug 12829/13455
12028         $GSS && skip_env "must run as gss disabled"
12029         $LCTL get_param -n llite.*.client_type | grep -q local ||
12030                 skip "must run as local client"
12031         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12032
12033         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12034         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12035         rm -f $DIR/$tfile
12036         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12037 }
12038 run_test 126 "check that the fsgid provided by the client is taken into account"
12039
12040 test_127a() { # bug 15521
12041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12042         local name count samp unit min max sum sumsq
12043
12044         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12045         echo "stats before reset"
12046         $LCTL get_param osc.*.stats
12047         $LCTL set_param osc.*.stats=0
12048         local fsize=$((2048 * 1024))
12049
12050         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12051         cancel_lru_locks osc
12052         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12053
12054         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12055         stack_trap "rm -f $TMP/$tfile.tmp"
12056         while read name count samp unit min max sum sumsq; do
12057                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12058                 [ ! $min ] && error "Missing min value for $name proc entry"
12059                 eval $name=$count || error "Wrong proc format"
12060
12061                 case $name in
12062                 read_bytes|write_bytes)
12063                         [[ "$unit" =~ "bytes" ]] ||
12064                                 error "unit is not 'bytes': $unit"
12065                         (( $min >= 4096 )) || error "min is too small: $min"
12066                         (( $min <= $fsize )) || error "min is too big: $min"
12067                         (( $max >= 4096 )) || error "max is too small: $max"
12068                         (( $max <= $fsize )) || error "max is too big: $max"
12069                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12070                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12071                                 error "sumsquare is too small: $sumsq"
12072                         (( $sumsq <= $fsize * $fsize )) ||
12073                                 error "sumsquare is too big: $sumsq"
12074                         ;;
12075                 ost_read|ost_write)
12076                         [[ "$unit" =~ "usec" ]] ||
12077                                 error "unit is not 'usec': $unit"
12078                         ;;
12079                 *)      ;;
12080                 esac
12081         done < $DIR/$tfile.tmp
12082
12083         #check that we actually got some stats
12084         [ "$read_bytes" ] || error "Missing read_bytes stats"
12085         [ "$write_bytes" ] || error "Missing write_bytes stats"
12086         [ "$read_bytes" != 0 ] || error "no read done"
12087         [ "$write_bytes" != 0 ] || error "no write done"
12088 }
12089 run_test 127a "verify the client stats are sane"
12090
12091 test_127b() { # bug LU-333
12092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12093         local name count samp unit min max sum sumsq
12094
12095         echo "stats before reset"
12096         $LCTL get_param llite.*.stats
12097         $LCTL set_param llite.*.stats=0
12098
12099         # perform 2 reads and writes so MAX is different from SUM.
12100         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12101         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12102         cancel_lru_locks osc
12103         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12104         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12105
12106         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12107         stack_trap "rm -f $TMP/$tfile.tmp"
12108         while read name count samp unit min max sum sumsq; do
12109                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12110                 eval $name=$count || error "Wrong proc format"
12111
12112                 case $name in
12113                 read_bytes|write_bytes)
12114                         [[ "$unit" =~ "bytes" ]] ||
12115                                 error "unit is not 'bytes': $unit"
12116                         (( $count == 2 )) || error "count is not 2: $count"
12117                         (( $min == $PAGE_SIZE )) ||
12118                                 error "min is not $PAGE_SIZE: $min"
12119                         (( $max == $PAGE_SIZE )) ||
12120                                 error "max is not $PAGE_SIZE: $max"
12121                         (( $sum == $PAGE_SIZE * 2 )) ||
12122                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12123                         ;;
12124                 read|write)
12125                         [[ "$unit" =~ "usec" ]] ||
12126                                 error "unit is not 'usec': $unit"
12127                         ;;
12128                 *)      ;;
12129                 esac
12130         done < $TMP/$tfile.tmp
12131
12132         #check that we actually got some stats
12133         [ "$read_bytes" ] || error "Missing read_bytes stats"
12134         [ "$write_bytes" ] || error "Missing write_bytes stats"
12135         [ "$read_bytes" != 0 ] || error "no read done"
12136         [ "$write_bytes" != 0 ] || error "no write done"
12137 }
12138 run_test 127b "verify the llite client stats are sane"
12139
12140 test_127c() { # LU-12394
12141         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12142         local size
12143         local bsize
12144         local reads
12145         local writes
12146         local count
12147
12148         $LCTL set_param llite.*.extents_stats=1
12149         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12150
12151         # Use two stripes so there is enough space in default config
12152         $LFS setstripe -c 2 $DIR/$tfile
12153
12154         # Extent stats start at 0-4K and go in power of two buckets
12155         # LL_HIST_START = 12 --> 2^12 = 4K
12156         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12157         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12158         # small configs
12159         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12160                 do
12161                 # Write and read, 2x each, second time at a non-zero offset
12162                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12163                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12164                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12165                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12166                 rm -f $DIR/$tfile
12167         done
12168
12169         $LCTL get_param llite.*.extents_stats
12170
12171         count=2
12172         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12173                 do
12174                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12175                                 grep -m 1 $bsize)
12176                 reads=$(echo $bucket | awk '{print $5}')
12177                 writes=$(echo $bucket | awk '{print $9}')
12178                 [ "$reads" -eq $count ] ||
12179                         error "$reads reads in < $bsize bucket, expect $count"
12180                 [ "$writes" -eq $count ] ||
12181                         error "$writes writes in < $bsize bucket, expect $count"
12182         done
12183
12184         # Test mmap write and read
12185         $LCTL set_param llite.*.extents_stats=c
12186         size=512
12187         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12188         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12189         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12190
12191         $LCTL get_param llite.*.extents_stats
12192
12193         count=$(((size*1024) / PAGE_SIZE))
12194
12195         bsize=$((2 * PAGE_SIZE / 1024))K
12196
12197         bucket=$($LCTL get_param -n llite.*.extents_stats |
12198                         grep -m 1 $bsize)
12199         reads=$(echo $bucket | awk '{print $5}')
12200         writes=$(echo $bucket | awk '{print $9}')
12201         # mmap writes fault in the page first, creating an additonal read
12202         [ "$reads" -eq $((2 * count)) ] ||
12203                 error "$reads reads in < $bsize bucket, expect $count"
12204         [ "$writes" -eq $count ] ||
12205                 error "$writes writes in < $bsize bucket, expect $count"
12206 }
12207 run_test 127c "test llite extent stats with regular & mmap i/o"
12208
12209 test_128() { # bug 15212
12210         touch $DIR/$tfile
12211         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12212                 find $DIR/$tfile
12213                 find $DIR/$tfile
12214         EOF
12215
12216         result=$(grep error $TMP/$tfile.log)
12217         rm -f $DIR/$tfile $TMP/$tfile.log
12218         [ -z "$result" ] ||
12219                 error "consecutive find's under interactive lfs failed"
12220 }
12221 run_test 128 "interactive lfs for 2 consecutive find's"
12222
12223 set_dir_limits () {
12224         local mntdev
12225         local canondev
12226         local node
12227
12228         local ldproc=/proc/fs/ldiskfs
12229         local facets=$(get_facets MDS)
12230
12231         for facet in ${facets//,/ }; do
12232                 canondev=$(ldiskfs_canon \
12233                            *.$(convert_facet2label $facet).mntdev $facet)
12234                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12235                         ldproc=/sys/fs/ldiskfs
12236                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12237                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12238         done
12239 }
12240
12241 check_mds_dmesg() {
12242         local facets=$(get_facets MDS)
12243         for facet in ${facets//,/ }; do
12244                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12245         done
12246         return 1
12247 }
12248
12249 test_129() {
12250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12251         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12252                 skip "Need MDS version with at least 2.5.56"
12253         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12254                 skip_env "ldiskfs only test"
12255         fi
12256         remote_mds_nodsh && skip "remote MDS with nodsh"
12257
12258         local ENOSPC=28
12259         local has_warning=false
12260
12261         rm -rf $DIR/$tdir
12262         mkdir -p $DIR/$tdir
12263
12264         # block size of mds1
12265         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12266         set_dir_limits $maxsize $((maxsize * 6 / 8))
12267         stack_trap "set_dir_limits 0 0"
12268         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12269         local dirsize=$(stat -c%s "$DIR/$tdir")
12270         local nfiles=0
12271         while (( $dirsize <= $maxsize )); do
12272                 $MCREATE $DIR/$tdir/file_base_$nfiles
12273                 rc=$?
12274                 # check two errors:
12275                 # ENOSPC for ext4 max_dir_size, which has been used since
12276                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12277                 if (( rc == ENOSPC )); then
12278                         set_dir_limits 0 0
12279                         echo "rc=$rc returned as expected after $nfiles files"
12280
12281                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12282                                 error "create failed w/o dir size limit"
12283
12284                         # messages may be rate limited if test is run repeatedly
12285                         check_mds_dmesg '"is approaching max"' ||
12286                                 echo "warning message should be output"
12287                         check_mds_dmesg '"has reached max"' ||
12288                                 echo "reached message should be output"
12289
12290                         dirsize=$(stat -c%s "$DIR/$tdir")
12291
12292                         [[ $dirsize -ge $maxsize ]] && return 0
12293                         error "dirsize $dirsize < $maxsize after $nfiles files"
12294                 elif (( rc != 0 )); then
12295                         break
12296                 fi
12297                 nfiles=$((nfiles + 1))
12298                 dirsize=$(stat -c%s "$DIR/$tdir")
12299         done
12300
12301         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12302 }
12303 run_test 129 "test directory size limit ========================"
12304
12305 OLDIFS="$IFS"
12306 cleanup_130() {
12307         trap 0
12308         IFS="$OLDIFS"
12309 }
12310
12311 test_130a() {
12312         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12313         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12314
12315         trap cleanup_130 EXIT RETURN
12316
12317         local fm_file=$DIR/$tfile
12318         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12319         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12320                 error "dd failed for $fm_file"
12321
12322         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12323         filefrag -ves $fm_file
12324         RC=$?
12325         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12326                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12327         [ $RC != 0 ] && error "filefrag $fm_file failed"
12328
12329         filefrag_op=$(filefrag -ve -k $fm_file |
12330                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12331         lun=$($LFS getstripe -i $fm_file)
12332
12333         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12334         IFS=$'\n'
12335         tot_len=0
12336         for line in $filefrag_op
12337         do
12338                 frag_lun=`echo $line | cut -d: -f5`
12339                 ext_len=`echo $line | cut -d: -f4`
12340                 if (( $frag_lun != $lun )); then
12341                         cleanup_130
12342                         error "FIEMAP on 1-stripe file($fm_file) failed"
12343                         return
12344                 fi
12345                 (( tot_len += ext_len ))
12346         done
12347
12348         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12349                 cleanup_130
12350                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12351                 return
12352         fi
12353
12354         cleanup_130
12355
12356         echo "FIEMAP on single striped file succeeded"
12357 }
12358 run_test 130a "FIEMAP (1-stripe file)"
12359
12360 test_130b() {
12361         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12362
12363         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12364         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12365
12366         trap cleanup_130 EXIT RETURN
12367
12368         local fm_file=$DIR/$tfile
12369         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12370                         error "setstripe on $fm_file"
12371         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12372                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12373
12374         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12375                 error "dd failed on $fm_file"
12376
12377         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12378         filefrag_op=$(filefrag -ve -k $fm_file |
12379                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12380
12381         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12382                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12383
12384         IFS=$'\n'
12385         tot_len=0
12386         num_luns=1
12387         for line in $filefrag_op
12388         do
12389                 frag_lun=$(echo $line | cut -d: -f5 |
12390                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12391                 ext_len=$(echo $line | cut -d: -f4)
12392                 if (( $frag_lun != $last_lun )); then
12393                         if (( tot_len != 1024 )); then
12394                                 cleanup_130
12395                                 error "FIEMAP on $fm_file failed; returned " \
12396                                 "len $tot_len for OST $last_lun instead of 1024"
12397                                 return
12398                         else
12399                                 (( num_luns += 1 ))
12400                                 tot_len=0
12401                         fi
12402                 fi
12403                 (( tot_len += ext_len ))
12404                 last_lun=$frag_lun
12405         done
12406         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12407                 cleanup_130
12408                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12409                         "luns or wrong len for OST $last_lun"
12410                 return
12411         fi
12412
12413         cleanup_130
12414
12415         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12416 }
12417 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12418
12419 test_130c() {
12420         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12421
12422         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12423         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12424
12425         trap cleanup_130 EXIT RETURN
12426
12427         local fm_file=$DIR/$tfile
12428         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12429         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12430                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12431
12432         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12433                         error "dd failed on $fm_file"
12434
12435         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12436         filefrag_op=$(filefrag -ve -k $fm_file |
12437                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12438
12439         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12440                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12441
12442         IFS=$'\n'
12443         tot_len=0
12444         num_luns=1
12445         for line in $filefrag_op
12446         do
12447                 frag_lun=$(echo $line | cut -d: -f5 |
12448                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12449                 ext_len=$(echo $line | cut -d: -f4)
12450                 if (( $frag_lun != $last_lun )); then
12451                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12452                         if (( logical != 512 )); then
12453                                 cleanup_130
12454                                 error "FIEMAP on $fm_file failed; returned " \
12455                                 "logical start for lun $logical instead of 512"
12456                                 return
12457                         fi
12458                         if (( tot_len != 512 )); then
12459                                 cleanup_130
12460                                 error "FIEMAP on $fm_file failed; returned " \
12461                                 "len $tot_len for OST $last_lun instead of 1024"
12462                                 return
12463                         else
12464                                 (( num_luns += 1 ))
12465                                 tot_len=0
12466                         fi
12467                 fi
12468                 (( tot_len += ext_len ))
12469                 last_lun=$frag_lun
12470         done
12471         if (( num_luns != 2 || tot_len != 512 )); then
12472                 cleanup_130
12473                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12474                         "luns or wrong len for OST $last_lun"
12475                 return
12476         fi
12477
12478         cleanup_130
12479
12480         echo "FIEMAP on 2-stripe file with hole succeeded"
12481 }
12482 run_test 130c "FIEMAP (2-stripe file with hole)"
12483
12484 test_130d() {
12485         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12486
12487         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12488         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12489
12490         trap cleanup_130 EXIT RETURN
12491
12492         local fm_file=$DIR/$tfile
12493         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12494                         error "setstripe on $fm_file"
12495         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12496                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12497
12498         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12499         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12500                 error "dd failed on $fm_file"
12501
12502         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12503         filefrag_op=$(filefrag -ve -k $fm_file |
12504                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12505
12506         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12507                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12508
12509         IFS=$'\n'
12510         tot_len=0
12511         num_luns=1
12512         for line in $filefrag_op
12513         do
12514                 frag_lun=$(echo $line | cut -d: -f5 |
12515                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12516                 ext_len=$(echo $line | cut -d: -f4)
12517                 if (( $frag_lun != $last_lun )); then
12518                         if (( tot_len != 1024 )); then
12519                                 cleanup_130
12520                                 error "FIEMAP on $fm_file failed; returned " \
12521                                 "len $tot_len for OST $last_lun instead of 1024"
12522                                 return
12523                         else
12524                                 (( num_luns += 1 ))
12525                                 tot_len=0
12526                         fi
12527                 fi
12528                 (( tot_len += ext_len ))
12529                 last_lun=$frag_lun
12530         done
12531         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12532                 cleanup_130
12533                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12534                         "luns or wrong len for OST $last_lun"
12535                 return
12536         fi
12537
12538         cleanup_130
12539
12540         echo "FIEMAP on N-stripe file succeeded"
12541 }
12542 run_test 130d "FIEMAP (N-stripe file)"
12543
12544 test_130e() {
12545         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12546
12547         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12548         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12549
12550         trap cleanup_130 EXIT RETURN
12551
12552         local fm_file=$DIR/$tfile
12553         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12554         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12555                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12556
12557         NUM_BLKS=512
12558         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12559         for ((i = 0; i < $NUM_BLKS; i++))
12560         do
12561                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12562         done
12563
12564         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12565         filefrag_op=$(filefrag -ve -k $fm_file |
12566                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12567
12568         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12569                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12570
12571         IFS=$'\n'
12572         tot_len=0
12573         num_luns=1
12574         for line in $filefrag_op
12575         do
12576                 frag_lun=$(echo $line | cut -d: -f5 |
12577                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12578                 ext_len=$(echo $line | cut -d: -f4)
12579                 if (( $frag_lun != $last_lun )); then
12580                         if (( tot_len != $EXPECTED_LEN )); then
12581                                 cleanup_130
12582                                 error "FIEMAP on $fm_file failed; returned " \
12583                                 "len $tot_len for OST $last_lun instead " \
12584                                 "of $EXPECTED_LEN"
12585                                 return
12586                         else
12587                                 (( num_luns += 1 ))
12588                                 tot_len=0
12589                         fi
12590                 fi
12591                 (( tot_len += ext_len ))
12592                 last_lun=$frag_lun
12593         done
12594         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12595                 cleanup_130
12596                 error "FIEMAP on $fm_file failed; returned wrong number " \
12597                         "of luns or wrong len for OST $last_lun"
12598                 return
12599         fi
12600
12601         cleanup_130
12602
12603         echo "FIEMAP with continuation calls succeeded"
12604 }
12605 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12606
12607 test_130f() {
12608         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12609         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12610
12611         local fm_file=$DIR/$tfile
12612         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12613                 error "multiop create with lov_delay_create on $fm_file"
12614
12615         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12616         filefrag_extents=$(filefrag -vek $fm_file |
12617                            awk '/extents? found/ { print $2 }')
12618         if [[ "$filefrag_extents" != "0" ]]; then
12619                 error "FIEMAP on $fm_file failed; " \
12620                       "returned $filefrag_extents expected 0"
12621         fi
12622
12623         rm -f $fm_file
12624 }
12625 run_test 130f "FIEMAP (unstriped file)"
12626
12627 # Test for writev/readv
12628 test_131a() {
12629         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12630                 error "writev test failed"
12631         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12632                 error "readv failed"
12633         rm -f $DIR/$tfile
12634 }
12635 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12636
12637 test_131b() {
12638         local fsize=$((524288 + 1048576 + 1572864))
12639         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12640                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12641                         error "append writev test failed"
12642
12643         ((fsize += 1572864 + 1048576))
12644         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12645                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12646                         error "append writev test failed"
12647         rm -f $DIR/$tfile
12648 }
12649 run_test 131b "test append writev"
12650
12651 test_131c() {
12652         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12653         error "NOT PASS"
12654 }
12655 run_test 131c "test read/write on file w/o objects"
12656
12657 test_131d() {
12658         rwv -f $DIR/$tfile -w -n 1 1572864
12659         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12660         if [ "$NOB" != 1572864 ]; then
12661                 error "Short read filed: read $NOB bytes instead of 1572864"
12662         fi
12663         rm -f $DIR/$tfile
12664 }
12665 run_test 131d "test short read"
12666
12667 test_131e() {
12668         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12669         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12670         error "read hitting hole failed"
12671         rm -f $DIR/$tfile
12672 }
12673 run_test 131e "test read hitting hole"
12674
12675 check_stats() {
12676         local facet=$1
12677         local op=$2
12678         local want=${3:-0}
12679         local res
12680
12681         case $facet in
12682         mds*) res=$(do_facet $facet \
12683                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12684                  ;;
12685         ost*) res=$(do_facet $facet \
12686                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12687                  ;;
12688         *) error "Wrong facet '$facet'" ;;
12689         esac
12690         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12691         # if the argument $3 is zero, it means any stat increment is ok.
12692         if [[ $want -gt 0 ]]; then
12693                 local count=$(echo $res | awk '{ print $2 }')
12694                 [[ $count -ne $want ]] &&
12695                         error "The $op counter on $facet is $count, not $want"
12696         fi
12697 }
12698
12699 test_133a() {
12700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12701         remote_ost_nodsh && skip "remote OST with nodsh"
12702         remote_mds_nodsh && skip "remote MDS with nodsh"
12703         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12704                 skip_env "MDS doesn't support rename stats"
12705
12706         local testdir=$DIR/${tdir}/stats_testdir
12707
12708         mkdir -p $DIR/${tdir}
12709
12710         # clear stats.
12711         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12712         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12713
12714         # verify mdt stats first.
12715         mkdir ${testdir} || error "mkdir failed"
12716         check_stats $SINGLEMDS "mkdir" 1
12717         touch ${testdir}/${tfile} || error "touch failed"
12718         check_stats $SINGLEMDS "open" 1
12719         check_stats $SINGLEMDS "close" 1
12720         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12721                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12722                 check_stats $SINGLEMDS "mknod" 2
12723         }
12724         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12725         check_stats $SINGLEMDS "unlink" 1
12726         rm -f ${testdir}/${tfile} || error "file remove failed"
12727         check_stats $SINGLEMDS "unlink" 2
12728
12729         # remove working dir and check mdt stats again.
12730         rmdir ${testdir} || error "rmdir failed"
12731         check_stats $SINGLEMDS "rmdir" 1
12732
12733         local testdir1=$DIR/${tdir}/stats_testdir1
12734         mkdir -p ${testdir}
12735         mkdir -p ${testdir1}
12736         touch ${testdir1}/test1
12737         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12738         check_stats $SINGLEMDS "crossdir_rename" 1
12739
12740         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12741         check_stats $SINGLEMDS "samedir_rename" 1
12742
12743         rm -rf $DIR/${tdir}
12744 }
12745 run_test 133a "Verifying MDT stats ========================================"
12746
12747 test_133b() {
12748         local res
12749
12750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12751         remote_ost_nodsh && skip "remote OST with nodsh"
12752         remote_mds_nodsh && skip "remote MDS with nodsh"
12753
12754         local testdir=$DIR/${tdir}/stats_testdir
12755
12756         mkdir -p ${testdir} || error "mkdir failed"
12757         touch ${testdir}/${tfile} || error "touch failed"
12758         cancel_lru_locks mdc
12759
12760         # clear stats.
12761         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12762         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12763
12764         # extra mdt stats verification.
12765         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12766         check_stats $SINGLEMDS "setattr" 1
12767         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12768         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12769         then            # LU-1740
12770                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12771                 check_stats $SINGLEMDS "getattr" 1
12772         fi
12773         rm -rf $DIR/${tdir}
12774
12775         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12776         # so the check below is not reliable
12777         [ $MDSCOUNT -eq 1 ] || return 0
12778
12779         # Sleep to avoid a cached response.
12780         #define OBD_STATFS_CACHE_SECONDS 1
12781         sleep 2
12782         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12783         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12784         $LFS df || error "lfs failed"
12785         check_stats $SINGLEMDS "statfs" 1
12786
12787         # check aggregated statfs (LU-10018)
12788         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12789                 return 0
12790         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12791                 return 0
12792         sleep 2
12793         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12794         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12795         df $DIR
12796         check_stats $SINGLEMDS "statfs" 1
12797
12798         # We want to check that the client didn't send OST_STATFS to
12799         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12800         # extra care is needed here.
12801         if remote_mds; then
12802                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12803                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12804
12805                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12806                 [ "$res" ] && error "OST got STATFS"
12807         fi
12808
12809         return 0
12810 }
12811 run_test 133b "Verifying extra MDT stats =================================="
12812
12813 test_133c() {
12814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12815         remote_ost_nodsh && skip "remote OST with nodsh"
12816         remote_mds_nodsh && skip "remote MDS with nodsh"
12817
12818         local testdir=$DIR/$tdir/stats_testdir
12819
12820         test_mkdir -p $testdir
12821
12822         # verify obdfilter stats.
12823         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12824         sync
12825         cancel_lru_locks osc
12826         wait_delete_completed
12827
12828         # clear stats.
12829         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12830         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12831
12832         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12833                 error "dd failed"
12834         sync
12835         cancel_lru_locks osc
12836         check_stats ost1 "write" 1
12837
12838         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12839         check_stats ost1 "read" 1
12840
12841         > $testdir/$tfile || error "truncate failed"
12842         check_stats ost1 "punch" 1
12843
12844         rm -f $testdir/$tfile || error "file remove failed"
12845         wait_delete_completed
12846         check_stats ost1 "destroy" 1
12847
12848         rm -rf $DIR/$tdir
12849 }
12850 run_test 133c "Verifying OST stats ========================================"
12851
12852 order_2() {
12853         local value=$1
12854         local orig=$value
12855         local order=1
12856
12857         while [ $value -ge 2 ]; do
12858                 order=$((order*2))
12859                 value=$((value/2))
12860         done
12861
12862         if [ $orig -gt $order ]; then
12863                 order=$((order*2))
12864         fi
12865         echo $order
12866 }
12867
12868 size_in_KMGT() {
12869     local value=$1
12870     local size=('K' 'M' 'G' 'T');
12871     local i=0
12872     local size_string=$value
12873
12874     while [ $value -ge 1024 ]; do
12875         if [ $i -gt 3 ]; then
12876             #T is the biggest unit we get here, if that is bigger,
12877             #just return XXXT
12878             size_string=${value}T
12879             break
12880         fi
12881         value=$((value >> 10))
12882         if [ $value -lt 1024 ]; then
12883             size_string=${value}${size[$i]}
12884             break
12885         fi
12886         i=$((i + 1))
12887     done
12888
12889     echo $size_string
12890 }
12891
12892 get_rename_size() {
12893         local size=$1
12894         local context=${2:-.}
12895         local sample=$(do_facet $SINGLEMDS $LCTL \
12896                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12897                 grep -A1 $context |
12898                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12899         echo $sample
12900 }
12901
12902 test_133d() {
12903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12904         remote_ost_nodsh && skip "remote OST with nodsh"
12905         remote_mds_nodsh && skip "remote MDS with nodsh"
12906         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12907                 skip_env "MDS doesn't support rename stats"
12908
12909         local testdir1=$DIR/${tdir}/stats_testdir1
12910         local testdir2=$DIR/${tdir}/stats_testdir2
12911         mkdir -p $DIR/${tdir}
12912
12913         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12914
12915         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12916         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12917
12918         createmany -o $testdir1/test 512 || error "createmany failed"
12919
12920         # check samedir rename size
12921         mv ${testdir1}/test0 ${testdir1}/test_0
12922
12923         local testdir1_size=$(ls -l $DIR/${tdir} |
12924                 awk '/stats_testdir1/ {print $5}')
12925         local testdir2_size=$(ls -l $DIR/${tdir} |
12926                 awk '/stats_testdir2/ {print $5}')
12927
12928         testdir1_size=$(order_2 $testdir1_size)
12929         testdir2_size=$(order_2 $testdir2_size)
12930
12931         testdir1_size=$(size_in_KMGT $testdir1_size)
12932         testdir2_size=$(size_in_KMGT $testdir2_size)
12933
12934         echo "source rename dir size: ${testdir1_size}"
12935         echo "target rename dir size: ${testdir2_size}"
12936
12937         local cmd="do_facet $SINGLEMDS $LCTL "
12938         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12939
12940         eval $cmd || error "$cmd failed"
12941         local samedir=$($cmd | grep 'same_dir')
12942         local same_sample=$(get_rename_size $testdir1_size)
12943         [ -z "$samedir" ] && error "samedir_rename_size count error"
12944         [[ $same_sample -eq 1 ]] ||
12945                 error "samedir_rename_size error $same_sample"
12946         echo "Check same dir rename stats success"
12947
12948         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12949
12950         # check crossdir rename size
12951         mv ${testdir1}/test_0 ${testdir2}/test_0
12952
12953         testdir1_size=$(ls -l $DIR/${tdir} |
12954                 awk '/stats_testdir1/ {print $5}')
12955         testdir2_size=$(ls -l $DIR/${tdir} |
12956                 awk '/stats_testdir2/ {print $5}')
12957
12958         testdir1_size=$(order_2 $testdir1_size)
12959         testdir2_size=$(order_2 $testdir2_size)
12960
12961         testdir1_size=$(size_in_KMGT $testdir1_size)
12962         testdir2_size=$(size_in_KMGT $testdir2_size)
12963
12964         echo "source rename dir size: ${testdir1_size}"
12965         echo "target rename dir size: ${testdir2_size}"
12966
12967         eval $cmd || error "$cmd failed"
12968         local crossdir=$($cmd | grep 'crossdir')
12969         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12970         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12971         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12972         [[ $src_sample -eq 1 ]] ||
12973                 error "crossdir_rename_size error $src_sample"
12974         [[ $tgt_sample -eq 1 ]] ||
12975                 error "crossdir_rename_size error $tgt_sample"
12976         echo "Check cross dir rename stats success"
12977         rm -rf $DIR/${tdir}
12978 }
12979 run_test 133d "Verifying rename_stats ========================================"
12980
12981 test_133e() {
12982         remote_mds_nodsh && skip "remote MDS with nodsh"
12983         remote_ost_nodsh && skip "remote OST with nodsh"
12984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12985
12986         local testdir=$DIR/${tdir}/stats_testdir
12987         local ctr f0 f1 bs=32768 count=42 sum
12988
12989         mkdir -p ${testdir} || error "mkdir failed"
12990
12991         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12992
12993         for ctr in {write,read}_bytes; do
12994                 sync
12995                 cancel_lru_locks osc
12996
12997                 do_facet ost1 $LCTL set_param -n \
12998                         "obdfilter.*.exports.clear=clear"
12999
13000                 if [ $ctr = write_bytes ]; then
13001                         f0=/dev/zero
13002                         f1=${testdir}/${tfile}
13003                 else
13004                         f0=${testdir}/${tfile}
13005                         f1=/dev/null
13006                 fi
13007
13008                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13009                         error "dd failed"
13010                 sync
13011                 cancel_lru_locks osc
13012
13013                 sum=$(do_facet ost1 $LCTL get_param \
13014                         "obdfilter.*.exports.*.stats" |
13015                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13016                                 $1 == ctr { sum += $7 }
13017                                 END { printf("%0.0f", sum) }')
13018
13019                 if ((sum != bs * count)); then
13020                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13021                 fi
13022         done
13023
13024         rm -rf $DIR/${tdir}
13025 }
13026 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13027
13028 test_133f() {
13029         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13030                 skip "too old lustre for get_param -R ($facet_ver)"
13031
13032         # verifying readability.
13033         $LCTL get_param -R '*' &> /dev/null
13034
13035         # Verifing writability with badarea_io.
13036         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13037                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13038                 error "client badarea_io failed"
13039
13040         # remount the FS in case writes/reads /proc break the FS
13041         cleanup || error "failed to unmount"
13042         setup || error "failed to setup"
13043 }
13044 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13045
13046 test_133g() {
13047         remote_mds_nodsh && skip "remote MDS with nodsh"
13048         remote_ost_nodsh && skip "remote OST with nodsh"
13049
13050         local facet
13051         for facet in mds1 ost1; do
13052                 local facet_ver=$(lustre_version_code $facet)
13053                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13054                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13055                 else
13056                         log "$facet: too old lustre for get_param -R"
13057                 fi
13058                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13059                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13060                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13061                                 xargs badarea_io" ||
13062                                         error "$facet badarea_io failed"
13063                 else
13064                         skip_noexit "$facet: too old lustre for get_param -R"
13065                 fi
13066         done
13067
13068         # remount the FS in case writes/reads /proc break the FS
13069         cleanup || error "failed to unmount"
13070         setup || error "failed to setup"
13071 }
13072 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13073
13074 test_133h() {
13075         remote_mds_nodsh && skip "remote MDS with nodsh"
13076         remote_ost_nodsh && skip "remote OST with nodsh"
13077         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13078                 skip "Need MDS version at least 2.9.54"
13079
13080         local facet
13081         for facet in client mds1 ost1; do
13082                 # Get the list of files that are missing the terminating newline
13083                 local plist=$(do_facet $facet
13084                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13085                 local ent
13086                 for ent in $plist; do
13087                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13088                                 awk -v FS='\v' -v RS='\v\v' \
13089                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13090                                         print FILENAME}'" 2>/dev/null)
13091                         [ -z $missing ] || {
13092                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13093                                 error "file does not end with newline: $facet-$ent"
13094                         }
13095                 done
13096         done
13097 }
13098 run_test 133h "Proc files should end with newlines"
13099
13100 test_134a() {
13101         remote_mds_nodsh && skip "remote MDS with nodsh"
13102         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13103                 skip "Need MDS version at least 2.7.54"
13104
13105         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13106         cancel_lru_locks mdc
13107
13108         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13109         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13110         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13111
13112         local nr=1000
13113         createmany -o $DIR/$tdir/f $nr ||
13114                 error "failed to create $nr files in $DIR/$tdir"
13115         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13116
13117         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13118         do_facet mds1 $LCTL set_param fail_loc=0x327
13119         do_facet mds1 $LCTL set_param fail_val=500
13120         touch $DIR/$tdir/m
13121
13122         echo "sleep 10 seconds ..."
13123         sleep 10
13124         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13125
13126         do_facet mds1 $LCTL set_param fail_loc=0
13127         do_facet mds1 $LCTL set_param fail_val=0
13128         [ $lck_cnt -lt $unused ] ||
13129                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13130
13131         rm $DIR/$tdir/m
13132         unlinkmany $DIR/$tdir/f $nr
13133 }
13134 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13135
13136 test_134b() {
13137         remote_mds_nodsh && skip "remote MDS with nodsh"
13138         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13139                 skip "Need MDS version at least 2.7.54"
13140
13141         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13142         cancel_lru_locks mdc
13143
13144         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13145                         ldlm.lock_reclaim_threshold_mb)
13146         # disable reclaim temporarily
13147         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13148
13149         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13150         do_facet mds1 $LCTL set_param fail_loc=0x328
13151         do_facet mds1 $LCTL set_param fail_val=500
13152
13153         $LCTL set_param debug=+trace
13154
13155         local nr=600
13156         createmany -o $DIR/$tdir/f $nr &
13157         local create_pid=$!
13158
13159         echo "Sleep $TIMEOUT seconds ..."
13160         sleep $TIMEOUT
13161         if ! ps -p $create_pid  > /dev/null 2>&1; then
13162                 do_facet mds1 $LCTL set_param fail_loc=0
13163                 do_facet mds1 $LCTL set_param fail_val=0
13164                 do_facet mds1 $LCTL set_param \
13165                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13166                 error "createmany finished incorrectly!"
13167         fi
13168         do_facet mds1 $LCTL set_param fail_loc=0
13169         do_facet mds1 $LCTL set_param fail_val=0
13170         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13171         wait $create_pid || return 1
13172
13173         unlinkmany $DIR/$tdir/f $nr
13174 }
13175 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13176
13177 test_135() {
13178         remote_mds_nodsh && skip "remote MDS with nodsh"
13179         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13180                 skip "Need MDS version at least 2.13.50"
13181         local fname
13182
13183         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13184
13185 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13186         #set only one record at plain llog
13187         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13188
13189         #fill already existed plain llog each 64767
13190         #wrapping whole catalog
13191         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13192
13193         createmany -o $DIR/$tdir/$tfile_ 64700
13194         for (( i = 0; i < 64700; i = i + 2 ))
13195         do
13196                 rm $DIR/$tdir/$tfile_$i &
13197                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13198                 local pid=$!
13199                 wait $pid
13200         done
13201
13202         #waiting osp synchronization
13203         wait_delete_completed
13204 }
13205 run_test 135 "Race catalog processing"
13206
13207 test_136() {
13208         remote_mds_nodsh && skip "remote MDS with nodsh"
13209         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13210                 skip "Need MDS version at least 2.13.50"
13211         local fname
13212
13213         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13214         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13215         #set only one record at plain llog
13216 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13217         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13218
13219         #fill already existed 2 plain llogs each 64767
13220         #wrapping whole catalog
13221         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13222         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13223         wait_delete_completed
13224
13225         createmany -o $DIR/$tdir/$tfile_ 10
13226         sleep 25
13227
13228         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13229         for (( i = 0; i < 10; i = i + 3 ))
13230         do
13231                 rm $DIR/$tdir/$tfile_$i &
13232                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13233                 local pid=$!
13234                 wait $pid
13235                 sleep 7
13236                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13237         done
13238
13239         #waiting osp synchronization
13240         wait_delete_completed
13241 }
13242 run_test 136 "Race catalog processing 2"
13243
13244 test_140() { #bug-17379
13245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13246
13247         test_mkdir $DIR/$tdir
13248         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13249         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13250
13251         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13252         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13253         local i=0
13254         while i=$((i + 1)); do
13255                 test_mkdir $i
13256                 cd $i || error "Changing to $i"
13257                 ln -s ../stat stat || error "Creating stat symlink"
13258                 # Read the symlink until ELOOP present,
13259                 # not LBUGing the system is considered success,
13260                 # we didn't overrun the stack.
13261                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13262                 if [ $ret -ne 0 ]; then
13263                         if [ $ret -eq 40 ]; then
13264                                 break  # -ELOOP
13265                         else
13266                                 error "Open stat symlink"
13267                                         return
13268                         fi
13269                 fi
13270         done
13271         i=$((i - 1))
13272         echo "The symlink depth = $i"
13273         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13274                 error "Invalid symlink depth"
13275
13276         # Test recursive symlink
13277         ln -s symlink_self symlink_self
13278         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13279         echo "open symlink_self returns $ret"
13280         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13281 }
13282 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13283
13284 test_150a() {
13285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13286
13287         local TF="$TMP/$tfile"
13288
13289         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13290         cp $TF $DIR/$tfile
13291         cancel_lru_locks $OSC
13292         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13293         remount_client $MOUNT
13294         df -P $MOUNT
13295         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13296
13297         $TRUNCATE $TF 6000
13298         $TRUNCATE $DIR/$tfile 6000
13299         cancel_lru_locks $OSC
13300         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13301
13302         echo "12345" >>$TF
13303         echo "12345" >>$DIR/$tfile
13304         cancel_lru_locks $OSC
13305         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13306
13307         echo "12345" >>$TF
13308         echo "12345" >>$DIR/$tfile
13309         cancel_lru_locks $OSC
13310         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13311
13312         rm -f $TF
13313         true
13314 }
13315 run_test 150a "truncate/append tests"
13316
13317 test_150b() {
13318         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13319         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13320                 skip "Need OST version at least 2.13.53"
13321         touch $DIR/$tfile
13322         check_fallocate $DIR/$tfile || error "fallocate failed"
13323 }
13324 run_test 150b "Verify fallocate (prealloc) functionality"
13325
13326 test_150c() {
13327         local bytes
13328         local want
13329
13330         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13331         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13332                 skip "Need OST version at least 2.13.53"
13333
13334         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13335         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13336         sync; sync_all_data
13337         cancel_lru_locks $OSC
13338         sleep 5
13339         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13340         want=$((OSTCOUNT * 1048576))
13341
13342         # Must allocate all requested space, not more than 5% extra
13343         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13344                 error "bytes $bytes is not $want"
13345 }
13346 run_test 150c "Verify fallocate Size and Blocks"
13347
13348 test_150d() {
13349         local bytes
13350         local want
13351
13352         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13353         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13354                 skip "Need OST version at least 2.13.53"
13355
13356         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13357         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13358         sync; sync_all_data
13359         cancel_lru_locks $OSC
13360         sleep 5
13361         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13362         want=$((OSTCOUNT * 1048576))
13363
13364         # Must allocate all requested space, not more than 5% extra
13365         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13366                 error "bytes $bytes is not $want"
13367 }
13368 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13369
13370 #LU-2902 roc_hit was not able to read all values from lproc
13371 function roc_hit_init() {
13372         local list=$(comma_list $(osts_nodes))
13373         local dir=$DIR/$tdir-check
13374         local file=$dir/$tfile
13375         local BEFORE
13376         local AFTER
13377         local idx
13378
13379         test_mkdir $dir
13380         #use setstripe to do a write to every ost
13381         for i in $(seq 0 $((OSTCOUNT-1))); do
13382                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13383                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13384                 idx=$(printf %04x $i)
13385                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13386                         awk '$1 == "cache_access" {sum += $7}
13387                                 END { printf("%0.0f", sum) }')
13388
13389                 cancel_lru_locks osc
13390                 cat $file >/dev/null
13391
13392                 AFTER=$(get_osd_param $list *OST*$idx stats |
13393                         awk '$1 == "cache_access" {sum += $7}
13394                                 END { printf("%0.0f", sum) }')
13395
13396                 echo BEFORE:$BEFORE AFTER:$AFTER
13397                 if ! let "AFTER - BEFORE == 4"; then
13398                         rm -rf $dir
13399                         error "roc_hit is not safe to use"
13400                 fi
13401                 rm $file
13402         done
13403
13404         rm -rf $dir
13405 }
13406
13407 function roc_hit() {
13408         local list=$(comma_list $(osts_nodes))
13409         echo $(get_osd_param $list '' stats |
13410                 awk '$1 == "cache_hit" {sum += $7}
13411                         END { printf("%0.0f", sum) }')
13412 }
13413
13414 function set_cache() {
13415         local on=1
13416
13417         if [ "$2" == "off" ]; then
13418                 on=0;
13419         fi
13420         local list=$(comma_list $(osts_nodes))
13421         set_osd_param $list '' $1_cache_enable $on
13422
13423         cancel_lru_locks osc
13424 }
13425
13426 test_151() {
13427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13428         remote_ost_nodsh && skip "remote OST with nodsh"
13429
13430         local CPAGES=3
13431         local list=$(comma_list $(osts_nodes))
13432
13433         # check whether obdfilter is cache capable at all
13434         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13435                 skip "not cache-capable obdfilter"
13436         fi
13437
13438         # check cache is enabled on all obdfilters
13439         if get_osd_param $list '' read_cache_enable | grep 0; then
13440                 skip "oss cache is disabled"
13441         fi
13442
13443         set_osd_param $list '' writethrough_cache_enable 1
13444
13445         # check write cache is enabled on all obdfilters
13446         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13447                 skip "oss write cache is NOT enabled"
13448         fi
13449
13450         roc_hit_init
13451
13452         #define OBD_FAIL_OBD_NO_LRU  0x609
13453         do_nodes $list $LCTL set_param fail_loc=0x609
13454
13455         # pages should be in the case right after write
13456         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13457                 error "dd failed"
13458
13459         local BEFORE=$(roc_hit)
13460         cancel_lru_locks osc
13461         cat $DIR/$tfile >/dev/null
13462         local AFTER=$(roc_hit)
13463
13464         do_nodes $list $LCTL set_param fail_loc=0
13465
13466         if ! let "AFTER - BEFORE == CPAGES"; then
13467                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13468         fi
13469
13470         cancel_lru_locks osc
13471         # invalidates OST cache
13472         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13473         set_osd_param $list '' read_cache_enable 0
13474         cat $DIR/$tfile >/dev/null
13475
13476         # now data shouldn't be found in the cache
13477         BEFORE=$(roc_hit)
13478         cancel_lru_locks osc
13479         cat $DIR/$tfile >/dev/null
13480         AFTER=$(roc_hit)
13481         if let "AFTER - BEFORE != 0"; then
13482                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13483         fi
13484
13485         set_osd_param $list '' read_cache_enable 1
13486         rm -f $DIR/$tfile
13487 }
13488 run_test 151 "test cache on oss and controls ==============================="
13489
13490 test_152() {
13491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13492
13493         local TF="$TMP/$tfile"
13494
13495         # simulate ENOMEM during write
13496 #define OBD_FAIL_OST_NOMEM      0x226
13497         lctl set_param fail_loc=0x80000226
13498         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13499         cp $TF $DIR/$tfile
13500         sync || error "sync failed"
13501         lctl set_param fail_loc=0
13502
13503         # discard client's cache
13504         cancel_lru_locks osc
13505
13506         # simulate ENOMEM during read
13507         lctl set_param fail_loc=0x80000226
13508         cmp $TF $DIR/$tfile || error "cmp failed"
13509         lctl set_param fail_loc=0
13510
13511         rm -f $TF
13512 }
13513 run_test 152 "test read/write with enomem ============================"
13514
13515 test_153() {
13516         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13517 }
13518 run_test 153 "test if fdatasync does not crash ======================="
13519
13520 dot_lustre_fid_permission_check() {
13521         local fid=$1
13522         local ffid=$MOUNT/.lustre/fid/$fid
13523         local test_dir=$2
13524
13525         echo "stat fid $fid"
13526         stat $ffid > /dev/null || error "stat $ffid failed."
13527         echo "touch fid $fid"
13528         touch $ffid || error "touch $ffid failed."
13529         echo "write to fid $fid"
13530         cat /etc/hosts > $ffid || error "write $ffid failed."
13531         echo "read fid $fid"
13532         diff /etc/hosts $ffid || error "read $ffid failed."
13533         echo "append write to fid $fid"
13534         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13535         echo "rename fid $fid"
13536         mv $ffid $test_dir/$tfile.1 &&
13537                 error "rename $ffid to $tfile.1 should fail."
13538         touch $test_dir/$tfile.1
13539         mv $test_dir/$tfile.1 $ffid &&
13540                 error "rename $tfile.1 to $ffid should fail."
13541         rm -f $test_dir/$tfile.1
13542         echo "truncate fid $fid"
13543         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13544         echo "link fid $fid"
13545         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13546         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13547                 echo "setfacl fid $fid"
13548                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13549                 echo "getfacl fid $fid"
13550                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13551         fi
13552         echo "unlink fid $fid"
13553         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13554         echo "mknod fid $fid"
13555         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13556
13557         fid=[0xf00000400:0x1:0x0]
13558         ffid=$MOUNT/.lustre/fid/$fid
13559
13560         echo "stat non-exist fid $fid"
13561         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13562         echo "write to non-exist fid $fid"
13563         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13564         echo "link new fid $fid"
13565         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13566
13567         mkdir -p $test_dir/$tdir
13568         touch $test_dir/$tdir/$tfile
13569         fid=$($LFS path2fid $test_dir/$tdir)
13570         rc=$?
13571         [ $rc -ne 0 ] &&
13572                 error "error: could not get fid for $test_dir/$dir/$tfile."
13573
13574         ffid=$MOUNT/.lustre/fid/$fid
13575
13576         echo "ls $fid"
13577         ls $ffid > /dev/null || error "ls $ffid failed."
13578         echo "touch $fid/$tfile.1"
13579         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13580
13581         echo "touch $MOUNT/.lustre/fid/$tfile"
13582         touch $MOUNT/.lustre/fid/$tfile && \
13583                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13584
13585         echo "setxattr to $MOUNT/.lustre/fid"
13586         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13587
13588         echo "listxattr for $MOUNT/.lustre/fid"
13589         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13590
13591         echo "delxattr from $MOUNT/.lustre/fid"
13592         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13593
13594         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13595         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13596                 error "touch invalid fid should fail."
13597
13598         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13599         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13600                 error "touch non-normal fid should fail."
13601
13602         echo "rename $tdir to $MOUNT/.lustre/fid"
13603         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13604                 error "rename to $MOUNT/.lustre/fid should fail."
13605
13606         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13607         then            # LU-3547
13608                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13609                 local new_obf_mode=777
13610
13611                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13612                 chmod $new_obf_mode $DIR/.lustre/fid ||
13613                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13614
13615                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13616                 [ $obf_mode -eq $new_obf_mode ] ||
13617                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13618
13619                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13620                 chmod $old_obf_mode $DIR/.lustre/fid ||
13621                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13622         fi
13623
13624         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13625         fid=$($LFS path2fid $test_dir/$tfile-2)
13626
13627         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13628         then # LU-5424
13629                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13630                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13631                         error "create lov data thru .lustre failed"
13632         fi
13633         echo "cp /etc/passwd $test_dir/$tfile-2"
13634         cp /etc/passwd $test_dir/$tfile-2 ||
13635                 error "copy to $test_dir/$tfile-2 failed."
13636         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13637         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13638                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13639
13640         rm -rf $test_dir/tfile.lnk
13641         rm -rf $test_dir/$tfile-2
13642 }
13643
13644 test_154A() {
13645         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13646                 skip "Need MDS version at least 2.4.1"
13647
13648         local tf=$DIR/$tfile
13649         touch $tf
13650
13651         local fid=$($LFS path2fid $tf)
13652         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13653
13654         # check that we get the same pathname back
13655         local rootpath
13656         local found
13657         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13658                 echo "$rootpath $fid"
13659                 found=$($LFS fid2path $rootpath "$fid")
13660                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13661                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13662         done
13663
13664         # check wrong root path format
13665         rootpath=$MOUNT"_wrong"
13666         found=$($LFS fid2path $rootpath "$fid")
13667         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13668 }
13669 run_test 154A "lfs path2fid and fid2path basic checks"
13670
13671 test_154B() {
13672         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13673                 skip "Need MDS version at least 2.4.1"
13674
13675         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13676         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13677         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13678         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13679
13680         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13681         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13682
13683         # check that we get the same pathname
13684         echo "PFID: $PFID, name: $name"
13685         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13686         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13687         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13688                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13689
13690         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13691 }
13692 run_test 154B "verify the ll_decode_linkea tool"
13693
13694 test_154a() {
13695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13696         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13697         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13698                 skip "Need MDS version at least 2.2.51"
13699         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13700
13701         cp /etc/hosts $DIR/$tfile
13702
13703         fid=$($LFS path2fid $DIR/$tfile)
13704         rc=$?
13705         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13706
13707         dot_lustre_fid_permission_check "$fid" $DIR ||
13708                 error "dot lustre permission check $fid failed"
13709
13710         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13711
13712         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13713
13714         touch $MOUNT/.lustre/file &&
13715                 error "creation is not allowed under .lustre"
13716
13717         mkdir $MOUNT/.lustre/dir &&
13718                 error "mkdir is not allowed under .lustre"
13719
13720         rm -rf $DIR/$tfile
13721 }
13722 run_test 154a "Open-by-FID"
13723
13724 test_154b() {
13725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13726         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13727         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13728         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13729                 skip "Need MDS version at least 2.2.51"
13730
13731         local remote_dir=$DIR/$tdir/remote_dir
13732         local MDTIDX=1
13733         local rc=0
13734
13735         mkdir -p $DIR/$tdir
13736         $LFS mkdir -i $MDTIDX $remote_dir ||
13737                 error "create remote directory failed"
13738
13739         cp /etc/hosts $remote_dir/$tfile
13740
13741         fid=$($LFS path2fid $remote_dir/$tfile)
13742         rc=$?
13743         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13744
13745         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13746                 error "dot lustre permission check $fid failed"
13747         rm -rf $DIR/$tdir
13748 }
13749 run_test 154b "Open-by-FID for remote directory"
13750
13751 test_154c() {
13752         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13753                 skip "Need MDS version at least 2.4.1"
13754
13755         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13756         local FID1=$($LFS path2fid $DIR/$tfile.1)
13757         local FID2=$($LFS path2fid $DIR/$tfile.2)
13758         local FID3=$($LFS path2fid $DIR/$tfile.3)
13759
13760         local N=1
13761         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13762                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13763                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13764                 local want=FID$N
13765                 [ "$FID" = "${!want}" ] ||
13766                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13767                 N=$((N + 1))
13768         done
13769
13770         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13771         do
13772                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13773                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13774                 N=$((N + 1))
13775         done
13776 }
13777 run_test 154c "lfs path2fid and fid2path multiple arguments"
13778
13779 test_154d() {
13780         remote_mds_nodsh && skip "remote MDS with nodsh"
13781         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13782                 skip "Need MDS version at least 2.5.53"
13783
13784         if remote_mds; then
13785                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13786         else
13787                 nid="0@lo"
13788         fi
13789         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13790         local fd
13791         local cmd
13792
13793         rm -f $DIR/$tfile
13794         touch $DIR/$tfile
13795
13796         local fid=$($LFS path2fid $DIR/$tfile)
13797         # Open the file
13798         fd=$(free_fd)
13799         cmd="exec $fd<$DIR/$tfile"
13800         eval $cmd
13801         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13802         echo "$fid_list" | grep "$fid"
13803         rc=$?
13804
13805         cmd="exec $fd>/dev/null"
13806         eval $cmd
13807         if [ $rc -ne 0 ]; then
13808                 error "FID $fid not found in open files list $fid_list"
13809         fi
13810 }
13811 run_test 154d "Verify open file fid"
13812
13813 test_154e()
13814 {
13815         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13816                 skip "Need MDS version at least 2.6.50"
13817
13818         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13819                 error ".lustre returned by readdir"
13820         fi
13821 }
13822 run_test 154e ".lustre is not returned by readdir"
13823
13824 test_154f() {
13825         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13826
13827         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13828         test_mkdir -p -c1 $DIR/$tdir/d
13829         # test dirs inherit from its stripe
13830         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13831         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13832         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13833         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13834         touch $DIR/f
13835
13836         # get fid of parents
13837         local FID0=$($LFS path2fid $DIR/$tdir/d)
13838         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13839         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13840         local FID3=$($LFS path2fid $DIR)
13841
13842         # check that path2fid --parents returns expected <parent_fid>/name
13843         # 1) test for a directory (single parent)
13844         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13845         [ "$parent" == "$FID0/foo1" ] ||
13846                 error "expected parent: $FID0/foo1, got: $parent"
13847
13848         # 2) test for a file with nlink > 1 (multiple parents)
13849         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13850         echo "$parent" | grep -F "$FID1/$tfile" ||
13851                 error "$FID1/$tfile not returned in parent list"
13852         echo "$parent" | grep -F "$FID2/link" ||
13853                 error "$FID2/link not returned in parent list"
13854
13855         # 3) get parent by fid
13856         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13857         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13858         echo "$parent" | grep -F "$FID1/$tfile" ||
13859                 error "$FID1/$tfile not returned in parent list (by fid)"
13860         echo "$parent" | grep -F "$FID2/link" ||
13861                 error "$FID2/link not returned in parent list (by fid)"
13862
13863         # 4) test for entry in root directory
13864         parent=$($LFS path2fid --parents $DIR/f)
13865         echo "$parent" | grep -F "$FID3/f" ||
13866                 error "$FID3/f not returned in parent list"
13867
13868         # 5) test it on root directory
13869         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13870                 error "$MOUNT should not have parents"
13871
13872         # enable xattr caching and check that linkea is correctly updated
13873         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13874         save_lustre_params client "llite.*.xattr_cache" > $save
13875         lctl set_param llite.*.xattr_cache 1
13876
13877         # 6.1) linkea update on rename
13878         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13879
13880         # get parents by fid
13881         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13882         # foo1 should no longer be returned in parent list
13883         echo "$parent" | grep -F "$FID1" &&
13884                 error "$FID1 should no longer be in parent list"
13885         # the new path should appear
13886         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13887                 error "$FID2/$tfile.moved is not in parent list"
13888
13889         # 6.2) linkea update on unlink
13890         rm -f $DIR/$tdir/d/foo2/link
13891         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13892         # foo2/link should no longer be returned in parent list
13893         echo "$parent" | grep -F "$FID2/link" &&
13894                 error "$FID2/link should no longer be in parent list"
13895         true
13896
13897         rm -f $DIR/f
13898         restore_lustre_params < $save
13899         rm -f $save
13900 }
13901 run_test 154f "get parent fids by reading link ea"
13902
13903 test_154g()
13904 {
13905         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13906         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13907            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13908                 skip "Need MDS version at least 2.6.92"
13909
13910         mkdir -p $DIR/$tdir
13911         llapi_fid_test -d $DIR/$tdir
13912 }
13913 run_test 154g "various llapi FID tests"
13914
13915 test_155_small_load() {
13916     local temp=$TMP/$tfile
13917     local file=$DIR/$tfile
13918
13919     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13920         error "dd of=$temp bs=6096 count=1 failed"
13921     cp $temp $file
13922     cancel_lru_locks $OSC
13923     cmp $temp $file || error "$temp $file differ"
13924
13925     $TRUNCATE $temp 6000
13926     $TRUNCATE $file 6000
13927     cmp $temp $file || error "$temp $file differ (truncate1)"
13928
13929     echo "12345" >>$temp
13930     echo "12345" >>$file
13931     cmp $temp $file || error "$temp $file differ (append1)"
13932
13933     echo "12345" >>$temp
13934     echo "12345" >>$file
13935     cmp $temp $file || error "$temp $file differ (append2)"
13936
13937     rm -f $temp $file
13938     true
13939 }
13940
13941 test_155_big_load() {
13942         remote_ost_nodsh && skip "remote OST with nodsh"
13943
13944         local temp=$TMP/$tfile
13945         local file=$DIR/$tfile
13946
13947         free_min_max
13948         local cache_size=$(do_facet ost$((MAXI+1)) \
13949                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13950         local large_file_size=$((cache_size * 2))
13951
13952         echo "OSS cache size: $cache_size KB"
13953         echo "Large file size: $large_file_size KB"
13954
13955         [ $MAXV -le $large_file_size ] &&
13956                 skip_env "max available OST size needs > $large_file_size KB"
13957
13958         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13959
13960         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13961                 error "dd of=$temp bs=$large_file_size count=1k failed"
13962         cp $temp $file
13963         ls -lh $temp $file
13964         cancel_lru_locks osc
13965         cmp $temp $file || error "$temp $file differ"
13966
13967         rm -f $temp $file
13968         true
13969 }
13970
13971 save_writethrough() {
13972         local facets=$(get_facets OST)
13973
13974         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13975 }
13976
13977 test_155a() {
13978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13979
13980         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13981
13982         save_writethrough $p
13983
13984         set_cache read on
13985         set_cache writethrough on
13986         test_155_small_load
13987         restore_lustre_params < $p
13988         rm -f $p
13989 }
13990 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13991
13992 test_155b() {
13993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13994
13995         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13996
13997         save_writethrough $p
13998
13999         set_cache read on
14000         set_cache writethrough off
14001         test_155_small_load
14002         restore_lustre_params < $p
14003         rm -f $p
14004 }
14005 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14006
14007 test_155c() {
14008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14009
14010         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14011
14012         save_writethrough $p
14013
14014         set_cache read off
14015         set_cache writethrough on
14016         test_155_small_load
14017         restore_lustre_params < $p
14018         rm -f $p
14019 }
14020 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14021
14022 test_155d() {
14023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14024
14025         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14026
14027         save_writethrough $p
14028
14029         set_cache read off
14030         set_cache writethrough off
14031         test_155_small_load
14032         restore_lustre_params < $p
14033         rm -f $p
14034 }
14035 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14036
14037 test_155e() {
14038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14039
14040         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14041
14042         save_writethrough $p
14043
14044         set_cache read on
14045         set_cache writethrough on
14046         test_155_big_load
14047         restore_lustre_params < $p
14048         rm -f $p
14049 }
14050 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14051
14052 test_155f() {
14053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14054
14055         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14056
14057         save_writethrough $p
14058
14059         set_cache read on
14060         set_cache writethrough off
14061         test_155_big_load
14062         restore_lustre_params < $p
14063         rm -f $p
14064 }
14065 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14066
14067 test_155g() {
14068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14069
14070         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14071
14072         save_writethrough $p
14073
14074         set_cache read off
14075         set_cache writethrough on
14076         test_155_big_load
14077         restore_lustre_params < $p
14078         rm -f $p
14079 }
14080 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14081
14082 test_155h() {
14083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14084
14085         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14086
14087         save_writethrough $p
14088
14089         set_cache read off
14090         set_cache writethrough off
14091         test_155_big_load
14092         restore_lustre_params < $p
14093         rm -f $p
14094 }
14095 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14096
14097 test_156() {
14098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14099         remote_ost_nodsh && skip "remote OST with nodsh"
14100         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14101                 skip "stats not implemented on old servers"
14102         [ "$ost1_FSTYPE" = "zfs" ] &&
14103                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14104
14105         local CPAGES=3
14106         local BEFORE
14107         local AFTER
14108         local file="$DIR/$tfile"
14109         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14110
14111         save_writethrough $p
14112         roc_hit_init
14113
14114         log "Turn on read and write cache"
14115         set_cache read on
14116         set_cache writethrough on
14117
14118         log "Write data and read it back."
14119         log "Read should be satisfied from the cache."
14120         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14121         BEFORE=$(roc_hit)
14122         cancel_lru_locks osc
14123         cat $file >/dev/null
14124         AFTER=$(roc_hit)
14125         if ! let "AFTER - BEFORE == CPAGES"; then
14126                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14127         else
14128                 log "cache hits: before: $BEFORE, after: $AFTER"
14129         fi
14130
14131         log "Read again; it should be satisfied from the cache."
14132         BEFORE=$AFTER
14133         cancel_lru_locks osc
14134         cat $file >/dev/null
14135         AFTER=$(roc_hit)
14136         if ! let "AFTER - BEFORE == CPAGES"; then
14137                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14138         else
14139                 log "cache hits:: before: $BEFORE, after: $AFTER"
14140         fi
14141
14142         log "Turn off the read cache and turn on the write cache"
14143         set_cache read off
14144         set_cache writethrough on
14145
14146         log "Read again; it should be satisfied from the cache."
14147         BEFORE=$(roc_hit)
14148         cancel_lru_locks osc
14149         cat $file >/dev/null
14150         AFTER=$(roc_hit)
14151         if ! let "AFTER - BEFORE == CPAGES"; then
14152                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14153         else
14154                 log "cache hits:: before: $BEFORE, after: $AFTER"
14155         fi
14156
14157         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14158                 # > 2.12.56 uses pagecache if cached
14159                 log "Read again; it should not be satisfied from the cache."
14160                 BEFORE=$AFTER
14161                 cancel_lru_locks osc
14162                 cat $file >/dev/null
14163                 AFTER=$(roc_hit)
14164                 if ! let "AFTER - BEFORE == 0"; then
14165                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14166                 else
14167                         log "cache hits:: before: $BEFORE, after: $AFTER"
14168                 fi
14169         fi
14170
14171         log "Write data and read it back."
14172         log "Read should be satisfied from the cache."
14173         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14174         BEFORE=$(roc_hit)
14175         cancel_lru_locks osc
14176         cat $file >/dev/null
14177         AFTER=$(roc_hit)
14178         if ! let "AFTER - BEFORE == CPAGES"; then
14179                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14180         else
14181                 log "cache hits:: before: $BEFORE, after: $AFTER"
14182         fi
14183
14184         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14185                 # > 2.12.56 uses pagecache if cached
14186                 log "Read again; it should not be satisfied from the cache."
14187                 BEFORE=$AFTER
14188                 cancel_lru_locks osc
14189                 cat $file >/dev/null
14190                 AFTER=$(roc_hit)
14191                 if ! let "AFTER - BEFORE == 0"; then
14192                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14193                 else
14194                         log "cache hits:: before: $BEFORE, after: $AFTER"
14195                 fi
14196         fi
14197
14198         log "Turn off read and write cache"
14199         set_cache read off
14200         set_cache writethrough off
14201
14202         log "Write data and read it back"
14203         log "It should not be satisfied from the cache."
14204         rm -f $file
14205         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14206         cancel_lru_locks osc
14207         BEFORE=$(roc_hit)
14208         cat $file >/dev/null
14209         AFTER=$(roc_hit)
14210         if ! let "AFTER - BEFORE == 0"; then
14211                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14212         else
14213                 log "cache hits:: before: $BEFORE, after: $AFTER"
14214         fi
14215
14216         log "Turn on the read cache and turn off the write cache"
14217         set_cache read on
14218         set_cache writethrough off
14219
14220         log "Write data and read it back"
14221         log "It should not be satisfied from the cache."
14222         rm -f $file
14223         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14224         BEFORE=$(roc_hit)
14225         cancel_lru_locks osc
14226         cat $file >/dev/null
14227         AFTER=$(roc_hit)
14228         if ! let "AFTER - BEFORE == 0"; then
14229                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14230         else
14231                 log "cache hits:: before: $BEFORE, after: $AFTER"
14232         fi
14233
14234         log "Read again; it should be satisfied from the cache."
14235         BEFORE=$(roc_hit)
14236         cancel_lru_locks osc
14237         cat $file >/dev/null
14238         AFTER=$(roc_hit)
14239         if ! let "AFTER - BEFORE == CPAGES"; then
14240                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14241         else
14242                 log "cache hits:: before: $BEFORE, after: $AFTER"
14243         fi
14244
14245         restore_lustre_params < $p
14246         rm -f $p $file
14247 }
14248 run_test 156 "Verification of tunables"
14249
14250 test_160a() {
14251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14252         remote_mds_nodsh && skip "remote MDS with nodsh"
14253         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14254                 skip "Need MDS version at least 2.2.0"
14255
14256         changelog_register || error "changelog_register failed"
14257         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14258         changelog_users $SINGLEMDS | grep -q $cl_user ||
14259                 error "User $cl_user not found in changelog_users"
14260
14261         # change something
14262         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14263         changelog_clear 0 || error "changelog_clear failed"
14264         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14265         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14266         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14267         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14268         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14269         rm $DIR/$tdir/pics/desktop.jpg
14270
14271         changelog_dump | tail -10
14272
14273         echo "verifying changelog mask"
14274         changelog_chmask "-MKDIR"
14275         changelog_chmask "-CLOSE"
14276
14277         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14278         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14279
14280         changelog_chmask "+MKDIR"
14281         changelog_chmask "+CLOSE"
14282
14283         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14284         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14285
14286         changelog_dump | tail -10
14287         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14288         CLOSES=$(changelog_dump | grep -c "CLOSE")
14289         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14290         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14291
14292         # verify contents
14293         echo "verifying target fid"
14294         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14295         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14296         [ "$fidc" == "$fidf" ] ||
14297                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14298         echo "verifying parent fid"
14299         # The FID returned from the Changelog may be the directory shard on
14300         # a different MDT, and not the FID returned by path2fid on the parent.
14301         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14302         # since this is what will matter when recreating this file in the tree.
14303         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14304         local pathp=$($LFS fid2path $MOUNT "$fidp")
14305         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14306                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14307
14308         echo "getting records for $cl_user"
14309         changelog_users $SINGLEMDS
14310         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14311         local nclr=3
14312         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14313                 error "changelog_clear failed"
14314         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14315         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14316         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14317                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14318
14319         local min0_rec=$(changelog_users $SINGLEMDS |
14320                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14321         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14322                           awk '{ print $1; exit; }')
14323
14324         changelog_dump | tail -n 5
14325         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14326         [ $first_rec == $((min0_rec + 1)) ] ||
14327                 error "first index should be $min0_rec + 1 not $first_rec"
14328
14329         # LU-3446 changelog index reset on MDT restart
14330         local cur_rec1=$(changelog_users $SINGLEMDS |
14331                          awk '/^current.index:/ { print $NF }')
14332         changelog_clear 0 ||
14333                 error "clear all changelog records for $cl_user failed"
14334         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14335         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14336                 error "Fail to start $SINGLEMDS"
14337         local cur_rec2=$(changelog_users $SINGLEMDS |
14338                          awk '/^current.index:/ { print $NF }')
14339         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14340         [ $cur_rec1 == $cur_rec2 ] ||
14341                 error "current index should be $cur_rec1 not $cur_rec2"
14342
14343         echo "verifying users from this test are deregistered"
14344         changelog_deregister || error "changelog_deregister failed"
14345         changelog_users $SINGLEMDS | grep -q $cl_user &&
14346                 error "User '$cl_user' still in changelog_users"
14347
14348         # lctl get_param -n mdd.*.changelog_users
14349         # current index: 144
14350         # ID    index (idle seconds)
14351         # cl3   144 (2)
14352         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14353                 # this is the normal case where all users were deregistered
14354                 # make sure no new records are added when no users are present
14355                 local last_rec1=$(changelog_users $SINGLEMDS |
14356                                   awk '/^current.index:/ { print $NF }')
14357                 touch $DIR/$tdir/chloe
14358                 local last_rec2=$(changelog_users $SINGLEMDS |
14359                                   awk '/^current.index:/ { print $NF }')
14360                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14361                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14362         else
14363                 # any changelog users must be leftovers from a previous test
14364                 changelog_users $SINGLEMDS
14365                 echo "other changelog users; can't verify off"
14366         fi
14367 }
14368 run_test 160a "changelog sanity"
14369
14370 test_160b() { # LU-3587
14371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14372         remote_mds_nodsh && skip "remote MDS with nodsh"
14373         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14374                 skip "Need MDS version at least 2.2.0"
14375
14376         changelog_register || error "changelog_register failed"
14377         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14378         changelog_users $SINGLEMDS | grep -q $cl_user ||
14379                 error "User '$cl_user' not found in changelog_users"
14380
14381         local longname1=$(str_repeat a 255)
14382         local longname2=$(str_repeat b 255)
14383
14384         cd $DIR
14385         echo "creating very long named file"
14386         touch $longname1 || error "create of '$longname1' failed"
14387         echo "renaming very long named file"
14388         mv $longname1 $longname2
14389
14390         changelog_dump | grep RENME | tail -n 5
14391         rm -f $longname2
14392 }
14393 run_test 160b "Verify that very long rename doesn't crash in changelog"
14394
14395 test_160c() {
14396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14397         remote_mds_nodsh && skip "remote MDS with nodsh"
14398
14399         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14400                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14401                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14402                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14403
14404         local rc=0
14405
14406         # Registration step
14407         changelog_register || error "changelog_register failed"
14408
14409         rm -rf $DIR/$tdir
14410         mkdir -p $DIR/$tdir
14411         $MCREATE $DIR/$tdir/foo_160c
14412         changelog_chmask "-TRUNC"
14413         $TRUNCATE $DIR/$tdir/foo_160c 200
14414         changelog_chmask "+TRUNC"
14415         $TRUNCATE $DIR/$tdir/foo_160c 199
14416         changelog_dump | tail -n 5
14417         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14418         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14419 }
14420 run_test 160c "verify that changelog log catch the truncate event"
14421
14422 test_160d() {
14423         remote_mds_nodsh && skip "remote MDS with nodsh"
14424         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14426         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14427                 skip "Need MDS version at least 2.7.60"
14428
14429         # Registration step
14430         changelog_register || error "changelog_register failed"
14431
14432         mkdir -p $DIR/$tdir/migrate_dir
14433         changelog_clear 0 || error "changelog_clear failed"
14434
14435         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14436         changelog_dump | tail -n 5
14437         local migrates=$(changelog_dump | grep -c "MIGRT")
14438         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14439 }
14440 run_test 160d "verify that changelog log catch the migrate event"
14441
14442 test_160e() {
14443         remote_mds_nodsh && skip "remote MDS with nodsh"
14444
14445         # Create a user
14446         changelog_register || error "changelog_register failed"
14447
14448         # Delete a future user (expect fail)
14449         local MDT0=$(facet_svc $SINGLEMDS)
14450         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14451         local rc=$?
14452
14453         if [ $rc -eq 0 ]; then
14454                 error "Deleted non-existant user cl77"
14455         elif [ $rc -ne 2 ]; then
14456                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14457         fi
14458
14459         # Clear to a bad index (1 billion should be safe)
14460         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14461         rc=$?
14462
14463         if [ $rc -eq 0 ]; then
14464                 error "Successfully cleared to invalid CL index"
14465         elif [ $rc -ne 22 ]; then
14466                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14467         fi
14468 }
14469 run_test 160e "changelog negative testing (should return errors)"
14470
14471 test_160f() {
14472         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14473         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14474                 skip "Need MDS version at least 2.10.56"
14475
14476         local mdts=$(comma_list $(mdts_nodes))
14477
14478         # Create a user
14479         changelog_register || error "first changelog_register failed"
14480         changelog_register || error "second changelog_register failed"
14481         local cl_users
14482         declare -A cl_user1
14483         declare -A cl_user2
14484         local user_rec1
14485         local user_rec2
14486         local i
14487
14488         # generate some changelog records to accumulate on each MDT
14489         # use fnv1a because created files should be evenly distributed
14490         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14491                 error "test_mkdir $tdir failed"
14492         log "$(date +%s): creating first files"
14493         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14494                 error "create $DIR/$tdir/$tfile failed"
14495
14496         # check changelogs have been generated
14497         local start=$SECONDS
14498         local idle_time=$((MDSCOUNT * 5 + 5))
14499         local nbcl=$(changelog_dump | wc -l)
14500         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14501
14502         for param in "changelog_max_idle_time=$idle_time" \
14503                      "changelog_gc=1" \
14504                      "changelog_min_gc_interval=2" \
14505                      "changelog_min_free_cat_entries=3"; do
14506                 local MDT0=$(facet_svc $SINGLEMDS)
14507                 local var="${param%=*}"
14508                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14509
14510                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14511                 do_nodes $mdts $LCTL set_param mdd.*.$param
14512         done
14513
14514         # force cl_user2 to be idle (1st part), but also cancel the
14515         # cl_user1 records so that it is not evicted later in the test.
14516         local sleep1=$((idle_time / 2))
14517         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14518         sleep $sleep1
14519
14520         # simulate changelog catalog almost full
14521         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14522         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14523
14524         for i in $(seq $MDSCOUNT); do
14525                 cl_users=(${CL_USERS[mds$i]})
14526                 cl_user1[mds$i]="${cl_users[0]}"
14527                 cl_user2[mds$i]="${cl_users[1]}"
14528
14529                 [ -n "${cl_user1[mds$i]}" ] ||
14530                         error "mds$i: no user registered"
14531                 [ -n "${cl_user2[mds$i]}" ] ||
14532                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14533
14534                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14535                 [ -n "$user_rec1" ] ||
14536                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14537                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14538                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14539                 [ -n "$user_rec2" ] ||
14540                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14541                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14542                      "$user_rec1 + 2 == $user_rec2"
14543                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14544                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14545                               "$user_rec1 + 2, but is $user_rec2"
14546                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14547                 [ -n "$user_rec2" ] ||
14548                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14549                 [ $user_rec1 == $user_rec2 ] ||
14550                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14551                               "$user_rec1, but is $user_rec2"
14552         done
14553
14554         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14555         local sleep2=$((idle_time - (SECONDS - start) + 1))
14556         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14557         sleep $sleep2
14558
14559         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14560         # cl_user1 should be OK because it recently processed records.
14561         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14562         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14563                 error "create $DIR/$tdir/${tfile}b failed"
14564
14565         # ensure gc thread is done
14566         for i in $(mdts_nodes); do
14567                 wait_update $i \
14568                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14569                         error "$i: GC-thread not done"
14570         done
14571
14572         local first_rec
14573         for i in $(seq $MDSCOUNT); do
14574                 # check cl_user1 still registered
14575                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14576                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14577                 # check cl_user2 unregistered
14578                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14579                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14580
14581                 # check changelogs are present and starting at $user_rec1 + 1
14582                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14583                 [ -n "$user_rec1" ] ||
14584                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14585                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14586                             awk '{ print $1; exit; }')
14587
14588                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14589                 [ $((user_rec1 + 1)) == $first_rec ] ||
14590                         error "mds$i: first index should be $user_rec1 + 1, " \
14591                               "but is $first_rec"
14592         done
14593 }
14594 run_test 160f "changelog garbage collect (timestamped users)"
14595
14596 test_160g() {
14597         remote_mds_nodsh && skip "remote MDS with nodsh"
14598         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14599                 skip "Need MDS version at least 2.10.56"
14600
14601         local mdts=$(comma_list $(mdts_nodes))
14602
14603         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14604         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14605
14606         # Create a user
14607         changelog_register || error "first changelog_register failed"
14608         changelog_register || error "second changelog_register failed"
14609         local cl_users
14610         declare -A cl_user1
14611         declare -A cl_user2
14612         local user_rec1
14613         local user_rec2
14614         local i
14615
14616         # generate some changelog records to accumulate on each MDT
14617         # use fnv1a because created files should be evenly distributed
14618         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14619                 error "mkdir $tdir failed"
14620         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14621                 error "create $DIR/$tdir/$tfile failed"
14622
14623         # check changelogs have been generated
14624         local nbcl=$(changelog_dump | wc -l)
14625         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14626
14627         # reduce the max_idle_indexes value to make sure we exceed it
14628         max_ndx=$((nbcl / 2 - 1))
14629
14630         for param in "changelog_max_idle_indexes=$max_ndx" \
14631                      "changelog_gc=1" \
14632                      "changelog_min_gc_interval=2" \
14633                      "changelog_min_free_cat_entries=3"; do
14634                 local MDT0=$(facet_svc $SINGLEMDS)
14635                 local var="${param%=*}"
14636                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14637
14638                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14639                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14640                         error "unable to set mdd.*.$param"
14641         done
14642
14643         # simulate changelog catalog almost full
14644         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14645         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14646
14647         for i in $(seq $MDSCOUNT); do
14648                 cl_users=(${CL_USERS[mds$i]})
14649                 cl_user1[mds$i]="${cl_users[0]}"
14650                 cl_user2[mds$i]="${cl_users[1]}"
14651
14652                 [ -n "${cl_user1[mds$i]}" ] ||
14653                         error "mds$i: no user registered"
14654                 [ -n "${cl_user2[mds$i]}" ] ||
14655                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14656
14657                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14658                 [ -n "$user_rec1" ] ||
14659                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14660                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14661                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14662                 [ -n "$user_rec2" ] ||
14663                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14664                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14665                      "$user_rec1 + 2 == $user_rec2"
14666                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14667                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14668                               "$user_rec1 + 2, but is $user_rec2"
14669                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14670                 [ -n "$user_rec2" ] ||
14671                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14672                 [ $user_rec1 == $user_rec2 ] ||
14673                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14674                               "$user_rec1, but is $user_rec2"
14675         done
14676
14677         # ensure we are past the previous changelog_min_gc_interval set above
14678         sleep 2
14679
14680         # generate one more changelog to trigger fail_loc
14681         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14682                 error "create $DIR/$tdir/${tfile}bis failed"
14683
14684         # ensure gc thread is done
14685         for i in $(mdts_nodes); do
14686                 wait_update $i \
14687                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14688                         error "$i: GC-thread not done"
14689         done
14690
14691         local first_rec
14692         for i in $(seq $MDSCOUNT); do
14693                 # check cl_user1 still registered
14694                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14695                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14696                 # check cl_user2 unregistered
14697                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14698                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14699
14700                 # check changelogs are present and starting at $user_rec1 + 1
14701                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14702                 [ -n "$user_rec1" ] ||
14703                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14704                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14705                             awk '{ print $1; exit; }')
14706
14707                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14708                 [ $((user_rec1 + 1)) == $first_rec ] ||
14709                         error "mds$i: first index should be $user_rec1 + 1, " \
14710                               "but is $first_rec"
14711         done
14712 }
14713 run_test 160g "changelog garbage collect (old users)"
14714
14715 test_160h() {
14716         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14717         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14718                 skip "Need MDS version at least 2.10.56"
14719
14720         local mdts=$(comma_list $(mdts_nodes))
14721
14722         # Create a user
14723         changelog_register || error "first changelog_register failed"
14724         changelog_register || error "second changelog_register failed"
14725         local cl_users
14726         declare -A cl_user1
14727         declare -A cl_user2
14728         local user_rec1
14729         local user_rec2
14730         local i
14731
14732         # generate some changelog records to accumulate on each MDT
14733         # use fnv1a because created files should be evenly distributed
14734         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14735                 error "test_mkdir $tdir failed"
14736         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14737                 error "create $DIR/$tdir/$tfile failed"
14738
14739         # check changelogs have been generated
14740         local nbcl=$(changelog_dump | wc -l)
14741         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14742
14743         for param in "changelog_max_idle_time=10" \
14744                      "changelog_gc=1" \
14745                      "changelog_min_gc_interval=2"; do
14746                 local MDT0=$(facet_svc $SINGLEMDS)
14747                 local var="${param%=*}"
14748                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14749
14750                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14751                 do_nodes $mdts $LCTL set_param mdd.*.$param
14752         done
14753
14754         # force cl_user2 to be idle (1st part)
14755         sleep 9
14756
14757         for i in $(seq $MDSCOUNT); do
14758                 cl_users=(${CL_USERS[mds$i]})
14759                 cl_user1[mds$i]="${cl_users[0]}"
14760                 cl_user2[mds$i]="${cl_users[1]}"
14761
14762                 [ -n "${cl_user1[mds$i]}" ] ||
14763                         error "mds$i: no user registered"
14764                 [ -n "${cl_user2[mds$i]}" ] ||
14765                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14766
14767                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14768                 [ -n "$user_rec1" ] ||
14769                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14770                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14771                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14772                 [ -n "$user_rec2" ] ||
14773                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14774                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14775                      "$user_rec1 + 2 == $user_rec2"
14776                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14777                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14778                               "$user_rec1 + 2, but is $user_rec2"
14779                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14780                 [ -n "$user_rec2" ] ||
14781                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14782                 [ $user_rec1 == $user_rec2 ] ||
14783                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14784                               "$user_rec1, but is $user_rec2"
14785         done
14786
14787         # force cl_user2 to be idle (2nd part) and to reach
14788         # changelog_max_idle_time
14789         sleep 2
14790
14791         # force each GC-thread start and block then
14792         # one per MDT/MDD, set fail_val accordingly
14793         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14794         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14795
14796         # generate more changelogs to trigger fail_loc
14797         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14798                 error "create $DIR/$tdir/${tfile}bis failed"
14799
14800         # stop MDT to stop GC-thread, should be done in back-ground as it will
14801         # block waiting for the thread to be released and exit
14802         declare -A stop_pids
14803         for i in $(seq $MDSCOUNT); do
14804                 stop mds$i &
14805                 stop_pids[mds$i]=$!
14806         done
14807
14808         for i in $(mdts_nodes); do
14809                 local facet
14810                 local nb=0
14811                 local facets=$(facets_up_on_host $i)
14812
14813                 for facet in ${facets//,/ }; do
14814                         if [[ $facet == mds* ]]; then
14815                                 nb=$((nb + 1))
14816                         fi
14817                 done
14818                 # ensure each MDS's gc threads are still present and all in "R"
14819                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14820                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14821                         error "$i: expected $nb GC-thread"
14822                 wait_update $i \
14823                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14824                         "R" 20 ||
14825                         error "$i: GC-thread not found in R-state"
14826                 # check umounts of each MDT on MDS have reached kthread_stop()
14827                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14828                         error "$i: expected $nb umount"
14829                 wait_update $i \
14830                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14831                         error "$i: umount not found in D-state"
14832         done
14833
14834         # release all GC-threads
14835         do_nodes $mdts $LCTL set_param fail_loc=0
14836
14837         # wait for MDT stop to complete
14838         for i in $(seq $MDSCOUNT); do
14839                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14840         done
14841
14842         # XXX
14843         # may try to check if any orphan changelog records are present
14844         # via ldiskfs/zfs and llog_reader...
14845
14846         # re-start/mount MDTs
14847         for i in $(seq $MDSCOUNT); do
14848                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14849                         error "Fail to start mds$i"
14850         done
14851
14852         local first_rec
14853         for i in $(seq $MDSCOUNT); do
14854                 # check cl_user1 still registered
14855                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14856                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14857                 # check cl_user2 unregistered
14858                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14859                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14860
14861                 # check changelogs are present and starting at $user_rec1 + 1
14862                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14863                 [ -n "$user_rec1" ] ||
14864                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14865                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14866                             awk '{ print $1; exit; }')
14867
14868                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14869                 [ $((user_rec1 + 1)) == $first_rec ] ||
14870                         error "mds$i: first index should be $user_rec1 + 1, " \
14871                               "but is $first_rec"
14872         done
14873 }
14874 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14875               "during mount"
14876
14877 test_160i() {
14878
14879         local mdts=$(comma_list $(mdts_nodes))
14880
14881         changelog_register || error "first changelog_register failed"
14882
14883         # generate some changelog records to accumulate on each MDT
14884         # use fnv1a because created files should be evenly distributed
14885         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14886                 error "mkdir $tdir failed"
14887         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14888                 error "create $DIR/$tdir/$tfile failed"
14889
14890         # check changelogs have been generated
14891         local nbcl=$(changelog_dump | wc -l)
14892         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14893
14894         # simulate race between register and unregister
14895         # XXX as fail_loc is set per-MDS, with DNE configs the race
14896         # simulation will only occur for one MDT per MDS and for the
14897         # others the normal race scenario will take place
14898         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14899         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14900         do_nodes $mdts $LCTL set_param fail_val=1
14901
14902         # unregister 1st user
14903         changelog_deregister &
14904         local pid1=$!
14905         # wait some time for deregister work to reach race rdv
14906         sleep 2
14907         # register 2nd user
14908         changelog_register || error "2nd user register failed"
14909
14910         wait $pid1 || error "1st user deregister failed"
14911
14912         local i
14913         local last_rec
14914         declare -A LAST_REC
14915         for i in $(seq $MDSCOUNT); do
14916                 if changelog_users mds$i | grep "^cl"; then
14917                         # make sure new records are added with one user present
14918                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14919                                           awk '/^current.index:/ { print $NF }')
14920                 else
14921                         error "mds$i has no user registered"
14922                 fi
14923         done
14924
14925         # generate more changelog records to accumulate on each MDT
14926         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14927                 error "create $DIR/$tdir/${tfile}bis failed"
14928
14929         for i in $(seq $MDSCOUNT); do
14930                 last_rec=$(changelog_users $SINGLEMDS |
14931                            awk '/^current.index:/ { print $NF }')
14932                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14933                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14934                         error "changelogs are off on mds$i"
14935         done
14936 }
14937 run_test 160i "changelog user register/unregister race"
14938
14939 test_160j() {
14940         remote_mds_nodsh && skip "remote MDS with nodsh"
14941         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14942                 skip "Need MDS version at least 2.12.56"
14943
14944         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14945         stack_trap "umount $MOUNT2" EXIT
14946
14947         changelog_register || error "first changelog_register failed"
14948         stack_trap "changelog_deregister" EXIT
14949
14950         # generate some changelog
14951         # use fnv1a because created files should be evenly distributed
14952         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14953                 error "mkdir $tdir failed"
14954         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14955                 error "create $DIR/$tdir/${tfile}bis failed"
14956
14957         # open the changelog device
14958         exec 3>/dev/changelog-$FSNAME-MDT0000
14959         stack_trap "exec 3>&-" EXIT
14960         exec 4</dev/changelog-$FSNAME-MDT0000
14961         stack_trap "exec 4<&-" EXIT
14962
14963         # umount the first lustre mount
14964         umount $MOUNT
14965         stack_trap "mount_client $MOUNT" EXIT
14966
14967         # read changelog
14968         cat <&4 >/dev/null || error "read changelog failed"
14969
14970         # clear changelog
14971         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14972         changelog_users $SINGLEMDS | grep -q $cl_user ||
14973                 error "User $cl_user not found in changelog_users"
14974
14975         printf 'clear:'$cl_user':0' >&3
14976 }
14977 run_test 160j "client can be umounted  while its chanangelog is being used"
14978
14979 test_160k() {
14980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14981         remote_mds_nodsh && skip "remote MDS with nodsh"
14982
14983         mkdir -p $DIR/$tdir/1/1
14984
14985         changelog_register || error "changelog_register failed"
14986         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14987
14988         changelog_users $SINGLEMDS | grep -q $cl_user ||
14989                 error "User '$cl_user' not found in changelog_users"
14990 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14991         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
14992         rmdir $DIR/$tdir/1/1 & sleep 1
14993         mkdir $DIR/$tdir/2
14994         touch $DIR/$tdir/2/2
14995         rm -rf $DIR/$tdir/2
14996
14997         wait
14998         sleep 4
14999
15000         changelog_dump | grep rmdir || error "rmdir not recorded"
15001
15002         rm -rf $DIR/$tdir
15003         changelog_deregister
15004 }
15005 run_test 160k "Verify that changelog records are not lost"
15006
15007 # Verifies that a file passed as a parameter has recently had an operation
15008 # performed on it that has generated an MTIME changelog which contains the
15009 # correct parent FID. As files might reside on a different MDT from the
15010 # parent directory in DNE configurations, the FIDs are translated to paths
15011 # before being compared, which should be identical
15012 compare_mtime_changelog() {
15013         local file="${1}"
15014         local mdtidx
15015         local mtime
15016         local cl_fid
15017         local pdir
15018         local dir
15019
15020         mdtidx=$($LFS getstripe --mdt-index $file)
15021         mdtidx=$(printf "%04x" $mdtidx)
15022
15023         # Obtain the parent FID from the MTIME changelog
15024         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15025         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15026
15027         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15028         [ -z "$cl_fid" ] && error "parent FID not present"
15029
15030         # Verify that the path for the parent FID is the same as the path for
15031         # the test directory
15032         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15033
15034         dir=$(dirname $1)
15035
15036         [[ "${pdir%/}" == "$dir" ]] ||
15037                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15038 }
15039
15040 test_160l() {
15041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15042
15043         remote_mds_nodsh && skip "remote MDS with nodsh"
15044         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15045                 skip "Need MDS version at least 2.13.55"
15046
15047         local cl_user
15048
15049         changelog_register || error "changelog_register failed"
15050         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15051
15052         changelog_users $SINGLEMDS | grep -q $cl_user ||
15053                 error "User '$cl_user' not found in changelog_users"
15054
15055         # Clear some types so that MTIME changelogs are generated
15056         changelog_chmask "-CREAT"
15057         changelog_chmask "-CLOSE"
15058
15059         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15060
15061         # Test CL_MTIME during setattr
15062         touch $DIR/$tdir/$tfile
15063         compare_mtime_changelog $DIR/$tdir/$tfile
15064
15065         # Test CL_MTIME during close
15066         dd if=/dev/urandom of=$DIR/$tdir/${tfile}_2 bs=1M count=64 ||
15067                 error "cannot create file $DIR/$tdir/${tfile}_2"
15068         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15069 }
15070 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15071
15072 test_161a() {
15073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15074
15075         test_mkdir -c1 $DIR/$tdir
15076         cp /etc/hosts $DIR/$tdir/$tfile
15077         test_mkdir -c1 $DIR/$tdir/foo1
15078         test_mkdir -c1 $DIR/$tdir/foo2
15079         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15080         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15081         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15082         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15083         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15084         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15085                 $LFS fid2path $DIR $FID
15086                 error "bad link ea"
15087         fi
15088         # middle
15089         rm $DIR/$tdir/foo2/zachary
15090         # last
15091         rm $DIR/$tdir/foo2/thor
15092         # first
15093         rm $DIR/$tdir/$tfile
15094         # rename
15095         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15096         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15097                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15098         rm $DIR/$tdir/foo2/maggie
15099
15100         # overflow the EA
15101         local longname=$tfile.avg_len_is_thirty_two_
15102         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15103                 error_noexit 'failed to unlink many hardlinks'" EXIT
15104         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15105                 error "failed to hardlink many files"
15106         links=$($LFS fid2path $DIR $FID | wc -l)
15107         echo -n "${links}/1000 links in link EA"
15108         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15109 }
15110 run_test 161a "link ea sanity"
15111
15112 test_161b() {
15113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15114         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15115
15116         local MDTIDX=1
15117         local remote_dir=$DIR/$tdir/remote_dir
15118
15119         mkdir -p $DIR/$tdir
15120         $LFS mkdir -i $MDTIDX $remote_dir ||
15121                 error "create remote directory failed"
15122
15123         cp /etc/hosts $remote_dir/$tfile
15124         mkdir -p $remote_dir/foo1
15125         mkdir -p $remote_dir/foo2
15126         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15127         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15128         ln $remote_dir/$tfile $remote_dir/foo1/luna
15129         ln $remote_dir/$tfile $remote_dir/foo2/thor
15130
15131         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15132                      tr -d ']')
15133         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15134                 $LFS fid2path $DIR $FID
15135                 error "bad link ea"
15136         fi
15137         # middle
15138         rm $remote_dir/foo2/zachary
15139         # last
15140         rm $remote_dir/foo2/thor
15141         # first
15142         rm $remote_dir/$tfile
15143         # rename
15144         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15145         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15146         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15147                 $LFS fid2path $DIR $FID
15148                 error "bad link rename"
15149         fi
15150         rm $remote_dir/foo2/maggie
15151
15152         # overflow the EA
15153         local longname=filename_avg_len_is_thirty_two_
15154         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15155                 error "failed to hardlink many files"
15156         links=$($LFS fid2path $DIR $FID | wc -l)
15157         echo -n "${links}/1000 links in link EA"
15158         [[ ${links} -gt 60 ]] ||
15159                 error "expected at least 60 links in link EA"
15160         unlinkmany $remote_dir/foo2/$longname 1000 ||
15161         error "failed to unlink many hardlinks"
15162 }
15163 run_test 161b "link ea sanity under remote directory"
15164
15165 test_161c() {
15166         remote_mds_nodsh && skip "remote MDS with nodsh"
15167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15168         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15169                 skip "Need MDS version at least 2.1.5"
15170
15171         # define CLF_RENAME_LAST 0x0001
15172         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15173         changelog_register || error "changelog_register failed"
15174
15175         rm -rf $DIR/$tdir
15176         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15177         touch $DIR/$tdir/foo_161c
15178         touch $DIR/$tdir/bar_161c
15179         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15180         changelog_dump | grep RENME | tail -n 5
15181         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15182         changelog_clear 0 || error "changelog_clear failed"
15183         if [ x$flags != "x0x1" ]; then
15184                 error "flag $flags is not 0x1"
15185         fi
15186
15187         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15188         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15189         touch $DIR/$tdir/foo_161c
15190         touch $DIR/$tdir/bar_161c
15191         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15192         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15193         changelog_dump | grep RENME | tail -n 5
15194         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15195         changelog_clear 0 || error "changelog_clear failed"
15196         if [ x$flags != "x0x0" ]; then
15197                 error "flag $flags is not 0x0"
15198         fi
15199         echo "rename overwrite a target having nlink > 1," \
15200                 "changelog record has flags of $flags"
15201
15202         # rename doesn't overwrite a target (changelog flag 0x0)
15203         touch $DIR/$tdir/foo_161c
15204         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15205         changelog_dump | grep RENME | tail -n 5
15206         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15207         changelog_clear 0 || error "changelog_clear failed"
15208         if [ x$flags != "x0x0" ]; then
15209                 error "flag $flags is not 0x0"
15210         fi
15211         echo "rename doesn't overwrite a target," \
15212                 "changelog record has flags of $flags"
15213
15214         # define CLF_UNLINK_LAST 0x0001
15215         # unlink a file having nlink = 1 (changelog flag 0x1)
15216         rm -f $DIR/$tdir/foo2_161c
15217         changelog_dump | grep UNLNK | tail -n 5
15218         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15219         changelog_clear 0 || error "changelog_clear failed"
15220         if [ x$flags != "x0x1" ]; then
15221                 error "flag $flags is not 0x1"
15222         fi
15223         echo "unlink a file having nlink = 1," \
15224                 "changelog record has flags of $flags"
15225
15226         # unlink a file having nlink > 1 (changelog flag 0x0)
15227         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15228         rm -f $DIR/$tdir/foobar_161c
15229         changelog_dump | grep UNLNK | tail -n 5
15230         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15231         changelog_clear 0 || error "changelog_clear failed"
15232         if [ x$flags != "x0x0" ]; then
15233                 error "flag $flags is not 0x0"
15234         fi
15235         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15236 }
15237 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15238
15239 test_161d() {
15240         remote_mds_nodsh && skip "remote MDS with nodsh"
15241         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15242
15243         local pid
15244         local fid
15245
15246         changelog_register || error "changelog_register failed"
15247
15248         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15249         # interfer with $MOUNT/.lustre/fid/ access
15250         mkdir $DIR/$tdir
15251         [[ $? -eq 0 ]] || error "mkdir failed"
15252
15253         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15254         $LCTL set_param fail_loc=0x8000140c
15255         # 5s pause
15256         $LCTL set_param fail_val=5
15257
15258         # create file
15259         echo foofoo > $DIR/$tdir/$tfile &
15260         pid=$!
15261
15262         # wait for create to be delayed
15263         sleep 2
15264
15265         ps -p $pid
15266         [[ $? -eq 0 ]] || error "create should be blocked"
15267
15268         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15269         stack_trap "rm -f $tempfile"
15270         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15271         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15272         # some delay may occur during ChangeLog publishing and file read just
15273         # above, that could allow file write to happen finally
15274         [[ -s $tempfile ]] && echo "file should be empty"
15275
15276         $LCTL set_param fail_loc=0
15277
15278         wait $pid
15279         [[ $? -eq 0 ]] || error "create failed"
15280 }
15281 run_test 161d "create with concurrent .lustre/fid access"
15282
15283 check_path() {
15284         local expected="$1"
15285         shift
15286         local fid="$2"
15287
15288         local path
15289         path=$($LFS fid2path "$@")
15290         local rc=$?
15291
15292         if [ $rc -ne 0 ]; then
15293                 error "path looked up of '$expected' failed: rc=$rc"
15294         elif [ "$path" != "$expected" ]; then
15295                 error "path looked up '$path' instead of '$expected'"
15296         else
15297                 echo "FID '$fid' resolves to path '$path' as expected"
15298         fi
15299 }
15300
15301 test_162a() { # was test_162
15302         test_mkdir -p -c1 $DIR/$tdir/d2
15303         touch $DIR/$tdir/d2/$tfile
15304         touch $DIR/$tdir/d2/x1
15305         touch $DIR/$tdir/d2/x2
15306         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15307         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15308         # regular file
15309         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15310         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15311
15312         # softlink
15313         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15314         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15315         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15316
15317         # softlink to wrong file
15318         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15319         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15320         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15321
15322         # hardlink
15323         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15324         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15325         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15326         # fid2path dir/fsname should both work
15327         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15328         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15329
15330         # hardlink count: check that there are 2 links
15331         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15332         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15333
15334         # hardlink indexing: remove the first link
15335         rm $DIR/$tdir/d2/p/q/r/hlink
15336         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15337 }
15338 run_test 162a "path lookup sanity"
15339
15340 test_162b() {
15341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15342         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15343
15344         mkdir $DIR/$tdir
15345         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15346                                 error "create striped dir failed"
15347
15348         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15349                                         tail -n 1 | awk '{print $2}')
15350         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15351
15352         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15353         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15354
15355         # regular file
15356         for ((i=0;i<5;i++)); do
15357                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15358                         error "get fid for f$i failed"
15359                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15360
15361                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15362                         error "get fid for d$i failed"
15363                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15364         done
15365
15366         return 0
15367 }
15368 run_test 162b "striped directory path lookup sanity"
15369
15370 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15371 test_162c() {
15372         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15373                 skip "Need MDS version at least 2.7.51"
15374
15375         local lpath=$tdir.local
15376         local rpath=$tdir.remote
15377
15378         test_mkdir $DIR/$lpath
15379         test_mkdir $DIR/$rpath
15380
15381         for ((i = 0; i <= 101; i++)); do
15382                 lpath="$lpath/$i"
15383                 mkdir $DIR/$lpath
15384                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15385                         error "get fid for local directory $DIR/$lpath failed"
15386                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15387
15388                 rpath="$rpath/$i"
15389                 test_mkdir $DIR/$rpath
15390                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15391                         error "get fid for remote directory $DIR/$rpath failed"
15392                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15393         done
15394
15395         return 0
15396 }
15397 run_test 162c "fid2path works with paths 100 or more directories deep"
15398
15399 oalr_event_count() {
15400         local event="${1}"
15401         local trace="${2}"
15402
15403         awk -v name="${FSNAME}-OST0000" \
15404             -v event="${event}" \
15405             '$1 == "TRACE" && $2 == event && $3 == name' \
15406             "${trace}" |
15407         wc -l
15408 }
15409
15410 oalr_expect_event_count() {
15411         local event="${1}"
15412         local trace="${2}"
15413         local expect="${3}"
15414         local count
15415
15416         count=$(oalr_event_count "${event}" "${trace}")
15417         if ((count == expect)); then
15418                 return 0
15419         fi
15420
15421         error_noexit "${event} event count was '${count}', expected ${expect}"
15422         cat "${trace}" >&2
15423         exit 1
15424 }
15425
15426 cleanup_165() {
15427         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15428         stop ost1
15429         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15430 }
15431
15432 setup_165() {
15433         sync # Flush previous IOs so we can count log entries.
15434         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15435         stack_trap cleanup_165 EXIT
15436 }
15437
15438 test_165a() {
15439         local trace="/tmp/${tfile}.trace"
15440         local rc
15441         local count
15442
15443         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15444         setup_165
15445         sleep 5
15446
15447         do_facet ost1 ofd_access_log_reader --list
15448         stop ost1
15449
15450         do_facet ost1 killall -TERM ofd_access_log_reader
15451         wait
15452         rc=$?
15453
15454         if ((rc != 0)); then
15455                 error "ofd_access_log_reader exited with rc = '${rc}'"
15456         fi
15457
15458         # Parse trace file for discovery events:
15459         oalr_expect_event_count alr_log_add "${trace}" 1
15460         oalr_expect_event_count alr_log_eof "${trace}" 1
15461         oalr_expect_event_count alr_log_free "${trace}" 1
15462 }
15463 run_test 165a "ofd access log discovery"
15464
15465 test_165b() {
15466         local trace="/tmp/${tfile}.trace"
15467         local file="${DIR}/${tfile}"
15468         local pfid1
15469         local pfid2
15470         local -a entry
15471         local rc
15472         local count
15473         local size
15474         local flags
15475
15476         setup_165
15477
15478         lfs setstripe -c 1 -i 0 "${file}"
15479         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15480         do_facet ost1 ofd_access_log_reader --list
15481
15482         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15483         sleep 5
15484         do_facet ost1 killall -TERM ofd_access_log_reader
15485         wait
15486         rc=$?
15487
15488         if ((rc != 0)); then
15489                 error "ofd_access_log_reader exited with rc = '${rc}'"
15490         fi
15491
15492         oalr_expect_event_count alr_log_entry "${trace}" 1
15493
15494         pfid1=$($LFS path2fid "${file}")
15495
15496         # 1     2             3   4    5     6   7    8    9     10
15497         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15498         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15499
15500         echo "entry = '${entry[*]}'" >&2
15501
15502         pfid2=${entry[4]}
15503         if [[ "${pfid1}" != "${pfid2}" ]]; then
15504                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15505         fi
15506
15507         size=${entry[8]}
15508         if ((size != 1048576)); then
15509                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15510         fi
15511
15512         flags=${entry[10]}
15513         if [[ "${flags}" != "w" ]]; then
15514                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15515         fi
15516
15517         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15518         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c || error "cannot read '${file}'"
15519         sleep 5
15520         do_facet ost1 killall -TERM ofd_access_log_reader
15521         wait
15522         rc=$?
15523
15524         if ((rc != 0)); then
15525                 error "ofd_access_log_reader exited with rc = '${rc}'"
15526         fi
15527
15528         oalr_expect_event_count alr_log_entry "${trace}" 1
15529
15530         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15531         echo "entry = '${entry[*]}'" >&2
15532
15533         pfid2=${entry[4]}
15534         if [[ "${pfid1}" != "${pfid2}" ]]; then
15535                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15536         fi
15537
15538         size=${entry[8]}
15539         if ((size != 524288)); then
15540                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15541         fi
15542
15543         flags=${entry[10]}
15544         if [[ "${flags}" != "r" ]]; then
15545                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15546         fi
15547 }
15548 run_test 165b "ofd access log entries are produced and consumed"
15549
15550 test_165c() {
15551         local file="${DIR}/${tdir}/${tfile}"
15552         test_mkdir "${DIR}/${tdir}"
15553
15554         setup_165
15555
15556         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15557
15558         # 4096 / 64 = 64. Create twice as many entries.
15559         for ((i = 0; i < 128; i++)); do
15560                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c || error "cannot create file"
15561         done
15562
15563         sync
15564         do_facet ost1 ofd_access_log_reader --list
15565         unlinkmany  "${file}-%d" 128
15566 }
15567 run_test 165c "full ofd access logs do not block IOs"
15568
15569 oal_peek_entry_count() {
15570         do_facet ost1 ofd_access_log_reader --list | awk '$1 == "_entry_count:" { print $2; }'
15571 }
15572
15573 oal_expect_entry_count() {
15574         local entry_count=$(oal_peek_entry_count)
15575         local expect="$1"
15576
15577         if ((entry_count == expect)); then
15578                 return 0
15579         fi
15580
15581         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15582         do_facet ost1 ofd_access_log_reader --list >&2
15583         exit 1
15584 }
15585
15586 test_165d() {
15587         local trace="/tmp/${tfile}.trace"
15588         local file="${DIR}/${tdir}/${tfile}"
15589         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15590         local entry_count
15591         test_mkdir "${DIR}/${tdir}"
15592
15593         setup_165
15594         lfs setstripe -c 1 -i 0 "${file}"
15595
15596         do_facet ost1 lctl set_param "${param}=rw"
15597         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15598         oal_expect_entry_count 1
15599
15600         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15601         oal_expect_entry_count 2
15602
15603         do_facet ost1 lctl set_param "${param}=r"
15604         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15605         oal_expect_entry_count 2
15606
15607         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15608         oal_expect_entry_count 3
15609
15610         do_facet ost1 lctl set_param "${param}=w"
15611         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15612         oal_expect_entry_count 4
15613
15614         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15615         oal_expect_entry_count 4
15616
15617         do_facet ost1 lctl set_param "${param}=0"
15618         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15619         oal_expect_entry_count 4
15620
15621         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15622         oal_expect_entry_count 4
15623 }
15624 run_test 165d "ofd_access_log mask works"
15625
15626 test_169() {
15627         # do directio so as not to populate the page cache
15628         log "creating a 10 Mb file"
15629         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15630         log "starting reads"
15631         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15632         log "truncating the file"
15633         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15634         log "killing dd"
15635         kill %+ || true # reads might have finished
15636         echo "wait until dd is finished"
15637         wait
15638         log "removing the temporary file"
15639         rm -rf $DIR/$tfile || error "tmp file removal failed"
15640 }
15641 run_test 169 "parallel read and truncate should not deadlock"
15642
15643 test_170() {
15644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15645
15646         $LCTL clear     # bug 18514
15647         $LCTL debug_daemon start $TMP/${tfile}_log_good
15648         touch $DIR/$tfile
15649         $LCTL debug_daemon stop
15650         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15651                 error "sed failed to read log_good"
15652
15653         $LCTL debug_daemon start $TMP/${tfile}_log_good
15654         rm -rf $DIR/$tfile
15655         $LCTL debug_daemon stop
15656
15657         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15658                error "lctl df log_bad failed"
15659
15660         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15661         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15662
15663         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15664         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15665
15666         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15667                 error "bad_line good_line1 good_line2 are empty"
15668
15669         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15670         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15671         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15672
15673         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15674         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15675         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15676
15677         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15678                 error "bad_line_new good_line_new are empty"
15679
15680         local expected_good=$((good_line1 + good_line2*2))
15681
15682         rm -f $TMP/${tfile}*
15683         # LU-231, short malformed line may not be counted into bad lines
15684         if [ $bad_line -ne $bad_line_new ] &&
15685                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15686                 error "expected $bad_line bad lines, but got $bad_line_new"
15687                 return 1
15688         fi
15689
15690         if [ $expected_good -ne $good_line_new ]; then
15691                 error "expected $expected_good good lines, but got $good_line_new"
15692                 return 2
15693         fi
15694         true
15695 }
15696 run_test 170 "test lctl df to handle corrupted log ====================="
15697
15698 test_171() { # bug20592
15699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15700
15701         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15702         $LCTL set_param fail_loc=0x50e
15703         $LCTL set_param fail_val=3000
15704         multiop_bg_pause $DIR/$tfile O_s || true
15705         local MULTIPID=$!
15706         kill -USR1 $MULTIPID
15707         # cause log dump
15708         sleep 3
15709         wait $MULTIPID
15710         if dmesg | grep "recursive fault"; then
15711                 error "caught a recursive fault"
15712         fi
15713         $LCTL set_param fail_loc=0
15714         true
15715 }
15716 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15717
15718 # it would be good to share it with obdfilter-survey/iokit-libecho code
15719 setup_obdecho_osc () {
15720         local rc=0
15721         local ost_nid=$1
15722         local obdfilter_name=$2
15723         echo "Creating new osc for $obdfilter_name on $ost_nid"
15724         # make sure we can find loopback nid
15725         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15726
15727         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15728                            ${obdfilter_name}_osc_UUID || rc=2; }
15729         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15730                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15731         return $rc
15732 }
15733
15734 cleanup_obdecho_osc () {
15735         local obdfilter_name=$1
15736         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15737         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15738         return 0
15739 }
15740
15741 obdecho_test() {
15742         local OBD=$1
15743         local node=$2
15744         local pages=${3:-64}
15745         local rc=0
15746         local id
15747
15748         local count=10
15749         local obd_size=$(get_obd_size $node $OBD)
15750         local page_size=$(get_page_size $node)
15751         if [[ -n "$obd_size" ]]; then
15752                 local new_count=$((obd_size / (pages * page_size / 1024)))
15753                 [[ $new_count -ge $count ]] || count=$new_count
15754         fi
15755
15756         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15757         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15758                            rc=2; }
15759         if [ $rc -eq 0 ]; then
15760             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15761             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15762         fi
15763         echo "New object id is $id"
15764         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15765                            rc=4; }
15766         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15767                            "test_brw $count w v $pages $id" || rc=4; }
15768         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15769                            rc=4; }
15770         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15771                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15772         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15773                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15774         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15775         return $rc
15776 }
15777
15778 test_180a() {
15779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15780
15781         if ! module_loaded obdecho; then
15782                 load_module obdecho/obdecho &&
15783                         stack_trap "rmmod obdecho" EXIT ||
15784                         error "unable to load obdecho on client"
15785         fi
15786
15787         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15788         local host=$($LCTL get_param -n osc.$osc.import |
15789                      awk '/current_connection:/ { print $2 }' )
15790         local target=$($LCTL get_param -n osc.$osc.import |
15791                        awk '/target:/ { print $2 }' )
15792         target=${target%_UUID}
15793
15794         if [ -n "$target" ]; then
15795                 setup_obdecho_osc $host $target &&
15796                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15797                         { error "obdecho setup failed with $?"; return; }
15798
15799                 obdecho_test ${target}_osc client ||
15800                         error "obdecho_test failed on ${target}_osc"
15801         else
15802                 $LCTL get_param osc.$osc.import
15803                 error "there is no osc.$osc.import target"
15804         fi
15805 }
15806 run_test 180a "test obdecho on osc"
15807
15808 test_180b() {
15809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15810         remote_ost_nodsh && skip "remote OST with nodsh"
15811
15812         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15813                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15814                 error "failed to load module obdecho"
15815
15816         local target=$(do_facet ost1 $LCTL dl |
15817                        awk '/obdfilter/ { print $4; exit; }')
15818
15819         if [ -n "$target" ]; then
15820                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15821         else
15822                 do_facet ost1 $LCTL dl
15823                 error "there is no obdfilter target on ost1"
15824         fi
15825 }
15826 run_test 180b "test obdecho directly on obdfilter"
15827
15828 test_180c() { # LU-2598
15829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15830         remote_ost_nodsh && skip "remote OST with nodsh"
15831         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15832                 skip "Need MDS version at least 2.4.0"
15833
15834         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15835                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15836                 error "failed to load module obdecho"
15837
15838         local target=$(do_facet ost1 $LCTL dl |
15839                        awk '/obdfilter/ { print $4; exit; }')
15840
15841         if [ -n "$target" ]; then
15842                 local pages=16384 # 64MB bulk I/O RPC size
15843
15844                 obdecho_test "$target" ost1 "$pages" ||
15845                         error "obdecho_test with pages=$pages failed with $?"
15846         else
15847                 do_facet ost1 $LCTL dl
15848                 error "there is no obdfilter target on ost1"
15849         fi
15850 }
15851 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15852
15853 test_181() { # bug 22177
15854         test_mkdir $DIR/$tdir
15855         # create enough files to index the directory
15856         createmany -o $DIR/$tdir/foobar 4000
15857         # print attributes for debug purpose
15858         lsattr -d .
15859         # open dir
15860         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15861         MULTIPID=$!
15862         # remove the files & current working dir
15863         unlinkmany $DIR/$tdir/foobar 4000
15864         rmdir $DIR/$tdir
15865         kill -USR1 $MULTIPID
15866         wait $MULTIPID
15867         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15868         return 0
15869 }
15870 run_test 181 "Test open-unlinked dir ========================"
15871
15872 test_182() {
15873         local fcount=1000
15874         local tcount=10
15875
15876         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15877
15878         $LCTL set_param mdc.*.rpc_stats=clear
15879
15880         for (( i = 0; i < $tcount; i++ )) ; do
15881                 mkdir $DIR/$tdir/$i
15882         done
15883
15884         for (( i = 0; i < $tcount; i++ )) ; do
15885                 createmany -o $DIR/$tdir/$i/f- $fcount &
15886         done
15887         wait
15888
15889         for (( i = 0; i < $tcount; i++ )) ; do
15890                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15891         done
15892         wait
15893
15894         $LCTL get_param mdc.*.rpc_stats
15895
15896         rm -rf $DIR/$tdir
15897 }
15898 run_test 182 "Test parallel modify metadata operations ================"
15899
15900 test_183() { # LU-2275
15901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15902         remote_mds_nodsh && skip "remote MDS with nodsh"
15903         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15904                 skip "Need MDS version at least 2.3.56"
15905
15906         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15907         echo aaa > $DIR/$tdir/$tfile
15908
15909 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
15910         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
15911
15912         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
15913         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
15914
15915         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15916
15917         # Flush negative dentry cache
15918         touch $DIR/$tdir/$tfile
15919
15920         # We are not checking for any leaked references here, they'll
15921         # become evident next time we do cleanup with module unload.
15922         rm -rf $DIR/$tdir
15923 }
15924 run_test 183 "No crash or request leak in case of strange dispositions ========"
15925
15926 # test suite 184 is for LU-2016, LU-2017
15927 test_184a() {
15928         check_swap_layouts_support
15929
15930         dir0=$DIR/$tdir/$testnum
15931         test_mkdir -p -c1 $dir0
15932         ref1=/etc/passwd
15933         ref2=/etc/group
15934         file1=$dir0/f1
15935         file2=$dir0/f2
15936         $LFS setstripe -c1 $file1
15937         cp $ref1 $file1
15938         $LFS setstripe -c2 $file2
15939         cp $ref2 $file2
15940         gen1=$($LFS getstripe -g $file1)
15941         gen2=$($LFS getstripe -g $file2)
15942
15943         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
15944         gen=$($LFS getstripe -g $file1)
15945         [[ $gen1 != $gen ]] ||
15946                 "Layout generation on $file1 does not change"
15947         gen=$($LFS getstripe -g $file2)
15948         [[ $gen2 != $gen ]] ||
15949                 "Layout generation on $file2 does not change"
15950
15951         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
15952         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15953
15954         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
15955 }
15956 run_test 184a "Basic layout swap"
15957
15958 test_184b() {
15959         check_swap_layouts_support
15960
15961         dir0=$DIR/$tdir/$testnum
15962         mkdir -p $dir0 || error "creating dir $dir0"
15963         file1=$dir0/f1
15964         file2=$dir0/f2
15965         file3=$dir0/f3
15966         dir1=$dir0/d1
15967         dir2=$dir0/d2
15968         mkdir $dir1 $dir2
15969         $LFS setstripe -c1 $file1
15970         $LFS setstripe -c2 $file2
15971         $LFS setstripe -c1 $file3
15972         chown $RUNAS_ID $file3
15973         gen1=$($LFS getstripe -g $file1)
15974         gen2=$($LFS getstripe -g $file2)
15975
15976         $LFS swap_layouts $dir1 $dir2 &&
15977                 error "swap of directories layouts should fail"
15978         $LFS swap_layouts $dir1 $file1 &&
15979                 error "swap of directory and file layouts should fail"
15980         $RUNAS $LFS swap_layouts $file1 $file2 &&
15981                 error "swap of file we cannot write should fail"
15982         $LFS swap_layouts $file1 $file3 &&
15983                 error "swap of file with different owner should fail"
15984         /bin/true # to clear error code
15985 }
15986 run_test 184b "Forbidden layout swap (will generate errors)"
15987
15988 test_184c() {
15989         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
15990         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
15991         check_swap_layouts_support
15992         check_swap_layout_no_dom $DIR
15993
15994         local dir0=$DIR/$tdir/$testnum
15995         mkdir -p $dir0 || error "creating dir $dir0"
15996
15997         local ref1=$dir0/ref1
15998         local ref2=$dir0/ref2
15999         local file1=$dir0/file1
16000         local file2=$dir0/file2
16001         # create a file large enough for the concurrent test
16002         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16003         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16004         echo "ref file size: ref1($(stat -c %s $ref1))," \
16005              "ref2($(stat -c %s $ref2))"
16006
16007         cp $ref2 $file2
16008         dd if=$ref1 of=$file1 bs=16k &
16009         local DD_PID=$!
16010
16011         # Make sure dd starts to copy file
16012         while [ ! -f $file1 ]; do sleep 0.1; done
16013
16014         $LFS swap_layouts $file1 $file2
16015         local rc=$?
16016         wait $DD_PID
16017         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16018         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16019
16020         # how many bytes copied before swapping layout
16021         local copied=$(stat -c %s $file2)
16022         local remaining=$(stat -c %s $ref1)
16023         remaining=$((remaining - copied))
16024         echo "Copied $copied bytes before swapping layout..."
16025
16026         cmp -n $copied $file1 $ref2 | grep differ &&
16027                 error "Content mismatch [0, $copied) of ref2 and file1"
16028         cmp -n $copied $file2 $ref1 ||
16029                 error "Content mismatch [0, $copied) of ref1 and file2"
16030         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16031                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16032
16033         # clean up
16034         rm -f $ref1 $ref2 $file1 $file2
16035 }
16036 run_test 184c "Concurrent write and layout swap"
16037
16038 test_184d() {
16039         check_swap_layouts_support
16040         check_swap_layout_no_dom $DIR
16041         [ -z "$(which getfattr 2>/dev/null)" ] &&
16042                 skip_env "no getfattr command"
16043
16044         local file1=$DIR/$tdir/$tfile-1
16045         local file2=$DIR/$tdir/$tfile-2
16046         local file3=$DIR/$tdir/$tfile-3
16047         local lovea1
16048         local lovea2
16049
16050         mkdir -p $DIR/$tdir
16051         touch $file1 || error "create $file1 failed"
16052         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16053                 error "create $file2 failed"
16054         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16055                 error "create $file3 failed"
16056         lovea1=$(get_layout_param $file1)
16057
16058         $LFS swap_layouts $file2 $file3 ||
16059                 error "swap $file2 $file3 layouts failed"
16060         $LFS swap_layouts $file1 $file2 ||
16061                 error "swap $file1 $file2 layouts failed"
16062
16063         lovea2=$(get_layout_param $file2)
16064         echo "$lovea1"
16065         echo "$lovea2"
16066         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16067
16068         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16069         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16070 }
16071 run_test 184d "allow stripeless layouts swap"
16072
16073 test_184e() {
16074         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16075                 skip "Need MDS version at least 2.6.94"
16076         check_swap_layouts_support
16077         check_swap_layout_no_dom $DIR
16078         [ -z "$(which getfattr 2>/dev/null)" ] &&
16079                 skip_env "no getfattr command"
16080
16081         local file1=$DIR/$tdir/$tfile-1
16082         local file2=$DIR/$tdir/$tfile-2
16083         local file3=$DIR/$tdir/$tfile-3
16084         local lovea
16085
16086         mkdir -p $DIR/$tdir
16087         touch $file1 || error "create $file1 failed"
16088         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16089                 error "create $file2 failed"
16090         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16091                 error "create $file3 failed"
16092
16093         $LFS swap_layouts $file1 $file2 ||
16094                 error "swap $file1 $file2 layouts failed"
16095
16096         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16097         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16098
16099         echo 123 > $file1 || error "Should be able to write into $file1"
16100
16101         $LFS swap_layouts $file1 $file3 ||
16102                 error "swap $file1 $file3 layouts failed"
16103
16104         echo 123 > $file1 || error "Should be able to write into $file1"
16105
16106         rm -rf $file1 $file2 $file3
16107 }
16108 run_test 184e "Recreate layout after stripeless layout swaps"
16109
16110 test_184f() {
16111         # Create a file with name longer than sizeof(struct stat) ==
16112         # 144 to see if we can get chars from the file name to appear
16113         # in the returned striping. Note that 'f' == 0x66.
16114         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16115
16116         mkdir -p $DIR/$tdir
16117         mcreate $DIR/$tdir/$file
16118         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16119                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16120         fi
16121 }
16122 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16123
16124 test_185() { # LU-2441
16125         # LU-3553 - no volatile file support in old servers
16126         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16127                 skip "Need MDS version at least 2.3.60"
16128
16129         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16130         touch $DIR/$tdir/spoo
16131         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16132         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16133                 error "cannot create/write a volatile file"
16134         [ "$FILESET" == "" ] &&
16135         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16136                 error "FID is still valid after close"
16137
16138         multiop_bg_pause $DIR/$tdir vVw4096_c
16139         local multi_pid=$!
16140
16141         local OLD_IFS=$IFS
16142         IFS=":"
16143         local fidv=($fid)
16144         IFS=$OLD_IFS
16145         # assume that the next FID for this client is sequential, since stdout
16146         # is unfortunately eaten by multiop_bg_pause
16147         local n=$((${fidv[1]} + 1))
16148         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16149         if [ "$FILESET" == "" ]; then
16150                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16151                         error "FID is missing before close"
16152         fi
16153         kill -USR1 $multi_pid
16154         # 1 second delay, so if mtime change we will see it
16155         sleep 1
16156         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16157         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16158 }
16159 run_test 185 "Volatile file support"
16160
16161 function create_check_volatile() {
16162         local idx=$1
16163         local tgt
16164
16165         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16166         local PID=$!
16167         sleep 1
16168         local FID=$(cat /tmp/${tfile}.fid)
16169         [ "$FID" == "" ] && error "can't get FID for volatile"
16170         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16171         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16172         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16173         kill -USR1 $PID
16174         wait
16175         sleep 1
16176         cancel_lru_locks mdc # flush opencache
16177         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16178         return 0
16179 }
16180
16181 test_185a(){
16182         # LU-12516 - volatile creation via .lustre
16183         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16184                 skip "Need MDS version at least 2.3.55"
16185
16186         create_check_volatile 0
16187         [ $MDSCOUNT -lt 2 ] && return 0
16188
16189         # DNE case
16190         create_check_volatile 1
16191
16192         return 0
16193 }
16194 run_test 185a "Volatile file creation in .lustre/fid/"
16195
16196 test_187a() {
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         local file=$dir0/file1
16205         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16206         local dv1=$($LFS data_version $file)
16207         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16208         local dv2=$($LFS data_version $file)
16209         [[ $dv1 != $dv2 ]] ||
16210                 error "data version did not change on write $dv1 == $dv2"
16211
16212         # clean up
16213         rm -f $file1
16214 }
16215 run_test 187a "Test data version change"
16216
16217 test_187b() {
16218         remote_mds_nodsh && skip "remote MDS with nodsh"
16219         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16220                 skip "Need MDS version at least 2.3.0"
16221
16222         local dir0=$DIR/$tdir/$testnum
16223         mkdir -p $dir0 || error "creating dir $dir0"
16224
16225         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16226         [[ ${DV[0]} != ${DV[1]} ]] ||
16227                 error "data version did not change on write"\
16228                       " ${DV[0]} == ${DV[1]}"
16229
16230         # clean up
16231         rm -f $file1
16232 }
16233 run_test 187b "Test data version change on volatile file"
16234
16235 test_200() {
16236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16237         remote_mgs_nodsh && skip "remote MGS with nodsh"
16238         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16239
16240         local POOL=${POOL:-cea1}
16241         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16242         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16243         # Pool OST targets
16244         local first_ost=0
16245         local last_ost=$(($OSTCOUNT - 1))
16246         local ost_step=2
16247         local ost_list=$(seq $first_ost $ost_step $last_ost)
16248         local ost_range="$first_ost $last_ost $ost_step"
16249         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16250         local file_dir=$POOL_ROOT/file_tst
16251         local subdir=$test_path/subdir
16252         local rc=0
16253
16254         while : ; do
16255                 # former test_200a test_200b
16256                 pool_add $POOL                          || { rc=$? ; break; }
16257                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16258                 # former test_200c test_200d
16259                 mkdir -p $test_path
16260                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16261                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16262                 mkdir -p $subdir
16263                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16264                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16265                                                         || { rc=$? ; break; }
16266                 # former test_200e test_200f
16267                 local files=$((OSTCOUNT*3))
16268                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16269                                                         || { rc=$? ; break; }
16270                 pool_create_files $POOL $file_dir $files "$ost_list" \
16271                                                         || { rc=$? ; break; }
16272                 # former test_200g test_200h
16273                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16274                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16275
16276                 # former test_201a test_201b test_201c
16277                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16278
16279                 local f=$test_path/$tfile
16280                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16281                 pool_remove $POOL $f                    || { rc=$? ; break; }
16282                 break
16283         done
16284
16285         destroy_test_pools
16286
16287         return $rc
16288 }
16289 run_test 200 "OST pools"
16290
16291 # usage: default_attr <count | size | offset>
16292 default_attr() {
16293         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16294 }
16295
16296 # usage: check_default_stripe_attr
16297 check_default_stripe_attr() {
16298         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16299         case $1 in
16300         --stripe-count|-c)
16301                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16302         --stripe-size|-S)
16303                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16304         --stripe-index|-i)
16305                 EXPECTED=-1;;
16306         *)
16307                 error "unknown getstripe attr '$1'"
16308         esac
16309
16310         [ $ACTUAL == $EXPECTED ] ||
16311                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16312 }
16313
16314 test_204a() {
16315         test_mkdir $DIR/$tdir
16316         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16317
16318         check_default_stripe_attr --stripe-count
16319         check_default_stripe_attr --stripe-size
16320         check_default_stripe_attr --stripe-index
16321 }
16322 run_test 204a "Print default stripe attributes"
16323
16324 test_204b() {
16325         test_mkdir $DIR/$tdir
16326         $LFS setstripe --stripe-count 1 $DIR/$tdir
16327
16328         check_default_stripe_attr --stripe-size
16329         check_default_stripe_attr --stripe-index
16330 }
16331 run_test 204b "Print default stripe size and offset"
16332
16333 test_204c() {
16334         test_mkdir $DIR/$tdir
16335         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16336
16337         check_default_stripe_attr --stripe-count
16338         check_default_stripe_attr --stripe-index
16339 }
16340 run_test 204c "Print default stripe count and offset"
16341
16342 test_204d() {
16343         test_mkdir $DIR/$tdir
16344         $LFS setstripe --stripe-index 0 $DIR/$tdir
16345
16346         check_default_stripe_attr --stripe-count
16347         check_default_stripe_attr --stripe-size
16348 }
16349 run_test 204d "Print default stripe count and size"
16350
16351 test_204e() {
16352         test_mkdir $DIR/$tdir
16353         $LFS setstripe -d $DIR/$tdir
16354
16355         check_default_stripe_attr --stripe-count --raw
16356         check_default_stripe_attr --stripe-size --raw
16357         check_default_stripe_attr --stripe-index --raw
16358 }
16359 run_test 204e "Print raw stripe attributes"
16360
16361 test_204f() {
16362         test_mkdir $DIR/$tdir
16363         $LFS setstripe --stripe-count 1 $DIR/$tdir
16364
16365         check_default_stripe_attr --stripe-size --raw
16366         check_default_stripe_attr --stripe-index --raw
16367 }
16368 run_test 204f "Print raw stripe size and offset"
16369
16370 test_204g() {
16371         test_mkdir $DIR/$tdir
16372         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16373
16374         check_default_stripe_attr --stripe-count --raw
16375         check_default_stripe_attr --stripe-index --raw
16376 }
16377 run_test 204g "Print raw stripe count and offset"
16378
16379 test_204h() {
16380         test_mkdir $DIR/$tdir
16381         $LFS setstripe --stripe-index 0 $DIR/$tdir
16382
16383         check_default_stripe_attr --stripe-count --raw
16384         check_default_stripe_attr --stripe-size --raw
16385 }
16386 run_test 204h "Print raw stripe count and size"
16387
16388 # Figure out which job scheduler is being used, if any,
16389 # or use a fake one
16390 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16391         JOBENV=SLURM_JOB_ID
16392 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16393         JOBENV=LSB_JOBID
16394 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16395         JOBENV=PBS_JOBID
16396 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16397         JOBENV=LOADL_STEP_ID
16398 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16399         JOBENV=JOB_ID
16400 else
16401         $LCTL list_param jobid_name > /dev/null 2>&1
16402         if [ $? -eq 0 ]; then
16403                 JOBENV=nodelocal
16404         else
16405                 JOBENV=FAKE_JOBID
16406         fi
16407 fi
16408 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16409
16410 verify_jobstats() {
16411         local cmd=($1)
16412         shift
16413         local facets="$@"
16414
16415 # we don't really need to clear the stats for this test to work, since each
16416 # command has a unique jobid, but it makes debugging easier if needed.
16417 #       for facet in $facets; do
16418 #               local dev=$(convert_facet2label $facet)
16419 #               # clear old jobstats
16420 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16421 #       done
16422
16423         # use a new JobID for each test, or we might see an old one
16424         [ "$JOBENV" = "FAKE_JOBID" ] &&
16425                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16426
16427         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16428
16429         [ "$JOBENV" = "nodelocal" ] && {
16430                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16431                 $LCTL set_param jobid_name=$FAKE_JOBID
16432                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16433         }
16434
16435         log "Test: ${cmd[*]}"
16436         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16437
16438         if [ $JOBENV = "FAKE_JOBID" ]; then
16439                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16440         else
16441                 ${cmd[*]}
16442         fi
16443
16444         # all files are created on OST0000
16445         for facet in $facets; do
16446                 local stats="*.$(convert_facet2label $facet).job_stats"
16447
16448                 # strip out libtool wrappers for in-tree executables
16449                 if [ $(do_facet $facet lctl get_param $stats |
16450                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16451                         do_facet $facet lctl get_param $stats
16452                         error "No jobstats for $JOBVAL found on $facet::$stats"
16453                 fi
16454         done
16455 }
16456
16457 jobstats_set() {
16458         local new_jobenv=$1
16459
16460         set_persistent_param_and_check client "jobid_var" \
16461                 "$FSNAME.sys.jobid_var" $new_jobenv
16462 }
16463
16464 test_205a() { # Job stats
16465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16466         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16467                 skip "Need MDS version with at least 2.7.1"
16468         remote_mgs_nodsh && skip "remote MGS with nodsh"
16469         remote_mds_nodsh && skip "remote MDS with nodsh"
16470         remote_ost_nodsh && skip "remote OST with nodsh"
16471         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16472                 skip "Server doesn't support jobstats"
16473         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16474
16475         local old_jobenv=$($LCTL get_param -n jobid_var)
16476         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16477
16478         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16479                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16480         else
16481                 stack_trap "do_facet mgs $PERM_CMD \
16482                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16483         fi
16484         changelog_register
16485
16486         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16487                                 mdt.*.job_cleanup_interval | head -n 1)
16488         local new_interval=5
16489         do_facet $SINGLEMDS \
16490                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16491         stack_trap "do_facet $SINGLEMDS \
16492                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16493         local start=$SECONDS
16494
16495         local cmd
16496         # mkdir
16497         cmd="mkdir $DIR/$tdir"
16498         verify_jobstats "$cmd" "$SINGLEMDS"
16499         # rmdir
16500         cmd="rmdir $DIR/$tdir"
16501         verify_jobstats "$cmd" "$SINGLEMDS"
16502         # mkdir on secondary MDT
16503         if [ $MDSCOUNT -gt 1 ]; then
16504                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16505                 verify_jobstats "$cmd" "mds2"
16506         fi
16507         # mknod
16508         cmd="mknod $DIR/$tfile c 1 3"
16509         verify_jobstats "$cmd" "$SINGLEMDS"
16510         # unlink
16511         cmd="rm -f $DIR/$tfile"
16512         verify_jobstats "$cmd" "$SINGLEMDS"
16513         # create all files on OST0000 so verify_jobstats can find OST stats
16514         # open & close
16515         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16516         verify_jobstats "$cmd" "$SINGLEMDS"
16517         # setattr
16518         cmd="touch $DIR/$tfile"
16519         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16520         # write
16521         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16522         verify_jobstats "$cmd" "ost1"
16523         # read
16524         cancel_lru_locks osc
16525         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16526         verify_jobstats "$cmd" "ost1"
16527         # truncate
16528         cmd="$TRUNCATE $DIR/$tfile 0"
16529         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16530         # rename
16531         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16532         verify_jobstats "$cmd" "$SINGLEMDS"
16533         # jobstats expiry - sleep until old stats should be expired
16534         local left=$((new_interval + 5 - (SECONDS - start)))
16535         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16536                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16537                         "0" $left
16538         cmd="mkdir $DIR/$tdir.expire"
16539         verify_jobstats "$cmd" "$SINGLEMDS"
16540         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16541             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16542
16543         # Ensure that jobid are present in changelog (if supported by MDS)
16544         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16545                 changelog_dump | tail -10
16546                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16547                 [ $jobids -eq 9 ] ||
16548                         error "Wrong changelog jobid count $jobids != 9"
16549
16550                 # LU-5862
16551                 JOBENV="disable"
16552                 jobstats_set $JOBENV
16553                 touch $DIR/$tfile
16554                 changelog_dump | grep $tfile
16555                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16556                 [ $jobids -eq 0 ] ||
16557                         error "Unexpected jobids when jobid_var=$JOBENV"
16558         fi
16559
16560         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
16561         JOBENV="JOBCOMPLEX"
16562         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16563
16564         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16565 }
16566 run_test 205a "Verify job stats"
16567
16568 # LU-13117, LU-13597
16569 test_205b() {
16570         job_stats="mdt.*.job_stats"
16571         $LCTL set_param $job_stats=clear
16572         $LCTL set_param jobid_var=USER jobid_name="%e.%u"
16573         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16574         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16575                 grep "job_id:.*foolish" &&
16576                         error "Unexpected jobid found"
16577         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16578                 grep "open:.*min.*max.*sum" ||
16579                         error "wrong job_stats format found"
16580 }
16581 run_test 205b "Verify job stats jobid and output format"
16582
16583 # LU-13733
16584 test_205c() {
16585         $LCTL set_param llite.*.stats=0
16586         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16587         $LCTL get_param llite.*.stats
16588         $LCTL get_param llite.*.stats | grep \
16589                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16590                         error "wrong client stats format found"
16591 }
16592 run_test 205c "Verify client stats format"
16593
16594 # LU-1480, LU-1773 and LU-1657
16595 test_206() {
16596         mkdir -p $DIR/$tdir
16597         $LFS setstripe -c -1 $DIR/$tdir
16598 #define OBD_FAIL_LOV_INIT 0x1403
16599         $LCTL set_param fail_loc=0xa0001403
16600         $LCTL set_param fail_val=1
16601         touch $DIR/$tdir/$tfile || true
16602 }
16603 run_test 206 "fail lov_init_raid0() doesn't lbug"
16604
16605 test_207a() {
16606         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16607         local fsz=`stat -c %s $DIR/$tfile`
16608         cancel_lru_locks mdc
16609
16610         # do not return layout in getattr intent
16611 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16612         $LCTL set_param fail_loc=0x170
16613         local sz=`stat -c %s $DIR/$tfile`
16614
16615         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16616
16617         rm -rf $DIR/$tfile
16618 }
16619 run_test 207a "can refresh layout at glimpse"
16620
16621 test_207b() {
16622         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16623         local cksum=`md5sum $DIR/$tfile`
16624         local fsz=`stat -c %s $DIR/$tfile`
16625         cancel_lru_locks mdc
16626         cancel_lru_locks osc
16627
16628         # do not return layout in getattr intent
16629 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16630         $LCTL set_param fail_loc=0x171
16631
16632         # it will refresh layout after the file is opened but before read issues
16633         echo checksum is "$cksum"
16634         echo "$cksum" |md5sum -c --quiet || error "file differs"
16635
16636         rm -rf $DIR/$tfile
16637 }
16638 run_test 207b "can refresh layout at open"
16639
16640 test_208() {
16641         # FIXME: in this test suite, only RD lease is used. This is okay
16642         # for now as only exclusive open is supported. After generic lease
16643         # is done, this test suite should be revised. - Jinshan
16644
16645         remote_mds_nodsh && skip "remote MDS with nodsh"
16646         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16647                 skip "Need MDS version at least 2.4.52"
16648
16649         echo "==== test 1: verify get lease work"
16650         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16651
16652         echo "==== test 2: verify lease can be broken by upcoming open"
16653         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16654         local PID=$!
16655         sleep 1
16656
16657         $MULTIOP $DIR/$tfile oO_RDONLY:c
16658         kill -USR1 $PID && wait $PID || error "break lease error"
16659
16660         echo "==== test 3: verify lease can't be granted if an open already exists"
16661         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16662         local PID=$!
16663         sleep 1
16664
16665         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16666         kill -USR1 $PID && wait $PID || error "open file error"
16667
16668         echo "==== test 4: lease can sustain over recovery"
16669         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16670         PID=$!
16671         sleep 1
16672
16673         fail mds1
16674
16675         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16676
16677         echo "==== test 5: lease broken can't be regained by replay"
16678         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16679         PID=$!
16680         sleep 1
16681
16682         # open file to break lease and then recovery
16683         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16684         fail mds1
16685
16686         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16687
16688         rm -f $DIR/$tfile
16689 }
16690 run_test 208 "Exclusive open"
16691
16692 test_209() {
16693         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16694                 skip_env "must have disp_stripe"
16695
16696         touch $DIR/$tfile
16697         sync; sleep 5; sync;
16698
16699         echo 3 > /proc/sys/vm/drop_caches
16700         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16701                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16702         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16703
16704         # open/close 500 times
16705         for i in $(seq 500); do
16706                 cat $DIR/$tfile
16707         done
16708
16709         echo 3 > /proc/sys/vm/drop_caches
16710         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16711                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16712         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16713
16714         echo "before: $req_before, after: $req_after"
16715         [ $((req_after - req_before)) -ge 300 ] &&
16716                 error "open/close requests are not freed"
16717         return 0
16718 }
16719 run_test 209 "read-only open/close requests should be freed promptly"
16720
16721 test_210() {
16722         local pid
16723
16724         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16725         pid=$!
16726         sleep 1
16727
16728         $LFS getstripe $DIR/$tfile
16729         kill -USR1 $pid
16730         wait $pid || error "multiop failed"
16731
16732         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16733         pid=$!
16734         sleep 1
16735
16736         $LFS getstripe $DIR/$tfile
16737         kill -USR1 $pid
16738         wait $pid || error "multiop failed"
16739 }
16740 run_test 210 "lfs getstripe does not break leases"
16741
16742 test_212() {
16743         size=`date +%s`
16744         size=$((size % 8192 + 1))
16745         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16746         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16747         rm -f $DIR/f212 $DIR/f212.xyz
16748 }
16749 run_test 212 "Sendfile test ============================================"
16750
16751 test_213() {
16752         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16753         cancel_lru_locks osc
16754         lctl set_param fail_loc=0x8000040f
16755         # generate a read lock
16756         cat $DIR/$tfile > /dev/null
16757         # write to the file, it will try to cancel the above read lock.
16758         cat /etc/hosts >> $DIR/$tfile
16759 }
16760 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16761
16762 test_214() { # for bug 20133
16763         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16764         for (( i=0; i < 340; i++ )) ; do
16765                 touch $DIR/$tdir/d214c/a$i
16766         done
16767
16768         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16769         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16770         ls $DIR/d214c || error "ls $DIR/d214c failed"
16771         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16772         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16773 }
16774 run_test 214 "hash-indexed directory test - bug 20133"
16775
16776 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16777 create_lnet_proc_files() {
16778         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16779 }
16780
16781 # counterpart of create_lnet_proc_files
16782 remove_lnet_proc_files() {
16783         rm -f $TMP/lnet_$1.sys
16784 }
16785
16786 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16787 # 3rd arg as regexp for body
16788 check_lnet_proc_stats() {
16789         local l=$(cat "$TMP/lnet_$1" |wc -l)
16790         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16791
16792         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16793 }
16794
16795 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16796 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16797 # optional and can be regexp for 2nd line (lnet.routes case)
16798 check_lnet_proc_entry() {
16799         local blp=2          # blp stands for 'position of 1st line of body'
16800         [ -z "$5" ] || blp=3 # lnet.routes case
16801
16802         local l=$(cat "$TMP/lnet_$1" |wc -l)
16803         # subtracting one from $blp because the body can be empty
16804         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16805
16806         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16807                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16808
16809         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16810                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16811
16812         # bail out if any unexpected line happened
16813         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16814         [ "$?" != 0 ] || error "$2 misformatted"
16815 }
16816
16817 test_215() { # for bugs 18102, 21079, 21517
16818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16819
16820         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16821         local P='[1-9][0-9]*'           # positive numeric
16822         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16823         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16824         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16825         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16826
16827         local L1 # regexp for 1st line
16828         local L2 # regexp for 2nd line (optional)
16829         local BR # regexp for the rest (body)
16830
16831         # lnet.stats should look as 11 space-separated non-negative numerics
16832         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16833         create_lnet_proc_files "stats"
16834         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16835         remove_lnet_proc_files "stats"
16836
16837         # lnet.routes should look like this:
16838         # Routing disabled/enabled
16839         # net hops priority state router
16840         # where net is a string like tcp0, hops > 0, priority >= 0,
16841         # state is up/down,
16842         # router is a string like 192.168.1.1@tcp2
16843         L1="^Routing (disabled|enabled)$"
16844         L2="^net +hops +priority +state +router$"
16845         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16846         create_lnet_proc_files "routes"
16847         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16848         remove_lnet_proc_files "routes"
16849
16850         # lnet.routers should look like this:
16851         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16852         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16853         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16854         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16855         L1="^ref +rtr_ref +alive +router$"
16856         BR="^$P +$P +(up|down) +$NID$"
16857         create_lnet_proc_files "routers"
16858         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16859         remove_lnet_proc_files "routers"
16860
16861         # lnet.peers should look like this:
16862         # nid refs state last max rtr min tx min queue
16863         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16864         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16865         # numeric (0 or >0 or <0), queue >= 0.
16866         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16867         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16868         create_lnet_proc_files "peers"
16869         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16870         remove_lnet_proc_files "peers"
16871
16872         # lnet.buffers  should look like this:
16873         # pages count credits min
16874         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16875         L1="^pages +count +credits +min$"
16876         BR="^ +$N +$N +$I +$I$"
16877         create_lnet_proc_files "buffers"
16878         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16879         remove_lnet_proc_files "buffers"
16880
16881         # lnet.nis should look like this:
16882         # nid status alive refs peer rtr max tx min
16883         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16884         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16885         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16886         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16887         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16888         create_lnet_proc_files "nis"
16889         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16890         remove_lnet_proc_files "nis"
16891
16892         # can we successfully write to lnet.stats?
16893         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
16894 }
16895 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
16896
16897 test_216() { # bug 20317
16898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16899         remote_ost_nodsh && skip "remote OST with nodsh"
16900
16901         local node
16902         local facets=$(get_facets OST)
16903         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16904
16905         save_lustre_params client "osc.*.contention_seconds" > $p
16906         save_lustre_params $facets \
16907                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
16908         save_lustre_params $facets \
16909                 "ldlm.namespaces.filter-*.contended_locks" >> $p
16910         save_lustre_params $facets \
16911                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
16912         clear_stats osc.*.osc_stats
16913
16914         # agressive lockless i/o settings
16915         do_nodes $(comma_list $(osts_nodes)) \
16916                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
16917                         ldlm.namespaces.filter-*.contended_locks=0 \
16918                         ldlm.namespaces.filter-*.contention_seconds=60"
16919         lctl set_param -n osc.*.contention_seconds=60
16920
16921         $DIRECTIO write $DIR/$tfile 0 10 4096
16922         $CHECKSTAT -s 40960 $DIR/$tfile
16923
16924         # disable lockless i/o
16925         do_nodes $(comma_list $(osts_nodes)) \
16926                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
16927                         ldlm.namespaces.filter-*.contended_locks=32 \
16928                         ldlm.namespaces.filter-*.contention_seconds=0"
16929         lctl set_param -n osc.*.contention_seconds=0
16930         clear_stats osc.*.osc_stats
16931
16932         dd if=/dev/zero of=$DIR/$tfile count=0
16933         $CHECKSTAT -s 0 $DIR/$tfile
16934
16935         restore_lustre_params <$p
16936         rm -f $p
16937         rm $DIR/$tfile
16938 }
16939 run_test 216 "check lockless direct write updates file size and kms correctly"
16940
16941 test_217() { # bug 22430
16942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16943
16944         local node
16945         local nid
16946
16947         for node in $(nodes_list); do
16948                 nid=$(host_nids_address $node $NETTYPE)
16949                 if [[ $nid = *-* ]] ; then
16950                         echo "lctl ping $(h2nettype $nid)"
16951                         lctl ping $(h2nettype $nid)
16952                 else
16953                         echo "skipping $node (no hyphen detected)"
16954                 fi
16955         done
16956 }
16957 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
16958
16959 test_218() {
16960        # do directio so as not to populate the page cache
16961        log "creating a 10 Mb file"
16962        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
16963        log "starting reads"
16964        dd if=$DIR/$tfile of=/dev/null bs=4096 &
16965        log "truncating the file"
16966        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
16967        log "killing dd"
16968        kill %+ || true # reads might have finished
16969        echo "wait until dd is finished"
16970        wait
16971        log "removing the temporary file"
16972        rm -rf $DIR/$tfile || error "tmp file removal failed"
16973 }
16974 run_test 218 "parallel read and truncate should not deadlock"
16975
16976 test_219() {
16977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16978
16979         # write one partial page
16980         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
16981         # set no grant so vvp_io_commit_write will do sync write
16982         $LCTL set_param fail_loc=0x411
16983         # write a full page at the end of file
16984         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
16985
16986         $LCTL set_param fail_loc=0
16987         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
16988         $LCTL set_param fail_loc=0x411
16989         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
16990
16991         # LU-4201
16992         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
16993         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
16994 }
16995 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
16996
16997 test_220() { #LU-325
16998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16999         remote_ost_nodsh && skip "remote OST with nodsh"
17000         remote_mds_nodsh && skip "remote MDS with nodsh"
17001         remote_mgs_nodsh && skip "remote MGS with nodsh"
17002
17003         local OSTIDX=0
17004
17005         # create on MDT0000 so the last_id and next_id are correct
17006         mkdir $DIR/$tdir
17007         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17008         OST=${OST%_UUID}
17009
17010         # on the mdt's osc
17011         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17012         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17013                         osp.$mdtosc_proc1.prealloc_last_id)
17014         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17015                         osp.$mdtosc_proc1.prealloc_next_id)
17016
17017         $LFS df -i
17018
17019         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17020         #define OBD_FAIL_OST_ENOINO              0x229
17021         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17022         create_pool $FSNAME.$TESTNAME || return 1
17023         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17024
17025         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17026
17027         MDSOBJS=$((last_id - next_id))
17028         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17029
17030         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17031         echo "OST still has $count kbytes free"
17032
17033         echo "create $MDSOBJS files @next_id..."
17034         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17035
17036         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17037                         osp.$mdtosc_proc1.prealloc_last_id)
17038         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17039                         osp.$mdtosc_proc1.prealloc_next_id)
17040
17041         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17042         $LFS df -i
17043
17044         echo "cleanup..."
17045
17046         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17047         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17048
17049         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17050                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17051         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17052                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17053         echo "unlink $MDSOBJS files @$next_id..."
17054         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17055 }
17056 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17057
17058 test_221() {
17059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17060
17061         dd if=`which date` of=$MOUNT/date oflag=sync
17062         chmod +x $MOUNT/date
17063
17064         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17065         $LCTL set_param fail_loc=0x80001401
17066
17067         $MOUNT/date > /dev/null
17068         rm -f $MOUNT/date
17069 }
17070 run_test 221 "make sure fault and truncate race to not cause OOM"
17071
17072 test_222a () {
17073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17074
17075         rm -rf $DIR/$tdir
17076         test_mkdir $DIR/$tdir
17077         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17078         createmany -o $DIR/$tdir/$tfile 10
17079         cancel_lru_locks mdc
17080         cancel_lru_locks osc
17081         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17082         $LCTL set_param fail_loc=0x31a
17083         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17084         $LCTL set_param fail_loc=0
17085         rm -r $DIR/$tdir
17086 }
17087 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17088
17089 test_222b () {
17090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17091
17092         rm -rf $DIR/$tdir
17093         test_mkdir $DIR/$tdir
17094         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17095         createmany -o $DIR/$tdir/$tfile 10
17096         cancel_lru_locks mdc
17097         cancel_lru_locks osc
17098         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17099         $LCTL set_param fail_loc=0x31a
17100         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17101         $LCTL set_param fail_loc=0
17102 }
17103 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17104
17105 test_223 () {
17106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17107
17108         rm -rf $DIR/$tdir
17109         test_mkdir $DIR/$tdir
17110         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17111         createmany -o $DIR/$tdir/$tfile 10
17112         cancel_lru_locks mdc
17113         cancel_lru_locks osc
17114         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17115         $LCTL set_param fail_loc=0x31b
17116         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17117         $LCTL set_param fail_loc=0
17118         rm -r $DIR/$tdir
17119 }
17120 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17121
17122 test_224a() { # LU-1039, MRP-303
17123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17124
17125         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17126         $LCTL set_param fail_loc=0x508
17127         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17128         $LCTL set_param fail_loc=0
17129         df $DIR
17130 }
17131 run_test 224a "Don't panic on bulk IO failure"
17132
17133 test_224b() { # LU-1039, MRP-303
17134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17135
17136         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17137         cancel_lru_locks osc
17138         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17139         $LCTL set_param fail_loc=0x515
17140         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17141         $LCTL set_param fail_loc=0
17142         df $DIR
17143 }
17144 run_test 224b "Don't panic on bulk IO failure"
17145
17146 test_224c() { # LU-6441
17147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17148         remote_mds_nodsh && skip "remote MDS with nodsh"
17149
17150         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17151         save_writethrough $p
17152         set_cache writethrough on
17153
17154         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17155         local at_max=$($LCTL get_param -n at_max)
17156         local timeout=$($LCTL get_param -n timeout)
17157         local test_at="at_max"
17158         local param_at="$FSNAME.sys.at_max"
17159         local test_timeout="timeout"
17160         local param_timeout="$FSNAME.sys.timeout"
17161
17162         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17163
17164         set_persistent_param_and_check client "$test_at" "$param_at" 0
17165         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17166
17167         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17168         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17169         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17170         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17171         sync
17172         do_facet ost1 "$LCTL set_param fail_loc=0"
17173
17174         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17175         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17176                 $timeout
17177
17178         $LCTL set_param -n $pages_per_rpc
17179         restore_lustre_params < $p
17180         rm -f $p
17181 }
17182 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17183
17184 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17185 test_225a () {
17186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17187         if [ -z ${MDSSURVEY} ]; then
17188                 skip_env "mds-survey not found"
17189         fi
17190         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17191                 skip "Need MDS version at least 2.2.51"
17192
17193         local mds=$(facet_host $SINGLEMDS)
17194         local target=$(do_nodes $mds 'lctl dl' |
17195                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17196
17197         local cmd1="file_count=1000 thrhi=4"
17198         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17199         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17200         local cmd="$cmd1 $cmd2 $cmd3"
17201
17202         rm -f ${TMP}/mds_survey*
17203         echo + $cmd
17204         eval $cmd || error "mds-survey with zero-stripe failed"
17205         cat ${TMP}/mds_survey*
17206         rm -f ${TMP}/mds_survey*
17207 }
17208 run_test 225a "Metadata survey sanity with zero-stripe"
17209
17210 test_225b () {
17211         if [ -z ${MDSSURVEY} ]; then
17212                 skip_env "mds-survey not found"
17213         fi
17214         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17215                 skip "Need MDS version at least 2.2.51"
17216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17217         remote_mds_nodsh && skip "remote MDS with nodsh"
17218         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17219                 skip_env "Need to mount OST to test"
17220         fi
17221
17222         local mds=$(facet_host $SINGLEMDS)
17223         local target=$(do_nodes $mds 'lctl dl' |
17224                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17225
17226         local cmd1="file_count=1000 thrhi=4"
17227         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17228         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17229         local cmd="$cmd1 $cmd2 $cmd3"
17230
17231         rm -f ${TMP}/mds_survey*
17232         echo + $cmd
17233         eval $cmd || error "mds-survey with stripe_count failed"
17234         cat ${TMP}/mds_survey*
17235         rm -f ${TMP}/mds_survey*
17236 }
17237 run_test 225b "Metadata survey sanity with stripe_count = 1"
17238
17239 mcreate_path2fid () {
17240         local mode=$1
17241         local major=$2
17242         local minor=$3
17243         local name=$4
17244         local desc=$5
17245         local path=$DIR/$tdir/$name
17246         local fid
17247         local rc
17248         local fid_path
17249
17250         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17251                 error "cannot create $desc"
17252
17253         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17254         rc=$?
17255         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17256
17257         fid_path=$($LFS fid2path $MOUNT $fid)
17258         rc=$?
17259         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17260
17261         [ "$path" == "$fid_path" ] ||
17262                 error "fid2path returned $fid_path, expected $path"
17263
17264         echo "pass with $path and $fid"
17265 }
17266
17267 test_226a () {
17268         rm -rf $DIR/$tdir
17269         mkdir -p $DIR/$tdir
17270
17271         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17272         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17273         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17274         mcreate_path2fid 0040666 0 0 dir "directory"
17275         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17276         mcreate_path2fid 0100666 0 0 file "regular file"
17277         mcreate_path2fid 0120666 0 0 link "symbolic link"
17278         mcreate_path2fid 0140666 0 0 sock "socket"
17279 }
17280 run_test 226a "call path2fid and fid2path on files of all type"
17281
17282 test_226b () {
17283         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17284
17285         local MDTIDX=1
17286
17287         rm -rf $DIR/$tdir
17288         mkdir -p $DIR/$tdir
17289         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17290                 error "create remote directory failed"
17291         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17292         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17293                                 "character special file (null)"
17294         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17295                                 "character special file (no device)"
17296         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17297         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17298                                 "block special file (loop)"
17299         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17300         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17301         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17302 }
17303 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17304
17305 test_226c () {
17306         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17307         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17308                 skip "Need MDS version at least 2.13.55"
17309
17310         local submnt=/mnt/submnt
17311         local srcfile=/etc/passwd
17312         local dstfile=$submnt/passwd
17313         local path
17314         local fid
17315
17316         rm -rf $DIR/$tdir
17317         rm -rf $submnt
17318         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17319                 error "create remote directory failed"
17320         mkdir -p $submnt || error "create $submnt failed"
17321         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17322                 error "mount $submnt failed"
17323         stack_trap "umount $submnt" EXIT
17324
17325         cp $srcfile $dstfile
17326         fid=$($LFS path2fid $dstfile)
17327         path=$($LFS fid2path $submnt "$fid")
17328         [ "$path" = "$dstfile" ] ||
17329                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17330 }
17331 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17332
17333 # LU-1299 Executing or running ldd on a truncated executable does not
17334 # cause an out-of-memory condition.
17335 test_227() {
17336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17337         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17338
17339         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17340         chmod +x $MOUNT/date
17341
17342         $MOUNT/date > /dev/null
17343         ldd $MOUNT/date > /dev/null
17344         rm -f $MOUNT/date
17345 }
17346 run_test 227 "running truncated executable does not cause OOM"
17347
17348 # LU-1512 try to reuse idle OI blocks
17349 test_228a() {
17350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17351         remote_mds_nodsh && skip "remote MDS with nodsh"
17352         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17353
17354         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17355         local myDIR=$DIR/$tdir
17356
17357         mkdir -p $myDIR
17358         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17359         $LCTL set_param fail_loc=0x80001002
17360         createmany -o $myDIR/t- 10000
17361         $LCTL set_param fail_loc=0
17362         # The guard is current the largest FID holder
17363         touch $myDIR/guard
17364         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17365                     tr -d '[')
17366         local IDX=$(($SEQ % 64))
17367
17368         do_facet $SINGLEMDS sync
17369         # Make sure journal flushed.
17370         sleep 6
17371         local blk1=$(do_facet $SINGLEMDS \
17372                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17373                      grep Blockcount | awk '{print $4}')
17374
17375         # Remove old files, some OI blocks will become idle.
17376         unlinkmany $myDIR/t- 10000
17377         # Create new files, idle OI blocks should be reused.
17378         createmany -o $myDIR/t- 2000
17379         do_facet $SINGLEMDS sync
17380         # Make sure journal flushed.
17381         sleep 6
17382         local blk2=$(do_facet $SINGLEMDS \
17383                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17384                      grep Blockcount | awk '{print $4}')
17385
17386         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17387 }
17388 run_test 228a "try to reuse idle OI blocks"
17389
17390 test_228b() {
17391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17392         remote_mds_nodsh && skip "remote MDS with nodsh"
17393         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17394
17395         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17396         local myDIR=$DIR/$tdir
17397
17398         mkdir -p $myDIR
17399         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17400         $LCTL set_param fail_loc=0x80001002
17401         createmany -o $myDIR/t- 10000
17402         $LCTL set_param fail_loc=0
17403         # The guard is current the largest FID holder
17404         touch $myDIR/guard
17405         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17406                     tr -d '[')
17407         local IDX=$(($SEQ % 64))
17408
17409         do_facet $SINGLEMDS sync
17410         # Make sure journal flushed.
17411         sleep 6
17412         local blk1=$(do_facet $SINGLEMDS \
17413                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17414                      grep Blockcount | awk '{print $4}')
17415
17416         # Remove old files, some OI blocks will become idle.
17417         unlinkmany $myDIR/t- 10000
17418
17419         # stop the MDT
17420         stop $SINGLEMDS || error "Fail to stop MDT."
17421         # remount the MDT
17422         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17423
17424         df $MOUNT || error "Fail to df."
17425         # Create new files, idle OI blocks should be reused.
17426         createmany -o $myDIR/t- 2000
17427         do_facet $SINGLEMDS sync
17428         # Make sure journal flushed.
17429         sleep 6
17430         local blk2=$(do_facet $SINGLEMDS \
17431                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17432                      grep Blockcount | awk '{print $4}')
17433
17434         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17435 }
17436 run_test 228b "idle OI blocks can be reused after MDT restart"
17437
17438 #LU-1881
17439 test_228c() {
17440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17441         remote_mds_nodsh && skip "remote MDS with nodsh"
17442         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17443
17444         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17445         local myDIR=$DIR/$tdir
17446
17447         mkdir -p $myDIR
17448         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17449         $LCTL set_param fail_loc=0x80001002
17450         # 20000 files can guarantee there are index nodes in the OI file
17451         createmany -o $myDIR/t- 20000
17452         $LCTL set_param fail_loc=0
17453         # The guard is current the largest FID holder
17454         touch $myDIR/guard
17455         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17456                     tr -d '[')
17457         local IDX=$(($SEQ % 64))
17458
17459         do_facet $SINGLEMDS sync
17460         # Make sure journal flushed.
17461         sleep 6
17462         local blk1=$(do_facet $SINGLEMDS \
17463                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17464                      grep Blockcount | awk '{print $4}')
17465
17466         # Remove old files, some OI blocks will become idle.
17467         unlinkmany $myDIR/t- 20000
17468         rm -f $myDIR/guard
17469         # The OI file should become empty now
17470
17471         # Create new files, idle OI blocks should be reused.
17472         createmany -o $myDIR/t- 2000
17473         do_facet $SINGLEMDS sync
17474         # Make sure journal flushed.
17475         sleep 6
17476         local blk2=$(do_facet $SINGLEMDS \
17477                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17478                      grep Blockcount | awk '{print $4}')
17479
17480         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17481 }
17482 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17483
17484 test_229() { # LU-2482, LU-3448
17485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17486         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17487         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17488                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17489
17490         rm -f $DIR/$tfile
17491
17492         # Create a file with a released layout and stripe count 2.
17493         $MULTIOP $DIR/$tfile H2c ||
17494                 error "failed to create file with released layout"
17495
17496         $LFS getstripe -v $DIR/$tfile
17497
17498         local pattern=$($LFS getstripe -L $DIR/$tfile)
17499         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17500
17501         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17502                 error "getstripe"
17503         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17504         stat $DIR/$tfile || error "failed to stat released file"
17505
17506         chown $RUNAS_ID $DIR/$tfile ||
17507                 error "chown $RUNAS_ID $DIR/$tfile failed"
17508
17509         chgrp $RUNAS_ID $DIR/$tfile ||
17510                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17511
17512         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17513         rm $DIR/$tfile || error "failed to remove released file"
17514 }
17515 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17516
17517 test_230a() {
17518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17519         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17520         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17521                 skip "Need MDS version at least 2.11.52"
17522
17523         local MDTIDX=1
17524
17525         test_mkdir $DIR/$tdir
17526         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17527         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17528         [ $mdt_idx -ne 0 ] &&
17529                 error "create local directory on wrong MDT $mdt_idx"
17530
17531         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17532                         error "create remote directory failed"
17533         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17534         [ $mdt_idx -ne $MDTIDX ] &&
17535                 error "create remote directory on wrong MDT $mdt_idx"
17536
17537         createmany -o $DIR/$tdir/test_230/t- 10 ||
17538                 error "create files on remote directory failed"
17539         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17540         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17541         rm -r $DIR/$tdir || error "unlink remote directory failed"
17542 }
17543 run_test 230a "Create remote directory and files under the remote directory"
17544
17545 test_230b() {
17546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17547         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17548         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17549                 skip "Need MDS version at least 2.11.52"
17550
17551         local MDTIDX=1
17552         local mdt_index
17553         local i
17554         local file
17555         local pid
17556         local stripe_count
17557         local migrate_dir=$DIR/$tdir/migrate_dir
17558         local other_dir=$DIR/$tdir/other_dir
17559
17560         test_mkdir $DIR/$tdir
17561         test_mkdir -i0 -c1 $migrate_dir
17562         test_mkdir -i0 -c1 $other_dir
17563         for ((i=0; i<10; i++)); do
17564                 mkdir -p $migrate_dir/dir_${i}
17565                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17566                         error "create files under remote dir failed $i"
17567         done
17568
17569         cp /etc/passwd $migrate_dir/$tfile
17570         cp /etc/passwd $other_dir/$tfile
17571         chattr +SAD $migrate_dir
17572         chattr +SAD $migrate_dir/$tfile
17573
17574         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17575         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17576         local old_dir_mode=$(stat -c%f $migrate_dir)
17577         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17578
17579         mkdir -p $migrate_dir/dir_default_stripe2
17580         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17581         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17582
17583         mkdir -p $other_dir
17584         ln $migrate_dir/$tfile $other_dir/luna
17585         ln $migrate_dir/$tfile $migrate_dir/sofia
17586         ln $other_dir/$tfile $migrate_dir/david
17587         ln -s $migrate_dir/$tfile $other_dir/zachary
17588         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17589         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17590
17591         local len
17592         local lnktgt
17593
17594         # inline symlink
17595         for len in 58 59 60; do
17596                 lnktgt=$(str_repeat 'l' $len)
17597                 touch $migrate_dir/$lnktgt
17598                 ln -s $lnktgt $migrate_dir/${len}char_ln
17599         done
17600
17601         # PATH_MAX
17602         for len in 4094 4095; do
17603                 lnktgt=$(str_repeat 'l' $len)
17604                 ln -s $lnktgt $migrate_dir/${len}char_ln
17605         done
17606
17607         # NAME_MAX
17608         for len in 254 255; do
17609                 touch $migrate_dir/$(str_repeat 'l' $len)
17610         done
17611
17612         $LFS migrate -m $MDTIDX $migrate_dir ||
17613                 error "fails on migrating remote dir to MDT1"
17614
17615         echo "migratate to MDT1, then checking.."
17616         for ((i = 0; i < 10; i++)); do
17617                 for file in $(find $migrate_dir/dir_${i}); do
17618                         mdt_index=$($LFS getstripe -m $file)
17619                         # broken symlink getstripe will fail
17620                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17621                                 error "$file is not on MDT${MDTIDX}"
17622                 done
17623         done
17624
17625         # the multiple link file should still in MDT0
17626         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17627         [ $mdt_index == 0 ] ||
17628                 error "$file is not on MDT${MDTIDX}"
17629
17630         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17631         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17632                 error " expect $old_dir_flag get $new_dir_flag"
17633
17634         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17635         [ "$old_file_flag" = "$new_file_flag" ] ||
17636                 error " expect $old_file_flag get $new_file_flag"
17637
17638         local new_dir_mode=$(stat -c%f $migrate_dir)
17639         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17640                 error "expect mode $old_dir_mode get $new_dir_mode"
17641
17642         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17643         [ "$old_file_mode" = "$new_file_mode" ] ||
17644                 error "expect mode $old_file_mode get $new_file_mode"
17645
17646         diff /etc/passwd $migrate_dir/$tfile ||
17647                 error "$tfile different after migration"
17648
17649         diff /etc/passwd $other_dir/luna ||
17650                 error "luna different after migration"
17651
17652         diff /etc/passwd $migrate_dir/sofia ||
17653                 error "sofia different after migration"
17654
17655         diff /etc/passwd $migrate_dir/david ||
17656                 error "david different after migration"
17657
17658         diff /etc/passwd $other_dir/zachary ||
17659                 error "zachary different after migration"
17660
17661         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17662                 error "${tfile}_ln different after migration"
17663
17664         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17665                 error "${tfile}_ln_other different after migration"
17666
17667         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17668         [ $stripe_count = 2 ] ||
17669                 error "dir strpe_count $d != 2 after migration."
17670
17671         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17672         [ $stripe_count = 2 ] ||
17673                 error "file strpe_count $d != 2 after migration."
17674
17675         #migrate back to MDT0
17676         MDTIDX=0
17677
17678         $LFS migrate -m $MDTIDX $migrate_dir ||
17679                 error "fails on migrating remote dir to MDT0"
17680
17681         echo "migrate back to MDT0, checking.."
17682         for file in $(find $migrate_dir); do
17683                 mdt_index=$($LFS getstripe -m $file)
17684                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17685                         error "$file is not on MDT${MDTIDX}"
17686         done
17687
17688         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17689         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17690                 error " expect $old_dir_flag get $new_dir_flag"
17691
17692         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17693         [ "$old_file_flag" = "$new_file_flag" ] ||
17694                 error " expect $old_file_flag get $new_file_flag"
17695
17696         local new_dir_mode=$(stat -c%f $migrate_dir)
17697         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17698                 error "expect mode $old_dir_mode get $new_dir_mode"
17699
17700         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17701         [ "$old_file_mode" = "$new_file_mode" ] ||
17702                 error "expect mode $old_file_mode get $new_file_mode"
17703
17704         diff /etc/passwd ${migrate_dir}/$tfile ||
17705                 error "$tfile different after migration"
17706
17707         diff /etc/passwd ${other_dir}/luna ||
17708                 error "luna different after migration"
17709
17710         diff /etc/passwd ${migrate_dir}/sofia ||
17711                 error "sofia different after migration"
17712
17713         diff /etc/passwd ${other_dir}/zachary ||
17714                 error "zachary different after migration"
17715
17716         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17717                 error "${tfile}_ln different after migration"
17718
17719         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17720                 error "${tfile}_ln_other different after migration"
17721
17722         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17723         [ $stripe_count = 2 ] ||
17724                 error "dir strpe_count $d != 2 after migration."
17725
17726         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17727         [ $stripe_count = 2 ] ||
17728                 error "file strpe_count $d != 2 after migration."
17729
17730         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17731 }
17732 run_test 230b "migrate directory"
17733
17734 test_230c() {
17735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17736         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17737         remote_mds_nodsh && skip "remote MDS with nodsh"
17738         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17739                 skip "Need MDS version at least 2.11.52"
17740
17741         local MDTIDX=1
17742         local total=3
17743         local mdt_index
17744         local file
17745         local migrate_dir=$DIR/$tdir/migrate_dir
17746
17747         #If migrating directory fails in the middle, all entries of
17748         #the directory is still accessiable.
17749         test_mkdir $DIR/$tdir
17750         test_mkdir -i0 -c1 $migrate_dir
17751         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17752         stat $migrate_dir
17753         createmany -o $migrate_dir/f $total ||
17754                 error "create files under ${migrate_dir} failed"
17755
17756         # fail after migrating top dir, and this will fail only once, so the
17757         # first sub file migration will fail (currently f3), others succeed.
17758         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17759         do_facet mds1 lctl set_param fail_loc=0x1801
17760         local t=$(ls $migrate_dir | wc -l)
17761         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17762                 error "migrate should fail"
17763         local u=$(ls $migrate_dir | wc -l)
17764         [ "$u" == "$t" ] || error "$u != $t during migration"
17765
17766         # add new dir/file should succeed
17767         mkdir $migrate_dir/dir ||
17768                 error "mkdir failed under migrating directory"
17769         touch $migrate_dir/file ||
17770                 error "create file failed under migrating directory"
17771
17772         # add file with existing name should fail
17773         for file in $migrate_dir/f*; do
17774                 stat $file > /dev/null || error "stat $file failed"
17775                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17776                         error "open(O_CREAT|O_EXCL) $file should fail"
17777                 $MULTIOP $file m && error "create $file should fail"
17778                 touch $DIR/$tdir/remote_dir/$tfile ||
17779                         error "touch $tfile failed"
17780                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17781                         error "link $file should fail"
17782                 mdt_index=$($LFS getstripe -m $file)
17783                 if [ $mdt_index == 0 ]; then
17784                         # file failed to migrate is not allowed to rename to
17785                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17786                                 error "rename to $file should fail"
17787                 else
17788                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17789                                 error "rename to $file failed"
17790                 fi
17791                 echo hello >> $file || error "write $file failed"
17792         done
17793
17794         # resume migration with different options should fail
17795         $LFS migrate -m 0 $migrate_dir &&
17796                 error "migrate -m 0 $migrate_dir should fail"
17797
17798         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17799                 error "migrate -c 2 $migrate_dir should fail"
17800
17801         # resume migration should succeed
17802         $LFS migrate -m $MDTIDX $migrate_dir ||
17803                 error "migrate $migrate_dir failed"
17804
17805         echo "Finish migration, then checking.."
17806         for file in $(find $migrate_dir); do
17807                 mdt_index=$($LFS getstripe -m $file)
17808                 [ $mdt_index == $MDTIDX ] ||
17809                         error "$file is not on MDT${MDTIDX}"
17810         done
17811
17812         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17813 }
17814 run_test 230c "check directory accessiblity if migration failed"
17815
17816 test_230d() {
17817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17818         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17819         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17820                 skip "Need MDS version at least 2.11.52"
17821         # LU-11235
17822         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17823
17824         local migrate_dir=$DIR/$tdir/migrate_dir
17825         local old_index
17826         local new_index
17827         local old_count
17828         local new_count
17829         local new_hash
17830         local mdt_index
17831         local i
17832         local j
17833
17834         old_index=$((RANDOM % MDSCOUNT))
17835         old_count=$((MDSCOUNT - old_index))
17836         new_index=$((RANDOM % MDSCOUNT))
17837         new_count=$((MDSCOUNT - new_index))
17838         new_hash=1 # for all_char
17839
17840         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17841         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17842
17843         test_mkdir $DIR/$tdir
17844         test_mkdir -i $old_index -c $old_count $migrate_dir
17845
17846         for ((i=0; i<100; i++)); do
17847                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17848                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17849                         error "create files under remote dir failed $i"
17850         done
17851
17852         echo -n "Migrate from MDT$old_index "
17853         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17854         echo -n "to MDT$new_index"
17855         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17856         echo
17857
17858         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17859         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17860                 error "migrate remote dir error"
17861
17862         echo "Finish migration, then checking.."
17863         for file in $(find $migrate_dir); do
17864                 mdt_index=$($LFS getstripe -m $file)
17865                 if [ $mdt_index -lt $new_index ] ||
17866                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17867                         error "$file is on MDT$mdt_index"
17868                 fi
17869         done
17870
17871         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17872 }
17873 run_test 230d "check migrate big directory"
17874
17875 test_230e() {
17876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17877         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17878         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17879                 skip "Need MDS version at least 2.11.52"
17880
17881         local i
17882         local j
17883         local a_fid
17884         local b_fid
17885
17886         mkdir -p $DIR/$tdir
17887         mkdir $DIR/$tdir/migrate_dir
17888         mkdir $DIR/$tdir/other_dir
17889         touch $DIR/$tdir/migrate_dir/a
17890         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17891         ls $DIR/$tdir/other_dir
17892
17893         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17894                 error "migrate dir fails"
17895
17896         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17897         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17898
17899         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17900         [ $mdt_index == 0 ] || error "a is not on MDT0"
17901
17902         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
17903                 error "migrate dir fails"
17904
17905         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
17906         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
17907
17908         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17909         [ $mdt_index == 1 ] || error "a is not on MDT1"
17910
17911         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
17912         [ $mdt_index == 1 ] || error "b is not on MDT1"
17913
17914         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17915         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
17916
17917         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
17918
17919         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17920 }
17921 run_test 230e "migrate mulitple local link files"
17922
17923 test_230f() {
17924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17925         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17926         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17927                 skip "Need MDS version at least 2.11.52"
17928
17929         local a_fid
17930         local ln_fid
17931
17932         mkdir -p $DIR/$tdir
17933         mkdir $DIR/$tdir/migrate_dir
17934         $LFS mkdir -i1 $DIR/$tdir/other_dir
17935         touch $DIR/$tdir/migrate_dir/a
17936         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
17937         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
17938         ls $DIR/$tdir/other_dir
17939
17940         # a should be migrated to MDT1, since no other links on MDT0
17941         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17942                 error "#1 migrate dir fails"
17943         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17944         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17945         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17946         [ $mdt_index == 1 ] || error "a is not on MDT1"
17947
17948         # a should stay on MDT1, because it is a mulitple link file
17949         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17950                 error "#2 migrate dir fails"
17951         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17952         [ $mdt_index == 1 ] || error "a is not on MDT1"
17953
17954         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17955                 error "#3 migrate dir fails"
17956
17957         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17958         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
17959         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
17960
17961         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
17962         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
17963
17964         # a should be migrated to MDT0, since no other links on MDT1
17965         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17966                 error "#4 migrate dir fails"
17967         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17968         [ $mdt_index == 0 ] || error "a is not on MDT0"
17969
17970         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17971 }
17972 run_test 230f "migrate mulitple remote link files"
17973
17974 test_230g() {
17975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17976         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17977         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17978                 skip "Need MDS version at least 2.11.52"
17979
17980         mkdir -p $DIR/$tdir/migrate_dir
17981
17982         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
17983                 error "migrating dir to non-exist MDT succeeds"
17984         true
17985 }
17986 run_test 230g "migrate dir to non-exist MDT"
17987
17988 test_230h() {
17989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17990         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17991         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17992                 skip "Need MDS version at least 2.11.52"
17993
17994         local mdt_index
17995
17996         mkdir -p $DIR/$tdir/migrate_dir
17997
17998         $LFS migrate -m1 $DIR &&
17999                 error "migrating mountpoint1 should fail"
18000
18001         $LFS migrate -m1 $DIR/$tdir/.. &&
18002                 error "migrating mountpoint2 should fail"
18003
18004         # same as mv
18005         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18006                 error "migrating $tdir/migrate_dir/.. should fail"
18007
18008         true
18009 }
18010 run_test 230h "migrate .. and root"
18011
18012 test_230i() {
18013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18014         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18015         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18016                 skip "Need MDS version at least 2.11.52"
18017
18018         mkdir -p $DIR/$tdir/migrate_dir
18019
18020         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18021                 error "migration fails with a tailing slash"
18022
18023         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18024                 error "migration fails with two tailing slashes"
18025 }
18026 run_test 230i "lfs migrate -m tolerates trailing slashes"
18027
18028 test_230j() {
18029         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18030         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18031                 skip "Need MDS version at least 2.11.52"
18032
18033         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18034         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18035                 error "create $tfile failed"
18036         cat /etc/passwd > $DIR/$tdir/$tfile
18037
18038         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18039
18040         cmp /etc/passwd $DIR/$tdir/$tfile ||
18041                 error "DoM file mismatch after migration"
18042 }
18043 run_test 230j "DoM file data not changed after dir migration"
18044
18045 test_230k() {
18046         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18047         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18048                 skip "Need MDS version at least 2.11.56"
18049
18050         local total=20
18051         local files_on_starting_mdt=0
18052
18053         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18054         $LFS getdirstripe $DIR/$tdir
18055         for i in $(seq $total); do
18056                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18057                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18058                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18059         done
18060
18061         echo "$files_on_starting_mdt files on MDT0"
18062
18063         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18064         $LFS getdirstripe $DIR/$tdir
18065
18066         files_on_starting_mdt=0
18067         for i in $(seq $total); do
18068                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18069                         error "file $tfile.$i mismatch after migration"
18070                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18071                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18072         done
18073
18074         echo "$files_on_starting_mdt files on MDT1 after migration"
18075         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18076
18077         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18078         $LFS getdirstripe $DIR/$tdir
18079
18080         files_on_starting_mdt=0
18081         for i in $(seq $total); do
18082                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18083                         error "file $tfile.$i mismatch after 2nd migration"
18084                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18085                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18086         done
18087
18088         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18089         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18090
18091         true
18092 }
18093 run_test 230k "file data not changed after dir migration"
18094
18095 test_230l() {
18096         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18097         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18098                 skip "Need MDS version at least 2.11.56"
18099
18100         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18101         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18102                 error "create files under remote dir failed $i"
18103         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18104 }
18105 run_test 230l "readdir between MDTs won't crash"
18106
18107 test_230m() {
18108         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18109         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18110                 skip "Need MDS version at least 2.11.56"
18111
18112         local MDTIDX=1
18113         local mig_dir=$DIR/$tdir/migrate_dir
18114         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18115         local shortstr="b"
18116         local val
18117
18118         echo "Creating files and dirs with xattrs"
18119         test_mkdir $DIR/$tdir
18120         test_mkdir -i0 -c1 $mig_dir
18121         mkdir $mig_dir/dir
18122         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18123                 error "cannot set xattr attr1 on dir"
18124         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18125                 error "cannot set xattr attr2 on dir"
18126         touch $mig_dir/dir/f0
18127         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18128                 error "cannot set xattr attr1 on file"
18129         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18130                 error "cannot set xattr attr2 on file"
18131         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18132         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18133         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18134         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18135         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18136         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18137         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18138         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18139         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18140
18141         echo "Migrating to MDT1"
18142         $LFS migrate -m $MDTIDX $mig_dir ||
18143                 error "fails on migrating dir to MDT1"
18144
18145         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18146         echo "Checking xattrs"
18147         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18148         [ "$val" = $longstr ] ||
18149                 error "expecting xattr1 $longstr on dir, found $val"
18150         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18151         [ "$val" = $shortstr ] ||
18152                 error "expecting xattr2 $shortstr on dir, found $val"
18153         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18154         [ "$val" = $longstr ] ||
18155                 error "expecting xattr1 $longstr on file, found $val"
18156         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18157         [ "$val" = $shortstr ] ||
18158                 error "expecting xattr2 $shortstr on file, found $val"
18159 }
18160 run_test 230m "xattrs not changed after dir migration"
18161
18162 test_230n() {
18163         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18164         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18165                 skip "Need MDS version at least 2.13.53"
18166
18167         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18168         cat /etc/hosts > $DIR/$tdir/$tfile
18169         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18170         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18171
18172         cmp /etc/hosts $DIR/$tdir/$tfile ||
18173                 error "File data mismatch after migration"
18174 }
18175 run_test 230n "Dir migration with mirrored file"
18176
18177 test_230o() {
18178         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18179         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18180                 skip "Need MDS version at least 2.13.52"
18181
18182         local mdts=$(comma_list $(mdts_nodes))
18183         local timeout=100
18184
18185         local restripe_status
18186         local delta
18187         local i
18188         local j
18189
18190         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18191
18192         # in case "crush" hash type is not set
18193         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18194
18195         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18196                            mdt.*MDT0000.enable_dir_restripe)
18197         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18198         stack_trap "do_nodes $mdts $LCTL set_param \
18199                     mdt.*.enable_dir_restripe=$restripe_status"
18200
18201         mkdir $DIR/$tdir
18202         createmany -m $DIR/$tdir/f 100 ||
18203                 error "create files under remote dir failed $i"
18204         createmany -d $DIR/$tdir/d 100 ||
18205                 error "create dirs under remote dir failed $i"
18206
18207         for i in $(seq 2 $MDSCOUNT); do
18208                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18209                 $LFS setdirstripe -c $i $DIR/$tdir ||
18210                         error "split -c $i $tdir failed"
18211                 wait_update $HOSTNAME \
18212                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18213                         error "dir split not finished"
18214                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18215                         awk '/migrate/ {sum += $2} END { print sum }')
18216                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18217                 # delta is around total_files/stripe_count
18218                 [ $delta -lt $((200 /(i - 1))) ] ||
18219                         error "$delta files migrated"
18220         done
18221 }
18222 run_test 230o "dir split"
18223
18224 test_230p() {
18225         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18226         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18227                 skip "Need MDS version at least 2.13.52"
18228
18229         local mdts=$(comma_list $(mdts_nodes))
18230         local timeout=100
18231
18232         local restripe_status
18233         local delta
18234         local i
18235         local j
18236
18237         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18238
18239         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18240
18241         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18242                            mdt.*MDT0000.enable_dir_restripe)
18243         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18244         stack_trap "do_nodes $mdts $LCTL set_param \
18245                     mdt.*.enable_dir_restripe=$restripe_status"
18246
18247         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18248         createmany -m $DIR/$tdir/f 100 ||
18249                 error "create files under remote dir failed $i"
18250         createmany -d $DIR/$tdir/d 100 ||
18251                 error "create dirs under remote dir failed $i"
18252
18253         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18254                 local mdt_hash="crush"
18255
18256                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18257                 $LFS setdirstripe -c $i $DIR/$tdir ||
18258                         error "split -c $i $tdir failed"
18259                 [ $i -eq 1 ] && mdt_hash="none"
18260                 wait_update $HOSTNAME \
18261                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18262                         error "dir merge not finished"
18263                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18264                         awk '/migrate/ {sum += $2} END { print sum }')
18265                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18266                 # delta is around total_files/stripe_count
18267                 [ $delta -lt $((200 / i)) ] ||
18268                         error "$delta files migrated"
18269         done
18270 }
18271 run_test 230p "dir merge"
18272
18273 test_230q() {
18274         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18275         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18276                 skip "Need MDS version at least 2.13.52"
18277
18278         local mdts=$(comma_list $(mdts_nodes))
18279         local saved_threshold=$(do_facet mds1 \
18280                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18281         local saved_delta=$(do_facet mds1 \
18282                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18283         local threshold=100
18284         local delta=2
18285         local total=0
18286         local stripe_count=0
18287         local stripe_index
18288         local nr_files
18289
18290         stack_trap "do_nodes $mdts $LCTL set_param \
18291                     mdt.*.dir_split_count=$saved_threshold"
18292         stack_trap "do_nodes $mdts $LCTL set_param \
18293                     mdt.*.dir_split_delta=$saved_delta"
18294         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18295         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18296         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18297         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18298         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18299         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18300
18301         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18302         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18303
18304         while [ $stripe_count -lt $MDSCOUNT ]; do
18305                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18306                         error "create sub files failed"
18307                 stat $DIR/$tdir > /dev/null
18308                 total=$((total + threshold * 3 / 2))
18309                 stripe_count=$((stripe_count + delta))
18310                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18311
18312                 wait_update $HOSTNAME \
18313                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18314                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18315
18316                 wait_update $HOSTNAME \
18317                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18318                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18319
18320                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18321                            grep -w $stripe_index | wc -l)
18322                 echo "$nr_files files on MDT$stripe_index after split"
18323                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18324                         error "$nr_files files on MDT$stripe_index after split"
18325
18326                 nr_files=$(ls $DIR/$tdir | wc -w)
18327                 [ $nr_files -eq $total ] ||
18328                         error "total sub files $nr_files != $total"
18329         done
18330 }
18331 run_test 230q "dir auto split"
18332
18333 test_230r() {
18334         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18335         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18336         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18337                 skip "Need MDS version at least 2.13.54"
18338
18339         # maximum amount of local locks:
18340         # parent striped dir - 2 locks
18341         # new stripe in parent to migrate to - 1 lock
18342         # source and target - 2 locks
18343         # Total 5 locks for regular file
18344         mkdir -p $DIR/$tdir
18345         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18346         touch $DIR/$tdir/dir1/eee
18347
18348         # create 4 hardlink for 4 more locks
18349         # Total: 9 locks > RS_MAX_LOCKS (8)
18350         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18351         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18352         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18353         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18354         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18355         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18356         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18357         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18358
18359         cancel_lru_locks mdc
18360
18361         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18362                 error "migrate dir fails"
18363
18364         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18365 }
18366 run_test 230r "migrate with too many local locks"
18367
18368 test_231a()
18369 {
18370         # For simplicity this test assumes that max_pages_per_rpc
18371         # is the same across all OSCs
18372         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18373         local bulk_size=$((max_pages * PAGE_SIZE))
18374         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18375                                        head -n 1)
18376
18377         mkdir -p $DIR/$tdir
18378         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18379                 error "failed to set stripe with -S ${brw_size}M option"
18380
18381         # clear the OSC stats
18382         $LCTL set_param osc.*.stats=0 &>/dev/null
18383         stop_writeback
18384
18385         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18386         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18387                 oflag=direct &>/dev/null || error "dd failed"
18388
18389         sync; sleep 1; sync # just to be safe
18390         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18391         if [ x$nrpcs != "x1" ]; then
18392                 $LCTL get_param osc.*.stats
18393                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18394         fi
18395
18396         start_writeback
18397         # Drop the OSC cache, otherwise we will read from it
18398         cancel_lru_locks osc
18399
18400         # clear the OSC stats
18401         $LCTL set_param osc.*.stats=0 &>/dev/null
18402
18403         # Client reads $bulk_size.
18404         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18405                 iflag=direct &>/dev/null || error "dd failed"
18406
18407         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18408         if [ x$nrpcs != "x1" ]; then
18409                 $LCTL get_param osc.*.stats
18410                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18411         fi
18412 }
18413 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18414
18415 test_231b() {
18416         mkdir -p $DIR/$tdir
18417         local i
18418         for i in {0..1023}; do
18419                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18420                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18421                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18422         done
18423         sync
18424 }
18425 run_test 231b "must not assert on fully utilized OST request buffer"
18426
18427 test_232a() {
18428         mkdir -p $DIR/$tdir
18429         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18430
18431         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18432         do_facet ost1 $LCTL set_param fail_loc=0x31c
18433
18434         # ignore dd failure
18435         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18436
18437         do_facet ost1 $LCTL set_param fail_loc=0
18438         umount_client $MOUNT || error "umount failed"
18439         mount_client $MOUNT || error "mount failed"
18440         stop ost1 || error "cannot stop ost1"
18441         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18442 }
18443 run_test 232a "failed lock should not block umount"
18444
18445 test_232b() {
18446         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18447                 skip "Need MDS version at least 2.10.58"
18448
18449         mkdir -p $DIR/$tdir
18450         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18451         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18452         sync
18453         cancel_lru_locks osc
18454
18455         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18456         do_facet ost1 $LCTL set_param fail_loc=0x31c
18457
18458         # ignore failure
18459         $LFS data_version $DIR/$tdir/$tfile || true
18460
18461         do_facet ost1 $LCTL set_param fail_loc=0
18462         umount_client $MOUNT || error "umount failed"
18463         mount_client $MOUNT || error "mount failed"
18464         stop ost1 || error "cannot stop ost1"
18465         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18466 }
18467 run_test 232b "failed data version lock should not block umount"
18468
18469 test_233a() {
18470         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18471                 skip "Need MDS version at least 2.3.64"
18472         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18473
18474         local fid=$($LFS path2fid $MOUNT)
18475
18476         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18477                 error "cannot access $MOUNT using its FID '$fid'"
18478 }
18479 run_test 233a "checking that OBF of the FS root succeeds"
18480
18481 test_233b() {
18482         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18483                 skip "Need MDS version at least 2.5.90"
18484         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18485
18486         local fid=$($LFS path2fid $MOUNT/.lustre)
18487
18488         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18489                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18490
18491         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18492         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18493                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18494 }
18495 run_test 233b "checking that OBF of the FS .lustre succeeds"
18496
18497 test_234() {
18498         local p="$TMP/sanityN-$TESTNAME.parameters"
18499         save_lustre_params client "llite.*.xattr_cache" > $p
18500         lctl set_param llite.*.xattr_cache 1 ||
18501                 skip_env "xattr cache is not supported"
18502
18503         mkdir -p $DIR/$tdir || error "mkdir failed"
18504         touch $DIR/$tdir/$tfile || error "touch failed"
18505         # OBD_FAIL_LLITE_XATTR_ENOMEM
18506         $LCTL set_param fail_loc=0x1405
18507         getfattr -n user.attr $DIR/$tdir/$tfile &&
18508                 error "getfattr should have failed with ENOMEM"
18509         $LCTL set_param fail_loc=0x0
18510         rm -rf $DIR/$tdir
18511
18512         restore_lustre_params < $p
18513         rm -f $p
18514 }
18515 run_test 234 "xattr cache should not crash on ENOMEM"
18516
18517 test_235() {
18518         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18519                 skip "Need MDS version at least 2.4.52"
18520
18521         flock_deadlock $DIR/$tfile
18522         local RC=$?
18523         case $RC in
18524                 0)
18525                 ;;
18526                 124) error "process hangs on a deadlock"
18527                 ;;
18528                 *) error "error executing flock_deadlock $DIR/$tfile"
18529                 ;;
18530         esac
18531 }
18532 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18533
18534 #LU-2935
18535 test_236() {
18536         check_swap_layouts_support
18537
18538         local ref1=/etc/passwd
18539         local ref2=/etc/group
18540         local file1=$DIR/$tdir/f1
18541         local file2=$DIR/$tdir/f2
18542
18543         test_mkdir -c1 $DIR/$tdir
18544         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18545         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18546         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18547         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18548         local fd=$(free_fd)
18549         local cmd="exec $fd<>$file2"
18550         eval $cmd
18551         rm $file2
18552         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18553                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18554         cmd="exec $fd>&-"
18555         eval $cmd
18556         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18557
18558         #cleanup
18559         rm -rf $DIR/$tdir
18560 }
18561 run_test 236 "Layout swap on open unlinked file"
18562
18563 # LU-4659 linkea consistency
18564 test_238() {
18565         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18566                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18567                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18568                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18569
18570         touch $DIR/$tfile
18571         ln $DIR/$tfile $DIR/$tfile.lnk
18572         touch $DIR/$tfile.new
18573         mv $DIR/$tfile.new $DIR/$tfile
18574         local fid1=$($LFS path2fid $DIR/$tfile)
18575         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18576         local path1=$($LFS fid2path $FSNAME "$fid1")
18577         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18578         local path2=$($LFS fid2path $FSNAME "$fid2")
18579         [ $tfile.lnk == $path2 ] ||
18580                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18581         rm -f $DIR/$tfile*
18582 }
18583 run_test 238 "Verify linkea consistency"
18584
18585 test_239A() { # was test_239
18586         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18587                 skip "Need MDS version at least 2.5.60"
18588
18589         local list=$(comma_list $(mdts_nodes))
18590
18591         mkdir -p $DIR/$tdir
18592         createmany -o $DIR/$tdir/f- 5000
18593         unlinkmany $DIR/$tdir/f- 5000
18594         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18595                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18596         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18597                         osp.*MDT*.sync_in_flight" | calc_sum)
18598         [ "$changes" -eq 0 ] || error "$changes not synced"
18599 }
18600 run_test 239A "osp_sync test"
18601
18602 test_239a() { #LU-5297
18603         remote_mds_nodsh && skip "remote MDS with nodsh"
18604
18605         touch $DIR/$tfile
18606         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18607         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18608         chgrp $RUNAS_GID $DIR/$tfile
18609         wait_delete_completed
18610 }
18611 run_test 239a "process invalid osp sync record correctly"
18612
18613 test_239b() { #LU-5297
18614         remote_mds_nodsh && skip "remote MDS with nodsh"
18615
18616         touch $DIR/$tfile1
18617         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18618         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18619         chgrp $RUNAS_GID $DIR/$tfile1
18620         wait_delete_completed
18621         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18622         touch $DIR/$tfile2
18623         chgrp $RUNAS_GID $DIR/$tfile2
18624         wait_delete_completed
18625 }
18626 run_test 239b "process osp sync record with ENOMEM error correctly"
18627
18628 test_240() {
18629         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18630         remote_mds_nodsh && skip "remote MDS with nodsh"
18631
18632         mkdir -p $DIR/$tdir
18633
18634         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18635                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18636         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18637                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18638
18639         umount_client $MOUNT || error "umount failed"
18640         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18641         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18642         mount_client $MOUNT || error "failed to mount client"
18643
18644         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18645         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18646 }
18647 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18648
18649 test_241_bio() {
18650         local count=$1
18651         local bsize=$2
18652
18653         for LOOP in $(seq $count); do
18654                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18655                 cancel_lru_locks $OSC || true
18656         done
18657 }
18658
18659 test_241_dio() {
18660         local count=$1
18661         local bsize=$2
18662
18663         for LOOP in $(seq $1); do
18664                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18665                         2>/dev/null
18666         done
18667 }
18668
18669 test_241a() { # was test_241
18670         local bsize=$PAGE_SIZE
18671
18672         (( bsize < 40960 )) && bsize=40960
18673         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18674         ls -la $DIR/$tfile
18675         cancel_lru_locks $OSC
18676         test_241_bio 1000 $bsize &
18677         PID=$!
18678         test_241_dio 1000 $bsize
18679         wait $PID
18680 }
18681 run_test 241a "bio vs dio"
18682
18683 test_241b() {
18684         local bsize=$PAGE_SIZE
18685
18686         (( bsize < 40960 )) && bsize=40960
18687         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18688         ls -la $DIR/$tfile
18689         test_241_dio 1000 $bsize &
18690         PID=$!
18691         test_241_dio 1000 $bsize
18692         wait $PID
18693 }
18694 run_test 241b "dio vs dio"
18695
18696 test_242() {
18697         remote_mds_nodsh && skip "remote MDS with nodsh"
18698
18699         mkdir -p $DIR/$tdir
18700         touch $DIR/$tdir/$tfile
18701
18702         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18703         do_facet mds1 lctl set_param fail_loc=0x105
18704         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18705
18706         do_facet mds1 lctl set_param fail_loc=0
18707         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18708 }
18709 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18710
18711 test_243()
18712 {
18713         test_mkdir $DIR/$tdir
18714         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18715 }
18716 run_test 243 "various group lock tests"
18717
18718 test_244a()
18719 {
18720         test_mkdir $DIR/$tdir
18721         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18722         sendfile_grouplock $DIR/$tdir/$tfile || \
18723                 error "sendfile+grouplock failed"
18724         rm -rf $DIR/$tdir
18725 }
18726 run_test 244a "sendfile with group lock tests"
18727
18728 test_244b()
18729 {
18730         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18731
18732         local threads=50
18733         local size=$((1024*1024))
18734
18735         test_mkdir $DIR/$tdir
18736         for i in $(seq 1 $threads); do
18737                 local file=$DIR/$tdir/file_$((i / 10))
18738                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18739                 local pids[$i]=$!
18740         done
18741         for i in $(seq 1 $threads); do
18742                 wait ${pids[$i]}
18743         done
18744 }
18745 run_test 244b "multi-threaded write with group lock"
18746
18747 test_245() {
18748         local flagname="multi_mod_rpcs"
18749         local connect_data_name="max_mod_rpcs"
18750         local out
18751
18752         # check if multiple modify RPCs flag is set
18753         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18754                 grep "connect_flags:")
18755         echo "$out"
18756
18757         echo "$out" | grep -qw $flagname
18758         if [ $? -ne 0 ]; then
18759                 echo "connect flag $flagname is not set"
18760                 return
18761         fi
18762
18763         # check if multiple modify RPCs data is set
18764         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18765         echo "$out"
18766
18767         echo "$out" | grep -qw $connect_data_name ||
18768                 error "import should have connect data $connect_data_name"
18769 }
18770 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18771
18772 cleanup_247() {
18773         local submount=$1
18774
18775         trap 0
18776         umount_client $submount
18777         rmdir $submount
18778 }
18779
18780 test_247a() {
18781         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18782                 grep -q subtree ||
18783                 skip_env "Fileset feature is not supported"
18784
18785         local submount=${MOUNT}_$tdir
18786
18787         mkdir $MOUNT/$tdir
18788         mkdir -p $submount || error "mkdir $submount failed"
18789         FILESET="$FILESET/$tdir" mount_client $submount ||
18790                 error "mount $submount failed"
18791         trap "cleanup_247 $submount" EXIT
18792         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18793         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18794                 error "read $MOUNT/$tdir/$tfile failed"
18795         cleanup_247 $submount
18796 }
18797 run_test 247a "mount subdir as fileset"
18798
18799 test_247b() {
18800         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18801                 skip_env "Fileset feature is not supported"
18802
18803         local submount=${MOUNT}_$tdir
18804
18805         rm -rf $MOUNT/$tdir
18806         mkdir -p $submount || error "mkdir $submount failed"
18807         SKIP_FILESET=1
18808         FILESET="$FILESET/$tdir" mount_client $submount &&
18809                 error "mount $submount should fail"
18810         rmdir $submount
18811 }
18812 run_test 247b "mount subdir that dose not exist"
18813
18814 test_247c() {
18815         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18816                 skip_env "Fileset feature is not supported"
18817
18818         local submount=${MOUNT}_$tdir
18819
18820         mkdir -p $MOUNT/$tdir/dir1
18821         mkdir -p $submount || error "mkdir $submount failed"
18822         trap "cleanup_247 $submount" EXIT
18823         FILESET="$FILESET/$tdir" mount_client $submount ||
18824                 error "mount $submount failed"
18825         local fid=$($LFS path2fid $MOUNT/)
18826         $LFS fid2path $submount $fid && error "fid2path should fail"
18827         cleanup_247 $submount
18828 }
18829 run_test 247c "running fid2path outside subdirectory root"
18830
18831 test_247d() {
18832         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18833                 skip "Fileset feature is not supported"
18834
18835         local submount=${MOUNT}_$tdir
18836
18837         mkdir -p $MOUNT/$tdir/dir1
18838         mkdir -p $submount || error "mkdir $submount failed"
18839         FILESET="$FILESET/$tdir" mount_client $submount ||
18840                 error "mount $submount failed"
18841         trap "cleanup_247 $submount" EXIT
18842
18843         local td=$submount/dir1
18844         local fid=$($LFS path2fid $td)
18845         [ -z "$fid" ] && error "path2fid unable to get $td FID"
18846
18847         # check that we get the same pathname back
18848         local rootpath
18849         local found
18850         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
18851                 echo "$rootpath $fid"
18852                 found=$($LFS fid2path $rootpath "$fid")
18853                 [ -n "found" ] || error "fid2path should succeed"
18854                 [ "$found" == "$td" ] || error "fid2path $found != $td"
18855         done
18856         # check wrong root path format
18857         rootpath=$submount"_wrong"
18858         found=$($LFS fid2path $rootpath "$fid")
18859         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
18860
18861         cleanup_247 $submount
18862 }
18863 run_test 247d "running fid2path inside subdirectory root"
18864
18865 # LU-8037
18866 test_247e() {
18867         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18868                 grep -q subtree ||
18869                 skip "Fileset feature is not supported"
18870
18871         local submount=${MOUNT}_$tdir
18872
18873         mkdir $MOUNT/$tdir
18874         mkdir -p $submount || error "mkdir $submount failed"
18875         FILESET="$FILESET/.." mount_client $submount &&
18876                 error "mount $submount should fail"
18877         rmdir $submount
18878 }
18879 run_test 247e "mount .. as fileset"
18880
18881 test_247f() {
18882         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18883         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18884                 skip "Need at least version 2.13.52"
18885         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18886                 grep -q subtree ||
18887                 skip "Fileset feature is not supported"
18888
18889         mkdir $DIR/$tdir || error "mkdir $tdir failed"
18890         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
18891                 error "mkdir remote failed"
18892         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
18893         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
18894                 error "mkdir striped failed"
18895         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
18896
18897         local submount=${MOUNT}_$tdir
18898
18899         mkdir -p $submount || error "mkdir $submount failed"
18900
18901         local dir
18902         local fileset=$FILESET
18903
18904         for dir in $tdir/remote $tdir/remote/subdir \
18905                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
18906                 FILESET="$fileset/$dir" mount_client $submount ||
18907                         error "mount $dir failed"
18908                 umount_client $submount
18909         done
18910 }
18911 run_test 247f "mount striped or remote directory as fileset"
18912
18913 test_248a() {
18914         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
18915         [ -z "$fast_read_sav" ] && skip "no fast read support"
18916
18917         # create a large file for fast read verification
18918         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
18919
18920         # make sure the file is created correctly
18921         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
18922                 { rm -f $DIR/$tfile; skip "file creation error"; }
18923
18924         echo "Test 1: verify that fast read is 4 times faster on cache read"
18925
18926         # small read with fast read enabled
18927         $LCTL set_param -n llite.*.fast_read=1
18928         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18929                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18930                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18931         # small read with fast read disabled
18932         $LCTL set_param -n llite.*.fast_read=0
18933         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18934                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18935                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18936
18937         # verify that fast read is 4 times faster for cache read
18938         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
18939                 error_not_in_vm "fast read was not 4 times faster: " \
18940                            "$t_fast vs $t_slow"
18941
18942         echo "Test 2: verify the performance between big and small read"
18943         $LCTL set_param -n llite.*.fast_read=1
18944
18945         # 1k non-cache read
18946         cancel_lru_locks osc
18947         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18948                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18949                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18950
18951         # 1M non-cache read
18952         cancel_lru_locks osc
18953         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18954                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18955                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18956
18957         # verify that big IO is not 4 times faster than small IO
18958         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
18959                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
18960
18961         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
18962         rm -f $DIR/$tfile
18963 }
18964 run_test 248a "fast read verification"
18965
18966 test_248b() {
18967         # Default short_io_bytes=16384, try both smaller and larger sizes.
18968         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
18969         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
18970         echo "bs=53248 count=113 normal buffered write"
18971         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
18972                 error "dd of initial data file failed"
18973         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
18974
18975         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
18976         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
18977                 error "dd with sync normal writes failed"
18978         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
18979
18980         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
18981         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
18982                 error "dd with sync small writes failed"
18983         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
18984
18985         cancel_lru_locks osc
18986
18987         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
18988         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
18989         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
18990         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
18991                 iflag=direct || error "dd with O_DIRECT small read failed"
18992         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
18993         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
18994                 error "compare $TMP/$tfile.1 failed"
18995
18996         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
18997         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
18998
18999         # just to see what the maximum tunable value is, and test parsing
19000         echo "test invalid parameter 2MB"
19001         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19002                 error "too-large short_io_bytes allowed"
19003         echo "test maximum parameter 512KB"
19004         # if we can set a larger short_io_bytes, run test regardless of version
19005         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19006                 # older clients may not allow setting it this large, that's OK
19007                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19008                         skip "Need at least client version 2.13.50"
19009                 error "medium short_io_bytes failed"
19010         fi
19011         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19012         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19013
19014         echo "test large parameter 64KB"
19015         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19016         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19017
19018         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19019         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19020                 error "dd with sync large writes failed"
19021         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19022
19023         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19024         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19025         num=$((113 * 4096 / PAGE_SIZE))
19026         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19027         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19028                 error "dd with O_DIRECT large writes failed"
19029         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19030                 error "compare $DIR/$tfile.3 failed"
19031
19032         cancel_lru_locks osc
19033
19034         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19035         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19036                 error "dd with O_DIRECT large read failed"
19037         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19038                 error "compare $TMP/$tfile.2 failed"
19039
19040         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19041         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19042                 error "dd with O_DIRECT large read failed"
19043         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19044                 error "compare $TMP/$tfile.3 failed"
19045 }
19046 run_test 248b "test short_io read and write for both small and large sizes"
19047
19048 test_249() { # LU-7890
19049         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19050                 skip "Need at least version 2.8.54"
19051
19052         rm -f $DIR/$tfile
19053         $LFS setstripe -c 1 $DIR/$tfile
19054         # Offset 2T == 4k * 512M
19055         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19056                 error "dd to 2T offset failed"
19057 }
19058 run_test 249 "Write above 2T file size"
19059
19060 test_250() {
19061         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19062          && skip "no 16TB file size limit on ZFS"
19063
19064         $LFS setstripe -c 1 $DIR/$tfile
19065         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19066         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19067         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19068         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19069                 conv=notrunc,fsync && error "append succeeded"
19070         return 0
19071 }
19072 run_test 250 "Write above 16T limit"
19073
19074 test_251() {
19075         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19076
19077         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19078         #Skip once - writing the first stripe will succeed
19079         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19080         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19081                 error "short write happened"
19082
19083         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19084         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19085                 error "short read happened"
19086
19087         rm -f $DIR/$tfile
19088 }
19089 run_test 251 "Handling short read and write correctly"
19090
19091 test_252() {
19092         remote_mds_nodsh && skip "remote MDS with nodsh"
19093         remote_ost_nodsh && skip "remote OST with nodsh"
19094         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19095                 skip_env "ldiskfs only test"
19096         fi
19097
19098         local tgt
19099         local dev
19100         local out
19101         local uuid
19102         local num
19103         local gen
19104
19105         # check lr_reader on OST0000
19106         tgt=ost1
19107         dev=$(facet_device $tgt)
19108         out=$(do_facet $tgt $LR_READER $dev)
19109         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19110         echo "$out"
19111         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19112         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19113                 error "Invalid uuid returned by $LR_READER on target $tgt"
19114         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19115
19116         # check lr_reader -c on MDT0000
19117         tgt=mds1
19118         dev=$(facet_device $tgt)
19119         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19120                 skip "$LR_READER does not support additional options"
19121         fi
19122         out=$(do_facet $tgt $LR_READER -c $dev)
19123         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19124         echo "$out"
19125         num=$(echo "$out" | grep -c "mdtlov")
19126         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19127                 error "Invalid number of mdtlov clients returned by $LR_READER"
19128         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19129
19130         # check lr_reader -cr on MDT0000
19131         out=$(do_facet $tgt $LR_READER -cr $dev)
19132         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19133         echo "$out"
19134         echo "$out" | grep -q "^reply_data:$" ||
19135                 error "$LR_READER should have returned 'reply_data' section"
19136         num=$(echo "$out" | grep -c "client_generation")
19137         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19138 }
19139 run_test 252 "check lr_reader tool"
19140
19141 test_253() {
19142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19143         remote_mds_nodsh && skip "remote MDS with nodsh"
19144         remote_mgs_nodsh && skip "remote MGS with nodsh"
19145
19146         local ostidx=0
19147         local rc=0
19148         local ost_name=$(ostname_from_index $ostidx)
19149
19150         # on the mdt's osc
19151         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19152         do_facet $SINGLEMDS $LCTL get_param -n \
19153                 osp.$mdtosc_proc1.reserved_mb_high ||
19154                 skip  "remote MDS does not support reserved_mb_high"
19155
19156         rm -rf $DIR/$tdir
19157         wait_mds_ost_sync
19158         wait_delete_completed
19159         mkdir $DIR/$tdir
19160
19161         pool_add $TESTNAME || error "Pool creation failed"
19162         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19163
19164         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19165                 error "Setstripe failed"
19166
19167         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19168
19169         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19170                     grep "watermarks")
19171         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19172
19173         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19174                         osp.$mdtosc_proc1.prealloc_status)
19175         echo "prealloc_status $oa_status"
19176
19177         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19178                 error "File creation should fail"
19179
19180         #object allocation was stopped, but we still able to append files
19181         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19182                 oflag=append || error "Append failed"
19183
19184         rm -f $DIR/$tdir/$tfile.0
19185
19186         # For this test, we want to delete the files we created to go out of
19187         # space but leave the watermark, so we remain nearly out of space
19188         ost_watermarks_enospc_delete_files $tfile $ostidx
19189
19190         wait_delete_completed
19191
19192         sleep_maxage
19193
19194         for i in $(seq 10 12); do
19195                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19196                         2>/dev/null || error "File creation failed after rm"
19197         done
19198
19199         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19200                         osp.$mdtosc_proc1.prealloc_status)
19201         echo "prealloc_status $oa_status"
19202
19203         if (( oa_status != 0 )); then
19204                 error "Object allocation still disable after rm"
19205         fi
19206 }
19207 run_test 253 "Check object allocation limit"
19208
19209 test_254() {
19210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19211         remote_mds_nodsh && skip "remote MDS with nodsh"
19212         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19213                 skip "MDS does not support changelog_size"
19214
19215         local cl_user
19216         local MDT0=$(facet_svc $SINGLEMDS)
19217
19218         changelog_register || error "changelog_register failed"
19219
19220         changelog_clear 0 || error "changelog_clear failed"
19221
19222         local size1=$(do_facet $SINGLEMDS \
19223                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19224         echo "Changelog size $size1"
19225
19226         rm -rf $DIR/$tdir
19227         $LFS mkdir -i 0 $DIR/$tdir
19228         # change something
19229         mkdir -p $DIR/$tdir/pics/2008/zachy
19230         touch $DIR/$tdir/pics/2008/zachy/timestamp
19231         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19232         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19233         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19234         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19235         rm $DIR/$tdir/pics/desktop.jpg
19236
19237         local size2=$(do_facet $SINGLEMDS \
19238                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19239         echo "Changelog size after work $size2"
19240
19241         (( $size2 > $size1 )) ||
19242                 error "new Changelog size=$size2 less than old size=$size1"
19243 }
19244 run_test 254 "Check changelog size"
19245
19246 ladvise_no_type()
19247 {
19248         local type=$1
19249         local file=$2
19250
19251         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19252                 awk -F: '{print $2}' | grep $type > /dev/null
19253         if [ $? -ne 0 ]; then
19254                 return 0
19255         fi
19256         return 1
19257 }
19258
19259 ladvise_no_ioctl()
19260 {
19261         local file=$1
19262
19263         lfs ladvise -a willread $file > /dev/null 2>&1
19264         if [ $? -eq 0 ]; then
19265                 return 1
19266         fi
19267
19268         lfs ladvise -a willread $file 2>&1 |
19269                 grep "Inappropriate ioctl for device" > /dev/null
19270         if [ $? -eq 0 ]; then
19271                 return 0
19272         fi
19273         return 1
19274 }
19275
19276 percent() {
19277         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19278 }
19279
19280 # run a random read IO workload
19281 # usage: random_read_iops <filename> <filesize> <iosize>
19282 random_read_iops() {
19283         local file=$1
19284         local fsize=$2
19285         local iosize=${3:-4096}
19286
19287         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19288                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19289 }
19290
19291 drop_file_oss_cache() {
19292         local file="$1"
19293         local nodes="$2"
19294
19295         $LFS ladvise -a dontneed $file 2>/dev/null ||
19296                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19297 }
19298
19299 ladvise_willread_performance()
19300 {
19301         local repeat=10
19302         local average_origin=0
19303         local average_cache=0
19304         local average_ladvise=0
19305
19306         for ((i = 1; i <= $repeat; i++)); do
19307                 echo "Iter $i/$repeat: reading without willread hint"
19308                 cancel_lru_locks osc
19309                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19310                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19311                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19312                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19313
19314                 cancel_lru_locks osc
19315                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19316                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19317                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19318
19319                 cancel_lru_locks osc
19320                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19321                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19322                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19323                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19324                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19325         done
19326         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19327         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19328         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19329
19330         speedup_cache=$(percent $average_cache $average_origin)
19331         speedup_ladvise=$(percent $average_ladvise $average_origin)
19332
19333         echo "Average uncached read: $average_origin"
19334         echo "Average speedup with OSS cached read: " \
19335                 "$average_cache = +$speedup_cache%"
19336         echo "Average speedup with ladvise willread: " \
19337                 "$average_ladvise = +$speedup_ladvise%"
19338
19339         local lowest_speedup=20
19340         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19341                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19342                         "got $average_cache%. Skipping ladvise willread check."
19343                 return 0
19344         fi
19345
19346         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19347         # it is still good to run until then to exercise 'ladvise willread'
19348         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19349                 [ "$ost1_FSTYPE" = "zfs" ] &&
19350                 echo "osd-zfs does not support dontneed or drop_caches" &&
19351                 return 0
19352
19353         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19354         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
19355                 error_not_in_vm "Speedup with willread is less than " \
19356                         "$lowest_speedup%, got $average_ladvise%"
19357 }
19358
19359 test_255a() {
19360         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19361                 skip "lustre < 2.8.54 does not support ladvise "
19362         remote_ost_nodsh && skip "remote OST with nodsh"
19363
19364         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19365
19366         ladvise_no_type willread $DIR/$tfile &&
19367                 skip "willread ladvise is not supported"
19368
19369         ladvise_no_ioctl $DIR/$tfile &&
19370                 skip "ladvise ioctl is not supported"
19371
19372         local size_mb=100
19373         local size=$((size_mb * 1048576))
19374         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19375                 error "dd to $DIR/$tfile failed"
19376
19377         lfs ladvise -a willread $DIR/$tfile ||
19378                 error "Ladvise failed with no range argument"
19379
19380         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19381                 error "Ladvise failed with no -l or -e argument"
19382
19383         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19384                 error "Ladvise failed with only -e argument"
19385
19386         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19387                 error "Ladvise failed with only -l argument"
19388
19389         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19390                 error "End offset should not be smaller than start offset"
19391
19392         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19393                 error "End offset should not be equal to start offset"
19394
19395         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19396                 error "Ladvise failed with overflowing -s argument"
19397
19398         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19399                 error "Ladvise failed with overflowing -e argument"
19400
19401         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19402                 error "Ladvise failed with overflowing -l argument"
19403
19404         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19405                 error "Ladvise succeeded with conflicting -l and -e arguments"
19406
19407         echo "Synchronous ladvise should wait"
19408         local delay=4
19409 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19410         do_nodes $(comma_list $(osts_nodes)) \
19411                 $LCTL set_param fail_val=$delay fail_loc=0x237
19412
19413         local start_ts=$SECONDS
19414         lfs ladvise -a willread $DIR/$tfile ||
19415                 error "Ladvise failed with no range argument"
19416         local end_ts=$SECONDS
19417         local inteval_ts=$((end_ts - start_ts))
19418
19419         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19420                 error "Synchronous advice didn't wait reply"
19421         fi
19422
19423         echo "Asynchronous ladvise shouldn't wait"
19424         local start_ts=$SECONDS
19425         lfs ladvise -a willread -b $DIR/$tfile ||
19426                 error "Ladvise failed with no range argument"
19427         local end_ts=$SECONDS
19428         local inteval_ts=$((end_ts - start_ts))
19429
19430         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19431                 error "Asynchronous advice blocked"
19432         fi
19433
19434         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19435         ladvise_willread_performance
19436 }
19437 run_test 255a "check 'lfs ladvise -a willread'"
19438
19439 facet_meminfo() {
19440         local facet=$1
19441         local info=$2
19442
19443         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19444 }
19445
19446 test_255b() {
19447         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19448                 skip "lustre < 2.8.54 does not support ladvise "
19449         remote_ost_nodsh && skip "remote OST with nodsh"
19450
19451         lfs setstripe -c 1 -i 0 $DIR/$tfile
19452
19453         ladvise_no_type dontneed $DIR/$tfile &&
19454                 skip "dontneed ladvise is not supported"
19455
19456         ladvise_no_ioctl $DIR/$tfile &&
19457                 skip "ladvise ioctl is not supported"
19458
19459         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19460                 [ "$ost1_FSTYPE" = "zfs" ] &&
19461                 skip "zfs-osd does not support 'ladvise dontneed'"
19462
19463         local size_mb=100
19464         local size=$((size_mb * 1048576))
19465         # In order to prevent disturbance of other processes, only check 3/4
19466         # of the memory usage
19467         local kibibytes=$((size_mb * 1024 * 3 / 4))
19468
19469         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19470                 error "dd to $DIR/$tfile failed"
19471
19472         #force write to complete before dropping OST cache & checking memory
19473         sync
19474
19475         local total=$(facet_meminfo ost1 MemTotal)
19476         echo "Total memory: $total KiB"
19477
19478         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19479         local before_read=$(facet_meminfo ost1 Cached)
19480         echo "Cache used before read: $before_read KiB"
19481
19482         lfs ladvise -a willread $DIR/$tfile ||
19483                 error "Ladvise willread failed"
19484         local after_read=$(facet_meminfo ost1 Cached)
19485         echo "Cache used after read: $after_read KiB"
19486
19487         lfs ladvise -a dontneed $DIR/$tfile ||
19488                 error "Ladvise dontneed again failed"
19489         local no_read=$(facet_meminfo ost1 Cached)
19490         echo "Cache used after dontneed ladvise: $no_read KiB"
19491
19492         if [ $total -lt $((before_read + kibibytes)) ]; then
19493                 echo "Memory is too small, abort checking"
19494                 return 0
19495         fi
19496
19497         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19498                 error "Ladvise willread should use more memory" \
19499                         "than $kibibytes KiB"
19500         fi
19501
19502         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19503                 error "Ladvise dontneed should release more memory" \
19504                         "than $kibibytes KiB"
19505         fi
19506 }
19507 run_test 255b "check 'lfs ladvise -a dontneed'"
19508
19509 test_255c() {
19510         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19511                 skip "lustre < 2.10.50 does not support lockahead"
19512
19513         local count
19514         local new_count
19515         local difference
19516         local i
19517         local rc
19518
19519         test_mkdir -p $DIR/$tdir
19520         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19521
19522         #test 10 returns only success/failure
19523         i=10
19524         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19525         rc=$?
19526         if [ $rc -eq 255 ]; then
19527                 error "Ladvise test${i} failed, ${rc}"
19528         fi
19529
19530         #test 11 counts lock enqueue requests, all others count new locks
19531         i=11
19532         count=$(do_facet ost1 \
19533                 $LCTL get_param -n ost.OSS.ost.stats)
19534         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19535
19536         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19537         rc=$?
19538         if [ $rc -eq 255 ]; then
19539                 error "Ladvise test${i} failed, ${rc}"
19540         fi
19541
19542         new_count=$(do_facet ost1 \
19543                 $LCTL get_param -n ost.OSS.ost.stats)
19544         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19545                    awk '{ print $2 }')
19546
19547         difference="$((new_count - count))"
19548         if [ $difference -ne $rc ]; then
19549                 error "Ladvise test${i}, bad enqueue count, returned " \
19550                       "${rc}, actual ${difference}"
19551         fi
19552
19553         for i in $(seq 12 21); do
19554                 # If we do not do this, we run the risk of having too many
19555                 # locks and starting lock cancellation while we are checking
19556                 # lock counts.
19557                 cancel_lru_locks osc
19558
19559                 count=$($LCTL get_param -n \
19560                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19561
19562                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19563                 rc=$?
19564                 if [ $rc -eq 255 ]; then
19565                         error "Ladvise test ${i} failed, ${rc}"
19566                 fi
19567
19568                 new_count=$($LCTL get_param -n \
19569                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19570                 difference="$((new_count - count))"
19571
19572                 # Test 15 output is divided by 100 to map down to valid return
19573                 if [ $i -eq 15 ]; then
19574                         rc="$((rc * 100))"
19575                 fi
19576
19577                 if [ $difference -ne $rc ]; then
19578                         error "Ladvise test ${i}, bad lock count, returned " \
19579                               "${rc}, actual ${difference}"
19580                 fi
19581         done
19582
19583         #test 22 returns only success/failure
19584         i=22
19585         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19586         rc=$?
19587         if [ $rc -eq 255 ]; then
19588                 error "Ladvise test${i} failed, ${rc}"
19589         fi
19590 }
19591 run_test 255c "suite of ladvise lockahead tests"
19592
19593 test_256() {
19594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19595         remote_mds_nodsh && skip "remote MDS with nodsh"
19596         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19597         changelog_users $SINGLEMDS | grep "^cl" &&
19598                 skip "active changelog user"
19599
19600         local cl_user
19601         local cat_sl
19602         local mdt_dev
19603
19604         mdt_dev=$(mdsdevname 1)
19605         echo $mdt_dev
19606
19607         changelog_register || error "changelog_register failed"
19608
19609         rm -rf $DIR/$tdir
19610         mkdir -p $DIR/$tdir
19611
19612         changelog_clear 0 || error "changelog_clear failed"
19613
19614         # change something
19615         touch $DIR/$tdir/{1..10}
19616
19617         # stop the MDT
19618         stop $SINGLEMDS || error "Fail to stop MDT"
19619
19620         # remount the MDT
19621
19622         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19623
19624         #after mount new plainllog is used
19625         touch $DIR/$tdir/{11..19}
19626         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19627         stack_trap "rm -f $tmpfile"
19628         cat_sl=$(do_facet $SINGLEMDS "sync; \
19629                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19630                  llog_reader $tmpfile | grep -c type=1064553b")
19631         do_facet $SINGLEMDS llog_reader $tmpfile
19632
19633         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19634
19635         changelog_clear 0 || error "changelog_clear failed"
19636
19637         cat_sl=$(do_facet $SINGLEMDS "sync; \
19638                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19639                  llog_reader $tmpfile | grep -c type=1064553b")
19640
19641         if (( cat_sl == 2 )); then
19642                 error "Empty plain llog was not deleted from changelog catalog"
19643         elif (( cat_sl != 1 )); then
19644                 error "Active plain llog shouldn't be deleted from catalog"
19645         fi
19646 }
19647 run_test 256 "Check llog delete for empty and not full state"
19648
19649 test_257() {
19650         remote_mds_nodsh && skip "remote MDS with nodsh"
19651         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19652                 skip "Need MDS version at least 2.8.55"
19653
19654         test_mkdir $DIR/$tdir
19655
19656         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19657                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19658         stat $DIR/$tdir
19659
19660 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19661         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19662         local facet=mds$((mdtidx + 1))
19663         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19664         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19665
19666         stop $facet || error "stop MDS failed"
19667         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19668                 error "start MDS fail"
19669         wait_recovery_complete $facet
19670 }
19671 run_test 257 "xattr locks are not lost"
19672
19673 # Verify we take the i_mutex when security requires it
19674 test_258a() {
19675 #define OBD_FAIL_IMUTEX_SEC 0x141c
19676         $LCTL set_param fail_loc=0x141c
19677         touch $DIR/$tfile
19678         chmod u+s $DIR/$tfile
19679         chmod a+rwx $DIR/$tfile
19680         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19681         RC=$?
19682         if [ $RC -ne 0 ]; then
19683                 error "error, failed to take i_mutex, rc=$?"
19684         fi
19685         rm -f $DIR/$tfile
19686 }
19687 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19688
19689 # Verify we do NOT take the i_mutex in the normal case
19690 test_258b() {
19691 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19692         $LCTL set_param fail_loc=0x141d
19693         touch $DIR/$tfile
19694         chmod a+rwx $DIR
19695         chmod a+rw $DIR/$tfile
19696         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19697         RC=$?
19698         if [ $RC -ne 0 ]; then
19699                 error "error, took i_mutex unnecessarily, rc=$?"
19700         fi
19701         rm -f $DIR/$tfile
19702
19703 }
19704 run_test 258b "verify i_mutex security behavior"
19705
19706 test_259() {
19707         local file=$DIR/$tfile
19708         local before
19709         local after
19710
19711         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19712
19713         stack_trap "rm -f $file" EXIT
19714
19715         wait_delete_completed
19716         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19717         echo "before: $before"
19718
19719         $LFS setstripe -i 0 -c 1 $file
19720         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19721         sync_all_data
19722         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19723         echo "after write: $after"
19724
19725 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19726         do_facet ost1 $LCTL set_param fail_loc=0x2301
19727         $TRUNCATE $file 0
19728         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19729         echo "after truncate: $after"
19730
19731         stop ost1
19732         do_facet ost1 $LCTL set_param fail_loc=0
19733         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19734         sleep 2
19735         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19736         echo "after restart: $after"
19737         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19738                 error "missing truncate?"
19739
19740         return 0
19741 }
19742 run_test 259 "crash at delayed truncate"
19743
19744 test_260() {
19745 #define OBD_FAIL_MDC_CLOSE               0x806
19746         $LCTL set_param fail_loc=0x80000806
19747         touch $DIR/$tfile
19748
19749 }
19750 run_test 260 "Check mdc_close fail"
19751
19752 ### Data-on-MDT sanity tests ###
19753 test_270a() {
19754         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19755                 skip "Need MDS version at least 2.10.55 for DoM"
19756
19757         # create DoM file
19758         local dom=$DIR/$tdir/dom_file
19759         local tmp=$DIR/$tdir/tmp_file
19760
19761         mkdir -p $DIR/$tdir
19762
19763         # basic checks for DoM component creation
19764         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19765                 error "Can set MDT layout to non-first entry"
19766
19767         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19768                 error "Can define multiple entries as MDT layout"
19769
19770         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19771
19772         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19773         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19774         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19775
19776         local mdtidx=$($LFS getstripe -m $dom)
19777         local mdtname=MDT$(printf %04x $mdtidx)
19778         local facet=mds$((mdtidx + 1))
19779         local space_check=1
19780
19781         # Skip free space checks with ZFS
19782         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19783
19784         # write
19785         sync
19786         local size_tmp=$((65536 * 3))
19787         local mdtfree1=$(do_facet $facet \
19788                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19789
19790         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19791         # check also direct IO along write
19792         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19793         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19794         sync
19795         cmp $tmp $dom || error "file data is different"
19796         [ $(stat -c%s $dom) == $size_tmp ] ||
19797                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19798         if [ $space_check == 1 ]; then
19799                 local mdtfree2=$(do_facet $facet \
19800                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19801
19802                 # increase in usage from by $size_tmp
19803                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19804                         error "MDT free space wrong after write: " \
19805                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19806         fi
19807
19808         # truncate
19809         local size_dom=10000
19810
19811         $TRUNCATE $dom $size_dom
19812         [ $(stat -c%s $dom) == $size_dom ] ||
19813                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19814         if [ $space_check == 1 ]; then
19815                 mdtfree1=$(do_facet $facet \
19816                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19817                 # decrease in usage from $size_tmp to new $size_dom
19818                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19819                   $(((size_tmp - size_dom) / 1024)) ] ||
19820                         error "MDT free space is wrong after truncate: " \
19821                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19822         fi
19823
19824         # append
19825         cat $tmp >> $dom
19826         sync
19827         size_dom=$((size_dom + size_tmp))
19828         [ $(stat -c%s $dom) == $size_dom ] ||
19829                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19830         if [ $space_check == 1 ]; then
19831                 mdtfree2=$(do_facet $facet \
19832                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19833                 # increase in usage by $size_tmp from previous
19834                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19835                         error "MDT free space is wrong after append: " \
19836                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19837         fi
19838
19839         # delete
19840         rm $dom
19841         if [ $space_check == 1 ]; then
19842                 mdtfree1=$(do_facet $facet \
19843                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19844                 # decrease in usage by $size_dom from previous
19845                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
19846                         error "MDT free space is wrong after removal: " \
19847                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
19848         fi
19849
19850         # combined striping
19851         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
19852                 error "Can't create DoM + OST striping"
19853
19854         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
19855         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19856         # check also direct IO along write
19857         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19858         sync
19859         cmp $tmp $dom || error "file data is different"
19860         [ $(stat -c%s $dom) == $size_tmp ] ||
19861                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19862         rm $dom $tmp
19863
19864         return 0
19865 }
19866 run_test 270a "DoM: basic functionality tests"
19867
19868 test_270b() {
19869         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19870                 skip "Need MDS version at least 2.10.55"
19871
19872         local dom=$DIR/$tdir/dom_file
19873         local max_size=1048576
19874
19875         mkdir -p $DIR/$tdir
19876         $LFS setstripe -E $max_size -L mdt $dom
19877
19878         # truncate over the limit
19879         $TRUNCATE $dom $(($max_size + 1)) &&
19880                 error "successful truncate over the maximum size"
19881         # write over the limit
19882         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
19883                 error "successful write over the maximum size"
19884         # append over the limit
19885         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
19886         echo "12345" >> $dom && error "successful append over the maximum size"
19887         rm $dom
19888
19889         return 0
19890 }
19891 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
19892
19893 test_270c() {
19894         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19895                 skip "Need MDS version at least 2.10.55"
19896
19897         mkdir -p $DIR/$tdir
19898         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19899
19900         # check files inherit DoM EA
19901         touch $DIR/$tdir/first
19902         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
19903                 error "bad pattern"
19904         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
19905                 error "bad stripe count"
19906         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
19907                 error "bad stripe size"
19908
19909         # check directory inherits DoM EA and uses it as default
19910         mkdir $DIR/$tdir/subdir
19911         touch $DIR/$tdir/subdir/second
19912         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
19913                 error "bad pattern in sub-directory"
19914         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
19915                 error "bad stripe count in sub-directory"
19916         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
19917                 error "bad stripe size in sub-directory"
19918         return 0
19919 }
19920 run_test 270c "DoM: DoM EA inheritance tests"
19921
19922 test_270d() {
19923         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19924                 skip "Need MDS version at least 2.10.55"
19925
19926         mkdir -p $DIR/$tdir
19927         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19928
19929         # inherit default DoM striping
19930         mkdir $DIR/$tdir/subdir
19931         touch $DIR/$tdir/subdir/f1
19932
19933         # change default directory striping
19934         $LFS setstripe -c 1 $DIR/$tdir/subdir
19935         touch $DIR/$tdir/subdir/f2
19936         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
19937                 error "wrong default striping in file 2"
19938         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
19939                 error "bad pattern in file 2"
19940         return 0
19941 }
19942 run_test 270d "DoM: change striping from DoM to RAID0"
19943
19944 test_270e() {
19945         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19946                 skip "Need MDS version at least 2.10.55"
19947
19948         mkdir -p $DIR/$tdir/dom
19949         mkdir -p $DIR/$tdir/norm
19950         DOMFILES=20
19951         NORMFILES=10
19952         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
19953         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
19954
19955         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
19956         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
19957
19958         # find DoM files by layout
19959         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
19960         [ $NUM -eq  $DOMFILES ] ||
19961                 error "lfs find -L: found $NUM, expected $DOMFILES"
19962         echo "Test 1: lfs find 20 DOM files by layout: OK"
19963
19964         # there should be 1 dir with default DOM striping
19965         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
19966         [ $NUM -eq  1 ] ||
19967                 error "lfs find -L: found $NUM, expected 1 dir"
19968         echo "Test 2: lfs find 1 DOM dir by layout: OK"
19969
19970         # find DoM files by stripe size
19971         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
19972         [ $NUM -eq  $DOMFILES ] ||
19973                 error "lfs find -S: found $NUM, expected $DOMFILES"
19974         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
19975
19976         # find files by stripe offset except DoM files
19977         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
19978         [ $NUM -eq  $NORMFILES ] ||
19979                 error "lfs find -i: found $NUM, expected $NORMFILES"
19980         echo "Test 5: lfs find no DOM files by stripe index: OK"
19981         return 0
19982 }
19983 run_test 270e "DoM: lfs find with DoM files test"
19984
19985 test_270f() {
19986         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19987                 skip "Need MDS version at least 2.10.55"
19988
19989         local mdtname=${FSNAME}-MDT0000-mdtlov
19990         local dom=$DIR/$tdir/dom_file
19991         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
19992                                                 lod.$mdtname.dom_stripesize)
19993         local dom_limit=131072
19994
19995         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
19996         local dom_current=$(do_facet mds1 $LCTL get_param -n \
19997                                                 lod.$mdtname.dom_stripesize)
19998         [ ${dom_limit} -eq ${dom_current} ] ||
19999                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20000
20001         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20002         $LFS setstripe -d $DIR/$tdir
20003         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20004                 error "Can't set directory default striping"
20005
20006         # exceed maximum stripe size
20007         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20008                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20009         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20010                 error "Able to create DoM component size more than LOD limit"
20011
20012         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20013         dom_current=$(do_facet mds1 $LCTL get_param -n \
20014                                                 lod.$mdtname.dom_stripesize)
20015         [ 0 -eq ${dom_current} ] ||
20016                 error "Can't set zero DoM stripe limit"
20017         rm $dom
20018
20019         # attempt to create DoM file on server with disabled DoM should
20020         # remove DoM entry from layout and be succeed
20021         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20022                 error "Can't create DoM file (DoM is disabled)"
20023         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20024                 error "File has DoM component while DoM is disabled"
20025         rm $dom
20026
20027         # attempt to create DoM file with only DoM stripe should return error
20028         $LFS setstripe -E $dom_limit -L mdt $dom &&
20029                 error "Able to create DoM-only file while DoM is disabled"
20030
20031         # too low values to be aligned with smallest stripe size 64K
20032         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20033         dom_current=$(do_facet mds1 $LCTL get_param -n \
20034                                                 lod.$mdtname.dom_stripesize)
20035         [ 30000 -eq ${dom_current} ] &&
20036                 error "Can set too small DoM stripe limit"
20037
20038         # 64K is a minimal stripe size in Lustre, expect limit of that size
20039         [ 65536 -eq ${dom_current} ] ||
20040                 error "Limit is not set to 64K but ${dom_current}"
20041
20042         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20043         dom_current=$(do_facet mds1 $LCTL get_param -n \
20044                                                 lod.$mdtname.dom_stripesize)
20045         echo $dom_current
20046         [ 2147483648 -eq ${dom_current} ] &&
20047                 error "Can set too large DoM stripe limit"
20048
20049         do_facet mds1 $LCTL set_param -n \
20050                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20051         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20052                 error "Can't create DoM component size after limit change"
20053         do_facet mds1 $LCTL set_param -n \
20054                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20055         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20056                 error "Can't create DoM file after limit decrease"
20057         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20058                 error "Can create big DoM component after limit decrease"
20059         touch ${dom}_def ||
20060                 error "Can't create file with old default layout"
20061
20062         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20063         return 0
20064 }
20065 run_test 270f "DoM: maximum DoM stripe size checks"
20066
20067 test_270g() {
20068         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20069                 skip "Need MDS version at least 2.13.52"
20070         local dom=$DIR/$tdir/$tfile
20071
20072         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20073         local lodname=${FSNAME}-MDT0000-mdtlov
20074
20075         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20076         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20077         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20078         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20079
20080         local dom_limit=1024
20081         local dom_threshold="50%"
20082
20083         $LFS setstripe -d $DIR/$tdir
20084         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20085                 error "Can't set directory default striping"
20086
20087         do_facet mds1 $LCTL set_param -n \
20088                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20089         # set 0 threshold and create DOM file to change tunable stripesize
20090         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20091         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20092                 error "Failed to create $dom file"
20093         # now tunable dom_cur_stripesize should reach maximum
20094         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20095                                         lod.${lodname}.dom_stripesize_cur_kb)
20096         [[ $dom_current == $dom_limit ]] ||
20097                 error "Current DOM stripesize is not maximum"
20098         rm $dom
20099
20100         # set threshold for further tests
20101         do_facet mds1 $LCTL set_param -n \
20102                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20103         echo "DOM threshold is $dom_threshold free space"
20104         local dom_def
20105         local dom_set
20106         # Spoof bfree to exceed threshold
20107         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20108         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20109         for spfree in 40 20 0 15 30 55; do
20110                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20111                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20112                         error "Failed to create $dom file"
20113                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20114                                         lod.${lodname}.dom_stripesize_cur_kb)
20115                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20116                 [[ $dom_def != $dom_current ]] ||
20117                         error "Default stripe size was not changed"
20118                 if [[ $spfree > 0 ]] ; then
20119                         dom_set=$($LFS getstripe -S $dom)
20120                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20121                                 error "DOM component size is still old"
20122                 else
20123                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20124                                 error "DoM component is set with no free space"
20125                 fi
20126                 rm $dom
20127                 dom_current=$dom_def
20128         done
20129 }
20130 run_test 270g "DoM: default DoM stripe size depends on free space"
20131
20132 test_270h() {
20133         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20134                 skip "Need MDS version at least 2.13.53"
20135
20136         local mdtname=${FSNAME}-MDT0000-mdtlov
20137         local dom=$DIR/$tdir/$tfile
20138         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20139
20140         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20141         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20142
20143         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20144         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20145                 error "can't create OST file"
20146         # mirrored file with DOM entry in the second mirror
20147         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20148                 error "can't create mirror with DoM component"
20149
20150         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20151
20152         # DOM component in the middle and has other enries in the same mirror,
20153         # should succeed but lost DoM component
20154         $LFS setstripe --copy=${dom}_1 $dom ||
20155                 error "Can't create file from OST|DOM mirror layout"
20156         # check new file has no DoM layout after all
20157         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20158                 error "File has DoM component while DoM is disabled"
20159 }
20160 run_test 270h "DoM: DoM stripe removal when disabled on server"
20161
20162 test_271a() {
20163         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20164                 skip "Need MDS version at least 2.10.55"
20165
20166         local dom=$DIR/$tdir/dom
20167
20168         mkdir -p $DIR/$tdir
20169
20170         $LFS setstripe -E 1024K -L mdt $dom
20171
20172         lctl set_param -n mdc.*.stats=clear
20173         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20174         cat $dom > /dev/null
20175         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20176         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20177         ls $dom
20178         rm -f $dom
20179 }
20180 run_test 271a "DoM: data is cached for read after write"
20181
20182 test_271b() {
20183         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20184                 skip "Need MDS version at least 2.10.55"
20185
20186         local dom=$DIR/$tdir/dom
20187
20188         mkdir -p $DIR/$tdir
20189
20190         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20191
20192         lctl set_param -n mdc.*.stats=clear
20193         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20194         cancel_lru_locks mdc
20195         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20196         # second stat to check size is cached on client
20197         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20198         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20199         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20200         rm -f $dom
20201 }
20202 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20203
20204 test_271ba() {
20205         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20206                 skip "Need MDS version at least 2.10.55"
20207
20208         local dom=$DIR/$tdir/dom
20209
20210         mkdir -p $DIR/$tdir
20211
20212         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20213
20214         lctl set_param -n mdc.*.stats=clear
20215         lctl set_param -n osc.*.stats=clear
20216         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20217         cancel_lru_locks mdc
20218         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20219         # second stat to check size is cached on client
20220         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20221         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20222         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20223         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20224         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20225         rm -f $dom
20226 }
20227 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20228
20229
20230 get_mdc_stats() {
20231         local mdtidx=$1
20232         local param=$2
20233         local mdt=MDT$(printf %04x $mdtidx)
20234
20235         if [ -z $param ]; then
20236                 lctl get_param -n mdc.*$mdt*.stats
20237         else
20238                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20239         fi
20240 }
20241
20242 test_271c() {
20243         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20244                 skip "Need MDS version at least 2.10.55"
20245
20246         local dom=$DIR/$tdir/dom
20247
20248         mkdir -p $DIR/$tdir
20249
20250         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20251
20252         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20253         local facet=mds$((mdtidx + 1))
20254
20255         cancel_lru_locks mdc
20256         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20257         createmany -o $dom 1000
20258         lctl set_param -n mdc.*.stats=clear
20259         smalliomany -w $dom 1000 200
20260         get_mdc_stats $mdtidx
20261         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20262         # Each file has 1 open, 1 IO enqueues, total 2000
20263         # but now we have also +1 getxattr for security.capability, total 3000
20264         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20265         unlinkmany $dom 1000
20266
20267         cancel_lru_locks mdc
20268         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20269         createmany -o $dom 1000
20270         lctl set_param -n mdc.*.stats=clear
20271         smalliomany -w $dom 1000 200
20272         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20273         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20274         # for OPEN and IO lock.
20275         [ $((enq - enq_2)) -ge 1000 ] ||
20276                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20277         unlinkmany $dom 1000
20278         return 0
20279 }
20280 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20281
20282 cleanup_271def_tests() {
20283         trap 0
20284         rm -f $1
20285 }
20286
20287 test_271d() {
20288         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20289                 skip "Need MDS version at least 2.10.57"
20290
20291         local dom=$DIR/$tdir/dom
20292         local tmp=$TMP/$tfile
20293         trap "cleanup_271def_tests $tmp" EXIT
20294
20295         mkdir -p $DIR/$tdir
20296
20297         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20298
20299         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20300
20301         cancel_lru_locks mdc
20302         dd if=/dev/urandom of=$tmp bs=1000 count=1
20303         dd if=$tmp of=$dom bs=1000 count=1
20304         cancel_lru_locks mdc
20305
20306         cat /etc/hosts >> $tmp
20307         lctl set_param -n mdc.*.stats=clear
20308
20309         # append data to the same file it should update local page
20310         echo "Append to the same page"
20311         cat /etc/hosts >> $dom
20312         local num=$(get_mdc_stats $mdtidx ost_read)
20313         local ra=$(get_mdc_stats $mdtidx req_active)
20314         local rw=$(get_mdc_stats $mdtidx req_waittime)
20315
20316         [ -z $num ] || error "$num READ RPC occured"
20317         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20318         echo "... DONE"
20319
20320         # compare content
20321         cmp $tmp $dom || error "file miscompare"
20322
20323         cancel_lru_locks mdc
20324         lctl set_param -n mdc.*.stats=clear
20325
20326         echo "Open and read file"
20327         cat $dom > /dev/null
20328         local num=$(get_mdc_stats $mdtidx ost_read)
20329         local ra=$(get_mdc_stats $mdtidx req_active)
20330         local rw=$(get_mdc_stats $mdtidx req_waittime)
20331
20332         [ -z $num ] || error "$num READ RPC occured"
20333         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20334         echo "... DONE"
20335
20336         # compare content
20337         cmp $tmp $dom || error "file miscompare"
20338
20339         return 0
20340 }
20341 run_test 271d "DoM: read on open (1K file in reply buffer)"
20342
20343 test_271f() {
20344         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20345                 skip "Need MDS version at least 2.10.57"
20346
20347         local dom=$DIR/$tdir/dom
20348         local tmp=$TMP/$tfile
20349         trap "cleanup_271def_tests $tmp" EXIT
20350
20351         mkdir -p $DIR/$tdir
20352
20353         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20354
20355         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20356
20357         cancel_lru_locks mdc
20358         dd if=/dev/urandom of=$tmp bs=265000 count=1
20359         dd if=$tmp of=$dom bs=265000 count=1
20360         cancel_lru_locks mdc
20361         cat /etc/hosts >> $tmp
20362         lctl set_param -n mdc.*.stats=clear
20363
20364         echo "Append to the same page"
20365         cat /etc/hosts >> $dom
20366         local num=$(get_mdc_stats $mdtidx ost_read)
20367         local ra=$(get_mdc_stats $mdtidx req_active)
20368         local rw=$(get_mdc_stats $mdtidx req_waittime)
20369
20370         [ -z $num ] || error "$num READ RPC occured"
20371         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20372         echo "... DONE"
20373
20374         # compare content
20375         cmp $tmp $dom || error "file miscompare"
20376
20377         cancel_lru_locks mdc
20378         lctl set_param -n mdc.*.stats=clear
20379
20380         echo "Open and read file"
20381         cat $dom > /dev/null
20382         local num=$(get_mdc_stats $mdtidx ost_read)
20383         local ra=$(get_mdc_stats $mdtidx req_active)
20384         local rw=$(get_mdc_stats $mdtidx req_waittime)
20385
20386         [ -z $num ] && num=0
20387         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20388         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20389         echo "... DONE"
20390
20391         # compare content
20392         cmp $tmp $dom || error "file miscompare"
20393
20394         return 0
20395 }
20396 run_test 271f "DoM: read on open (200K file and read tail)"
20397
20398 test_271g() {
20399         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20400                 skip "Skipping due to old client or server version"
20401
20402         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20403         # to get layout
20404         $CHECKSTAT -t file $DIR1/$tfile
20405
20406         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20407         MULTIOP_PID=$!
20408         sleep 1
20409         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20410         $LCTL set_param fail_loc=0x80000314
20411         rm $DIR1/$tfile || error "Unlink fails"
20412         RC=$?
20413         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20414         [ $RC -eq 0 ] || error "Failed write to stale object"
20415 }
20416 run_test 271g "Discard DoM data vs client flush race"
20417
20418 test_272a() {
20419         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20420                 skip "Need MDS version at least 2.11.50"
20421
20422         local dom=$DIR/$tdir/dom
20423         mkdir -p $DIR/$tdir
20424
20425         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20426         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20427                 error "failed to write data into $dom"
20428         local old_md5=$(md5sum $dom)
20429
20430         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20431                 error "failed to migrate to the same DoM component"
20432
20433         local new_md5=$(md5sum $dom)
20434
20435         [ "$old_md5" == "$new_md5" ] ||
20436                 error "md5sum differ: $old_md5, $new_md5"
20437
20438         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20439                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20440 }
20441 run_test 272a "DoM migration: new layout with the same DOM component"
20442
20443 test_272b() {
20444         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20445                 skip "Need MDS version at least 2.11.50"
20446
20447         local dom=$DIR/$tdir/dom
20448         mkdir -p $DIR/$tdir
20449         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20450
20451         local mdtidx=$($LFS getstripe -m $dom)
20452         local mdtname=MDT$(printf %04x $mdtidx)
20453         local facet=mds$((mdtidx + 1))
20454
20455         local mdtfree1=$(do_facet $facet \
20456                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20457         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20458                 error "failed to write data into $dom"
20459         local old_md5=$(md5sum $dom)
20460         cancel_lru_locks mdc
20461         local mdtfree1=$(do_facet $facet \
20462                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20463
20464         $LFS migrate -c2 $dom ||
20465                 error "failed to migrate to the new composite layout"
20466         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20467                 error "MDT stripe was not removed"
20468
20469         cancel_lru_locks mdc
20470         local new_md5=$(md5sum $dom)
20471         [ "$old_md5" == "$new_md5" ] ||
20472                 error "$old_md5 != $new_md5"
20473
20474         # Skip free space checks with ZFS
20475         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20476                 local mdtfree2=$(do_facet $facet \
20477                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20478                 [ $mdtfree2 -gt $mdtfree1 ] ||
20479                         error "MDT space is not freed after migration"
20480         fi
20481         return 0
20482 }
20483 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20484
20485 test_272c() {
20486         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20487                 skip "Need MDS version at least 2.11.50"
20488
20489         local dom=$DIR/$tdir/$tfile
20490         mkdir -p $DIR/$tdir
20491         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20492
20493         local mdtidx=$($LFS getstripe -m $dom)
20494         local mdtname=MDT$(printf %04x $mdtidx)
20495         local facet=mds$((mdtidx + 1))
20496
20497         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20498                 error "failed to write data into $dom"
20499         local old_md5=$(md5sum $dom)
20500         cancel_lru_locks mdc
20501         local mdtfree1=$(do_facet $facet \
20502                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20503
20504         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20505                 error "failed to migrate to the new composite layout"
20506         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20507                 error "MDT stripe was not removed"
20508
20509         cancel_lru_locks mdc
20510         local new_md5=$(md5sum $dom)
20511         [ "$old_md5" == "$new_md5" ] ||
20512                 error "$old_md5 != $new_md5"
20513
20514         # Skip free space checks with ZFS
20515         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20516                 local mdtfree2=$(do_facet $facet \
20517                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20518                 [ $mdtfree2 -gt $mdtfree1 ] ||
20519                         error "MDS space is not freed after migration"
20520         fi
20521         return 0
20522 }
20523 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20524
20525 test_272d() {
20526         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20527                 skip "Need MDS version at least 2.12.55"
20528
20529         local dom=$DIR/$tdir/$tfile
20530         mkdir -p $DIR/$tdir
20531         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20532
20533         local mdtidx=$($LFS getstripe -m $dom)
20534         local mdtname=MDT$(printf %04x $mdtidx)
20535         local facet=mds$((mdtidx + 1))
20536
20537         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20538                 error "failed to write data into $dom"
20539         local old_md5=$(md5sum $dom)
20540         cancel_lru_locks mdc
20541         local mdtfree1=$(do_facet $facet \
20542                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20543
20544         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20545                 error "failed mirroring to the new composite layout"
20546         $LFS mirror resync $dom ||
20547                 error "failed mirror resync"
20548         $LFS mirror split --mirror-id 1 -d $dom ||
20549                 error "failed mirror split"
20550
20551         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20552                 error "MDT stripe was not removed"
20553
20554         cancel_lru_locks mdc
20555         local new_md5=$(md5sum $dom)
20556         [ "$old_md5" == "$new_md5" ] ||
20557                 error "$old_md5 != $new_md5"
20558
20559         # Skip free space checks with ZFS
20560         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20561                 local mdtfree2=$(do_facet $facet \
20562                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20563                 [ $mdtfree2 -gt $mdtfree1 ] ||
20564                         error "MDS space is not freed after DOM mirror deletion"
20565         fi
20566         return 0
20567 }
20568 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20569
20570 test_272e() {
20571         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20572                 skip "Need MDS version at least 2.12.55"
20573
20574         local dom=$DIR/$tdir/$tfile
20575         mkdir -p $DIR/$tdir
20576         $LFS setstripe -c 2 $dom
20577
20578         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20579                 error "failed to write data into $dom"
20580         local old_md5=$(md5sum $dom)
20581         cancel_lru_locks mdc
20582
20583         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20584                 error "failed mirroring to the DOM layout"
20585         $LFS mirror resync $dom ||
20586                 error "failed mirror resync"
20587         $LFS mirror split --mirror-id 1 -d $dom ||
20588                 error "failed mirror split"
20589
20590         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20591                 error "MDT stripe was not removed"
20592
20593         cancel_lru_locks mdc
20594         local new_md5=$(md5sum $dom)
20595         [ "$old_md5" == "$new_md5" ] ||
20596                 error "$old_md5 != $new_md5"
20597
20598         return 0
20599 }
20600 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20601
20602 test_272f() {
20603         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20604                 skip "Need MDS version at least 2.12.55"
20605
20606         local dom=$DIR/$tdir/$tfile
20607         mkdir -p $DIR/$tdir
20608         $LFS setstripe -c 2 $dom
20609
20610         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20611                 error "failed to write data into $dom"
20612         local old_md5=$(md5sum $dom)
20613         cancel_lru_locks mdc
20614
20615         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20616                 error "failed migrating to the DOM file"
20617
20618         cancel_lru_locks mdc
20619         local new_md5=$(md5sum $dom)
20620         [ "$old_md5" != "$new_md5" ] &&
20621                 error "$old_md5 != $new_md5"
20622
20623         return 0
20624 }
20625 run_test 272f "DoM migration: OST-striped file to DOM file"
20626
20627 test_273a() {
20628         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20629                 skip "Need MDS version at least 2.11.50"
20630
20631         # Layout swap cannot be done if either file has DOM component,
20632         # this will never be supported, migration should be used instead
20633
20634         local dom=$DIR/$tdir/$tfile
20635         mkdir -p $DIR/$tdir
20636
20637         $LFS setstripe -c2 ${dom}_plain
20638         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20639         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20640                 error "can swap layout with DoM component"
20641         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20642                 error "can swap layout with DoM component"
20643
20644         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20645         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20646                 error "can swap layout with DoM component"
20647         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20648                 error "can swap layout with DoM component"
20649         return 0
20650 }
20651 run_test 273a "DoM: layout swapping should fail with DOM"
20652
20653 test_275() {
20654         remote_ost_nodsh && skip "remote OST with nodsh"
20655         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20656                 skip "Need OST version >= 2.10.57"
20657
20658         local file=$DIR/$tfile
20659         local oss
20660
20661         oss=$(comma_list $(osts_nodes))
20662
20663         dd if=/dev/urandom of=$file bs=1M count=2 ||
20664                 error "failed to create a file"
20665         cancel_lru_locks osc
20666
20667         #lock 1
20668         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20669                 error "failed to read a file"
20670
20671 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20672         $LCTL set_param fail_loc=0x8000031f
20673
20674         cancel_lru_locks osc &
20675         sleep 1
20676
20677 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20678         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20679         #IO takes another lock, but matches the PENDING one
20680         #and places it to the IO RPC
20681         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20682                 error "failed to read a file with PENDING lock"
20683 }
20684 run_test 275 "Read on a canceled duplicate lock"
20685
20686 test_276() {
20687         remote_ost_nodsh && skip "remote OST with nodsh"
20688         local pid
20689
20690         do_facet ost1 "(while true; do \
20691                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20692                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20693         pid=$!
20694
20695         for LOOP in $(seq 20); do
20696                 stop ost1
20697                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20698         done
20699         kill -9 $pid
20700         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20701                 rm $TMP/sanity_276_pid"
20702 }
20703 run_test 276 "Race between mount and obd_statfs"
20704
20705 test_277() {
20706         $LCTL set_param ldlm.namespaces.*.lru_size=0
20707         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20708         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20709                         grep ^used_mb | awk '{print $2}')
20710         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20711         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20712                 oflag=direct conv=notrunc
20713         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20714                         grep ^used_mb | awk '{print $2}')
20715         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20716 }
20717 run_test 277 "Direct IO shall drop page cache"
20718
20719 test_278() {
20720         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20721         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20722         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20723                 skip "needs the same host for mdt1 mdt2" && return
20724
20725         local pid1
20726         local pid2
20727
20728 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20729         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20730         stop mds2 &
20731         pid2=$!
20732
20733         stop mds1
20734
20735         echo "Starting MDTs"
20736         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20737         wait $pid2
20738 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20739 #will return NULL
20740         do_facet mds2 $LCTL set_param fail_loc=0
20741
20742         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20743         wait_recovery_complete mds2
20744 }
20745 run_test 278 "Race starting MDS between MDTs stop/start"
20746
20747 test_280() {
20748         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20749                 skip "Need MGS version at least 2.13.52"
20750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20751         combined_mgs_mds || skip "needs combined MGS/MDT"
20752
20753         umount_client $MOUNT
20754 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20755         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20756
20757         mount_client $MOUNT &
20758         sleep 1
20759         stop mgs || error "stop mgs failed"
20760         #for a race mgs would crash
20761         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20762         mount_client $MOUNT || error "mount client failed"
20763 }
20764 run_test 280 "Race between MGS umount and client llog processing"
20765
20766 cleanup_test_300() {
20767         trap 0
20768         umask $SAVE_UMASK
20769 }
20770 test_striped_dir() {
20771         local mdt_index=$1
20772         local stripe_count
20773         local stripe_index
20774
20775         mkdir -p $DIR/$tdir
20776
20777         SAVE_UMASK=$(umask)
20778         trap cleanup_test_300 RETURN EXIT
20779
20780         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20781                                                 $DIR/$tdir/striped_dir ||
20782                 error "set striped dir error"
20783
20784         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20785         [ "$mode" = "755" ] || error "expect 755 got $mode"
20786
20787         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20788                 error "getdirstripe failed"
20789         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20790         if [ "$stripe_count" != "2" ]; then
20791                 error "1:stripe_count is $stripe_count, expect 2"
20792         fi
20793         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20794         if [ "$stripe_count" != "2" ]; then
20795                 error "2:stripe_count is $stripe_count, expect 2"
20796         fi
20797
20798         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20799         if [ "$stripe_index" != "$mdt_index" ]; then
20800                 error "stripe_index is $stripe_index, expect $mdt_index"
20801         fi
20802
20803         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20804                 error "nlink error after create striped dir"
20805
20806         mkdir $DIR/$tdir/striped_dir/a
20807         mkdir $DIR/$tdir/striped_dir/b
20808
20809         stat $DIR/$tdir/striped_dir/a ||
20810                 error "create dir under striped dir failed"
20811         stat $DIR/$tdir/striped_dir/b ||
20812                 error "create dir under striped dir failed"
20813
20814         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20815                 error "nlink error after mkdir"
20816
20817         rmdir $DIR/$tdir/striped_dir/a
20818         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20819                 error "nlink error after rmdir"
20820
20821         rmdir $DIR/$tdir/striped_dir/b
20822         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20823                 error "nlink error after rmdir"
20824
20825         chattr +i $DIR/$tdir/striped_dir
20826         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20827                 error "immutable flags not working under striped dir!"
20828         chattr -i $DIR/$tdir/striped_dir
20829
20830         rmdir $DIR/$tdir/striped_dir ||
20831                 error "rmdir striped dir error"
20832
20833         cleanup_test_300
20834
20835         true
20836 }
20837
20838 test_300a() {
20839         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20840                 skip "skipped for lustre < 2.7.0"
20841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20842         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20843
20844         test_striped_dir 0 || error "failed on striped dir on MDT0"
20845         test_striped_dir 1 || error "failed on striped dir on MDT0"
20846 }
20847 run_test 300a "basic striped dir sanity test"
20848
20849 test_300b() {
20850         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20851                 skip "skipped for lustre < 2.7.0"
20852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20853         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20854
20855         local i
20856         local mtime1
20857         local mtime2
20858         local mtime3
20859
20860         test_mkdir $DIR/$tdir || error "mkdir fail"
20861         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20862                 error "set striped dir error"
20863         for i in {0..9}; do
20864                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
20865                 sleep 1
20866                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
20867                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
20868                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
20869                 sleep 1
20870                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
20871                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
20872                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
20873         done
20874         true
20875 }
20876 run_test 300b "check ctime/mtime for striped dir"
20877
20878 test_300c() {
20879         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20880                 skip "skipped for lustre < 2.7.0"
20881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20882         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20883
20884         local file_count
20885
20886         mkdir -p $DIR/$tdir
20887         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
20888                 error "set striped dir error"
20889
20890         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
20891                 error "chown striped dir failed"
20892
20893         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
20894                 error "create 5k files failed"
20895
20896         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
20897
20898         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
20899
20900         rm -rf $DIR/$tdir
20901 }
20902 run_test 300c "chown && check ls under striped directory"
20903
20904 test_300d() {
20905         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20906                 skip "skipped for lustre < 2.7.0"
20907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20908         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20909
20910         local stripe_count
20911         local file
20912
20913         mkdir -p $DIR/$tdir
20914         $LFS setstripe -c 2 $DIR/$tdir
20915
20916         #local striped directory
20917         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20918                 error "set striped dir error"
20919         #look at the directories for debug purposes
20920         ls -l $DIR/$tdir
20921         $LFS getdirstripe $DIR/$tdir
20922         ls -l $DIR/$tdir/striped_dir
20923         $LFS getdirstripe $DIR/$tdir/striped_dir
20924         createmany -o $DIR/$tdir/striped_dir/f 10 ||
20925                 error "create 10 files failed"
20926
20927         #remote striped directory
20928         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
20929                 error "set striped dir error"
20930         #look at the directories for debug purposes
20931         ls -l $DIR/$tdir
20932         $LFS getdirstripe $DIR/$tdir
20933         ls -l $DIR/$tdir/remote_striped_dir
20934         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
20935         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
20936                 error "create 10 files failed"
20937
20938         for file in $(find $DIR/$tdir); do
20939                 stripe_count=$($LFS getstripe -c $file)
20940                 [ $stripe_count -eq 2 ] ||
20941                         error "wrong stripe $stripe_count for $file"
20942         done
20943
20944         rm -rf $DIR/$tdir
20945 }
20946 run_test 300d "check default stripe under striped directory"
20947
20948 test_300e() {
20949         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20950                 skip "Need MDS version at least 2.7.55"
20951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20952         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20953
20954         local stripe_count
20955         local file
20956
20957         mkdir -p $DIR/$tdir
20958
20959         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20960                 error "set striped dir error"
20961
20962         touch $DIR/$tdir/striped_dir/a
20963         touch $DIR/$tdir/striped_dir/b
20964         touch $DIR/$tdir/striped_dir/c
20965
20966         mkdir $DIR/$tdir/striped_dir/dir_a
20967         mkdir $DIR/$tdir/striped_dir/dir_b
20968         mkdir $DIR/$tdir/striped_dir/dir_c
20969
20970         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
20971                 error "set striped adir under striped dir error"
20972
20973         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
20974                 error "set striped bdir under striped dir error"
20975
20976         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
20977                 error "set striped cdir under striped dir error"
20978
20979         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
20980                 error "rename dir under striped dir fails"
20981
20982         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
20983                 error "rename dir under different stripes fails"
20984
20985         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
20986                 error "rename file under striped dir should succeed"
20987
20988         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
20989                 error "rename dir under striped dir should succeed"
20990
20991         rm -rf $DIR/$tdir
20992 }
20993 run_test 300e "check rename under striped directory"
20994
20995 test_300f() {
20996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20997         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20998         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20999                 skip "Need MDS version at least 2.7.55"
21000
21001         local stripe_count
21002         local file
21003
21004         rm -rf $DIR/$tdir
21005         mkdir -p $DIR/$tdir
21006
21007         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21008                 error "set striped dir error"
21009
21010         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21011                 error "set striped dir error"
21012
21013         touch $DIR/$tdir/striped_dir/a
21014         mkdir $DIR/$tdir/striped_dir/dir_a
21015         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21016                 error "create striped dir under striped dir fails"
21017
21018         touch $DIR/$tdir/striped_dir1/b
21019         mkdir $DIR/$tdir/striped_dir1/dir_b
21020         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21021                 error "create striped dir under striped dir fails"
21022
21023         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21024                 error "rename dir under different striped dir should fail"
21025
21026         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21027                 error "rename striped dir under diff striped dir should fail"
21028
21029         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21030                 error "rename file under diff striped dirs fails"
21031
21032         rm -rf $DIR/$tdir
21033 }
21034 run_test 300f "check rename cross striped directory"
21035
21036 test_300_check_default_striped_dir()
21037 {
21038         local dirname=$1
21039         local default_count=$2
21040         local default_index=$3
21041         local stripe_count
21042         local stripe_index
21043         local dir_stripe_index
21044         local dir
21045
21046         echo "checking $dirname $default_count $default_index"
21047         $LFS setdirstripe -D -c $default_count -i $default_index \
21048                                 -t all_char $DIR/$tdir/$dirname ||
21049                 error "set default stripe on striped dir error"
21050         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21051         [ $stripe_count -eq $default_count ] ||
21052                 error "expect $default_count get $stripe_count for $dirname"
21053
21054         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21055         [ $stripe_index -eq $default_index ] ||
21056                 error "expect $default_index get $stripe_index for $dirname"
21057
21058         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21059                                                 error "create dirs failed"
21060
21061         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21062         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21063         for dir in $(find $DIR/$tdir/$dirname/*); do
21064                 stripe_count=$($LFS getdirstripe -c $dir)
21065                 [ $stripe_count -eq $default_count ] ||
21066                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21067                 error "stripe count $default_count != $stripe_count for $dir"
21068
21069                 stripe_index=$($LFS getdirstripe -i $dir)
21070                 [ $default_index -eq -1 ] ||
21071                         [ $stripe_index -eq $default_index ] ||
21072                         error "$stripe_index != $default_index for $dir"
21073
21074                 #check default stripe
21075                 stripe_count=$($LFS getdirstripe -D -c $dir)
21076                 [ $stripe_count -eq $default_count ] ||
21077                 error "default count $default_count != $stripe_count for $dir"
21078
21079                 stripe_index=$($LFS getdirstripe -D -i $dir)
21080                 [ $stripe_index -eq $default_index ] ||
21081                 error "default index $default_index != $stripe_index for $dir"
21082         done
21083         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21084 }
21085
21086 test_300g() {
21087         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21088         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21089                 skip "Need MDS version at least 2.7.55"
21090
21091         local dir
21092         local stripe_count
21093         local stripe_index
21094
21095         mkdir $DIR/$tdir
21096         mkdir $DIR/$tdir/normal_dir
21097
21098         #Checking when client cache stripe index
21099         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21100         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21101                 error "create striped_dir failed"
21102
21103         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21104                 error "create dir0 fails"
21105         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21106         [ $stripe_index -eq 0 ] ||
21107                 error "dir0 expect index 0 got $stripe_index"
21108
21109         mkdir $DIR/$tdir/striped_dir/dir1 ||
21110                 error "create dir1 fails"
21111         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21112         [ $stripe_index -eq 1 ] ||
21113                 error "dir1 expect index 1 got $stripe_index"
21114
21115         #check default stripe count/stripe index
21116         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21117         test_300_check_default_striped_dir normal_dir 1 0
21118         test_300_check_default_striped_dir normal_dir 2 1
21119         test_300_check_default_striped_dir normal_dir 2 -1
21120
21121         #delete default stripe information
21122         echo "delete default stripeEA"
21123         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21124                 error "set default stripe on striped dir error"
21125
21126         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21127         for dir in $(find $DIR/$tdir/normal_dir/*); do
21128                 stripe_count=$($LFS getdirstripe -c $dir)
21129                 [ $stripe_count -eq 0 ] ||
21130                         error "expect 1 get $stripe_count for $dir"
21131                 stripe_index=$($LFS getdirstripe -i $dir)
21132                 [ $stripe_index -eq 0 ] ||
21133                         error "expect 0 get $stripe_index for $dir"
21134         done
21135 }
21136 run_test 300g "check default striped directory for normal directory"
21137
21138 test_300h() {
21139         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21140         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21141                 skip "Need MDS version at least 2.7.55"
21142
21143         local dir
21144         local stripe_count
21145
21146         mkdir $DIR/$tdir
21147         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21148                 error "set striped dir error"
21149
21150         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21151         test_300_check_default_striped_dir striped_dir 1 0
21152         test_300_check_default_striped_dir striped_dir 2 1
21153         test_300_check_default_striped_dir striped_dir 2 -1
21154
21155         #delete default stripe information
21156         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21157                 error "set default stripe on striped dir error"
21158
21159         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21160         for dir in $(find $DIR/$tdir/striped_dir/*); do
21161                 stripe_count=$($LFS getdirstripe -c $dir)
21162                 [ $stripe_count -eq 0 ] ||
21163                         error "expect 1 get $stripe_count for $dir"
21164         done
21165 }
21166 run_test 300h "check default striped directory for striped directory"
21167
21168 test_300i() {
21169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21170         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21171         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21172                 skip "Need MDS version at least 2.7.55"
21173
21174         local stripe_count
21175         local file
21176
21177         mkdir $DIR/$tdir
21178
21179         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21180                 error "set striped dir error"
21181
21182         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21183                 error "create files under striped dir failed"
21184
21185         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21186                 error "set striped hashdir error"
21187
21188         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21189                 error "create dir0 under hash dir failed"
21190         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21191                 error "create dir1 under hash dir failed"
21192
21193         # unfortunately, we need to umount to clear dir layout cache for now
21194         # once we fully implement dir layout, we can drop this
21195         umount_client $MOUNT || error "umount failed"
21196         mount_client $MOUNT || error "mount failed"
21197
21198         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21199         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21200         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21201
21202         #set the stripe to be unknown hash type
21203         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21204         $LCTL set_param fail_loc=0x1901
21205         for ((i = 0; i < 10; i++)); do
21206                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21207                         error "stat f-$i failed"
21208                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21209         done
21210
21211         touch $DIR/$tdir/striped_dir/f0 &&
21212                 error "create under striped dir with unknown hash should fail"
21213
21214         $LCTL set_param fail_loc=0
21215
21216         umount_client $MOUNT || error "umount failed"
21217         mount_client $MOUNT || error "mount failed"
21218
21219         return 0
21220 }
21221 run_test 300i "client handle unknown hash type striped directory"
21222
21223 test_300j() {
21224         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21226         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21227                 skip "Need MDS version at least 2.7.55"
21228
21229         local stripe_count
21230         local file
21231
21232         mkdir $DIR/$tdir
21233
21234         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21235         $LCTL set_param fail_loc=0x1702
21236         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21237                 error "set striped dir error"
21238
21239         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21240                 error "create files under striped dir failed"
21241
21242         $LCTL set_param fail_loc=0
21243
21244         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21245
21246         return 0
21247 }
21248 run_test 300j "test large update record"
21249
21250 test_300k() {
21251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21252         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21253         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21254                 skip "Need MDS version at least 2.7.55"
21255
21256         # this test needs a huge transaction
21257         local kb
21258         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21259              osd*.$FSNAME-MDT0000.kbytestotal")
21260         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21261
21262         local stripe_count
21263         local file
21264
21265         mkdir $DIR/$tdir
21266
21267         #define OBD_FAIL_LARGE_STRIPE   0x1703
21268         $LCTL set_param fail_loc=0x1703
21269         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21270                 error "set striped dir error"
21271         $LCTL set_param fail_loc=0
21272
21273         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21274                 error "getstripeddir fails"
21275         rm -rf $DIR/$tdir/striped_dir ||
21276                 error "unlink striped dir fails"
21277
21278         return 0
21279 }
21280 run_test 300k "test large striped directory"
21281
21282 test_300l() {
21283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21284         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21285         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21286                 skip "Need MDS version at least 2.7.55"
21287
21288         local stripe_index
21289
21290         test_mkdir -p $DIR/$tdir/striped_dir
21291         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21292                         error "chown $RUNAS_ID failed"
21293         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21294                 error "set default striped dir failed"
21295
21296         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21297         $LCTL set_param fail_loc=0x80000158
21298         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21299
21300         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21301         [ $stripe_index -eq 1 ] ||
21302                 error "expect 1 get $stripe_index for $dir"
21303 }
21304 run_test 300l "non-root user to create dir under striped dir with stale layout"
21305
21306 test_300m() {
21307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21308         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21309         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21310                 skip "Need MDS version at least 2.7.55"
21311
21312         mkdir -p $DIR/$tdir/striped_dir
21313         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21314                 error "set default stripes dir error"
21315
21316         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21317
21318         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21319         [ $stripe_count -eq 0 ] ||
21320                         error "expect 0 get $stripe_count for a"
21321
21322         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21323                 error "set default stripes dir error"
21324
21325         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21326
21327         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21328         [ $stripe_count -eq 0 ] ||
21329                         error "expect 0 get $stripe_count for b"
21330
21331         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21332                 error "set default stripes dir error"
21333
21334         mkdir $DIR/$tdir/striped_dir/c &&
21335                 error "default stripe_index is invalid, mkdir c should fails"
21336
21337         rm -rf $DIR/$tdir || error "rmdir fails"
21338 }
21339 run_test 300m "setstriped directory on single MDT FS"
21340
21341 cleanup_300n() {
21342         local list=$(comma_list $(mdts_nodes))
21343
21344         trap 0
21345         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21346 }
21347
21348 test_300n() {
21349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21350         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21351         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21352                 skip "Need MDS version at least 2.7.55"
21353         remote_mds_nodsh && skip "remote MDS with nodsh"
21354
21355         local stripe_index
21356         local list=$(comma_list $(mdts_nodes))
21357
21358         trap cleanup_300n RETURN EXIT
21359         mkdir -p $DIR/$tdir
21360         chmod 777 $DIR/$tdir
21361         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21362                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21363                 error "create striped dir succeeds with gid=0"
21364
21365         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21366         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21367                 error "create striped dir fails with gid=-1"
21368
21369         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21370         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21371                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21372                 error "set default striped dir succeeds with gid=0"
21373
21374
21375         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21376         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21377                 error "set default striped dir fails with gid=-1"
21378
21379
21380         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21381         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21382                                         error "create test_dir fails"
21383         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21384                                         error "create test_dir1 fails"
21385         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21386                                         error "create test_dir2 fails"
21387         cleanup_300n
21388 }
21389 run_test 300n "non-root user to create dir under striped dir with default EA"
21390
21391 test_300o() {
21392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21393         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21394         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21395                 skip "Need MDS version at least 2.7.55"
21396
21397         local numfree1
21398         local numfree2
21399
21400         mkdir -p $DIR/$tdir
21401
21402         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21403         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21404         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21405                 skip "not enough free inodes $numfree1 $numfree2"
21406         fi
21407
21408         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21409         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21410         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21411                 skip "not enough free space $numfree1 $numfree2"
21412         fi
21413
21414         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21415                 error "setdirstripe fails"
21416
21417         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21418                 error "create dirs fails"
21419
21420         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21421         ls $DIR/$tdir/striped_dir > /dev/null ||
21422                 error "ls striped dir fails"
21423         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21424                 error "unlink big striped dir fails"
21425 }
21426 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21427
21428 test_300p() {
21429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21430         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21431         remote_mds_nodsh && skip "remote MDS with nodsh"
21432
21433         mkdir -p $DIR/$tdir
21434
21435         #define OBD_FAIL_OUT_ENOSPC     0x1704
21436         do_facet mds2 lctl set_param fail_loc=0x80001704
21437         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21438                  && error "create striped directory should fail"
21439
21440         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21441
21442         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21443         true
21444 }
21445 run_test 300p "create striped directory without space"
21446
21447 test_300q() {
21448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21449         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21450
21451         local fd=$(free_fd)
21452         local cmd="exec $fd<$tdir"
21453         cd $DIR
21454         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21455         eval $cmd
21456         cmd="exec $fd<&-"
21457         trap "eval $cmd" EXIT
21458         cd $tdir || error "cd $tdir fails"
21459         rmdir  ../$tdir || error "rmdir $tdir fails"
21460         mkdir local_dir && error "create dir succeeds"
21461         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21462         eval $cmd
21463         return 0
21464 }
21465 run_test 300q "create remote directory under orphan directory"
21466
21467 test_300r() {
21468         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21469                 skip "Need MDS version at least 2.7.55" && return
21470         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21471
21472         mkdir $DIR/$tdir
21473
21474         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21475                 error "set striped dir error"
21476
21477         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21478                 error "getstripeddir fails"
21479
21480         local stripe_count
21481         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21482                       awk '/lmv_stripe_count:/ { print $2 }')
21483
21484         [ $MDSCOUNT -ne $stripe_count ] &&
21485                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21486
21487         rm -rf $DIR/$tdir/striped_dir ||
21488                 error "unlink striped dir fails"
21489 }
21490 run_test 300r "test -1 striped directory"
21491
21492 prepare_remote_file() {
21493         mkdir $DIR/$tdir/src_dir ||
21494                 error "create remote source failed"
21495
21496         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21497                  error "cp to remote source failed"
21498         touch $DIR/$tdir/src_dir/a
21499
21500         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21501                 error "create remote target dir failed"
21502
21503         touch $DIR/$tdir/tgt_dir/b
21504
21505         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21506                 error "rename dir cross MDT failed!"
21507
21508         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21509                 error "src_child still exists after rename"
21510
21511         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21512                 error "missing file(a) after rename"
21513
21514         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21515                 error "diff after rename"
21516 }
21517
21518 test_310a() {
21519         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21521
21522         local remote_file=$DIR/$tdir/tgt_dir/b
21523
21524         mkdir -p $DIR/$tdir
21525
21526         prepare_remote_file || error "prepare remote file failed"
21527
21528         #open-unlink file
21529         $OPENUNLINK $remote_file $remote_file ||
21530                 error "openunlink $remote_file failed"
21531         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21532 }
21533 run_test 310a "open unlink remote file"
21534
21535 test_310b() {
21536         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21538
21539         local remote_file=$DIR/$tdir/tgt_dir/b
21540
21541         mkdir -p $DIR/$tdir
21542
21543         prepare_remote_file || error "prepare remote file failed"
21544
21545         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21546         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21547         $CHECKSTAT -t file $remote_file || error "check file failed"
21548 }
21549 run_test 310b "unlink remote file with multiple links while open"
21550
21551 test_310c() {
21552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21553         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21554
21555         local remote_file=$DIR/$tdir/tgt_dir/b
21556
21557         mkdir -p $DIR/$tdir
21558
21559         prepare_remote_file || error "prepare remote file failed"
21560
21561         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21562         multiop_bg_pause $remote_file O_uc ||
21563                         error "mulitop failed for remote file"
21564         MULTIPID=$!
21565         $MULTIOP $DIR/$tfile Ouc
21566         kill -USR1 $MULTIPID
21567         wait $MULTIPID
21568 }
21569 run_test 310c "open-unlink remote file with multiple links"
21570
21571 #LU-4825
21572 test_311() {
21573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21574         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21575         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21576                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21577         remote_mds_nodsh && skip "remote MDS with nodsh"
21578
21579         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21580         local mdts=$(comma_list $(mdts_nodes))
21581
21582         mkdir -p $DIR/$tdir
21583         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21584         createmany -o $DIR/$tdir/$tfile. 1000
21585
21586         # statfs data is not real time, let's just calculate it
21587         old_iused=$((old_iused + 1000))
21588
21589         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21590                         osp.*OST0000*MDT0000.create_count")
21591         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21592                                 osp.*OST0000*MDT0000.max_create_count")
21593         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21594
21595         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21596         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21597         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21598
21599         unlinkmany $DIR/$tdir/$tfile. 1000
21600
21601         do_nodes $mdts "$LCTL set_param -n \
21602                         osp.*OST0000*.max_create_count=$max_count"
21603         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21604                 do_nodes $mdts "$LCTL set_param -n \
21605                                 osp.*OST0000*.create_count=$count"
21606         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21607                         grep "=0" && error "create_count is zero"
21608
21609         local new_iused
21610         for i in $(seq 120); do
21611                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21612                 # system may be too busy to destroy all objs in time, use
21613                 # a somewhat small value to not fail autotest
21614                 [ $((old_iused - new_iused)) -gt 400 ] && break
21615                 sleep 1
21616         done
21617
21618         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21619         [ $((old_iused - new_iused)) -gt 400 ] ||
21620                 error "objs not destroyed after unlink"
21621 }
21622 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21623
21624 zfs_oid_to_objid()
21625 {
21626         local ost=$1
21627         local objid=$2
21628
21629         local vdevdir=$(dirname $(facet_vdevice $ost))
21630         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21631         local zfs_zapid=$(do_facet $ost $cmd |
21632                           grep -w "/O/0/d$((objid%32))" -C 5 |
21633                           awk '/Object/{getline; print $1}')
21634         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21635                           awk "/$objid = /"'{printf $3}')
21636
21637         echo $zfs_objid
21638 }
21639
21640 zfs_object_blksz() {
21641         local ost=$1
21642         local objid=$2
21643
21644         local vdevdir=$(dirname $(facet_vdevice $ost))
21645         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21646         local blksz=$(do_facet $ost $cmd $objid |
21647                       awk '/dblk/{getline; printf $4}')
21648
21649         case "${blksz: -1}" in
21650                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21651                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21652                 *) ;;
21653         esac
21654
21655         echo $blksz
21656 }
21657
21658 test_312() { # LU-4856
21659         remote_ost_nodsh && skip "remote OST with nodsh"
21660         [ "$ost1_FSTYPE" = "zfs" ] ||
21661                 skip_env "the test only applies to zfs"
21662
21663         local max_blksz=$(do_facet ost1 \
21664                           $ZFS get -p recordsize $(facet_device ost1) |
21665                           awk '!/VALUE/{print $3}')
21666
21667         # to make life a little bit easier
21668         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21669         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21670
21671         local tf=$DIR/$tdir/$tfile
21672         touch $tf
21673         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21674
21675         # Get ZFS object id
21676         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21677         # block size change by sequential overwrite
21678         local bs
21679
21680         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21681                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21682
21683                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21684                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21685         done
21686         rm -f $tf
21687
21688         # block size change by sequential append write
21689         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21690         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21691         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21692         local count
21693
21694         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21695                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21696                         oflag=sync conv=notrunc
21697
21698                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21699                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21700                         error "blksz error, actual $blksz, " \
21701                                 "expected: 2 * $count * $PAGE_SIZE"
21702         done
21703         rm -f $tf
21704
21705         # random write
21706         touch $tf
21707         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21708         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21709
21710         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21711         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21712         [ $blksz -eq $PAGE_SIZE ] ||
21713                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21714
21715         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21716         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21717         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21718
21719         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21720         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21721         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21722 }
21723 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21724
21725 test_313() {
21726         remote_ost_nodsh && skip "remote OST with nodsh"
21727
21728         local file=$DIR/$tfile
21729
21730         rm -f $file
21731         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21732
21733         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21734         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21735         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21736                 error "write should failed"
21737         do_facet ost1 "$LCTL set_param fail_loc=0"
21738         rm -f $file
21739 }
21740 run_test 313 "io should fail after last_rcvd update fail"
21741
21742 test_314() {
21743         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21744
21745         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21746         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21747         rm -f $DIR/$tfile
21748         wait_delete_completed
21749         do_facet ost1 "$LCTL set_param fail_loc=0"
21750 }
21751 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21752
21753 test_315() { # LU-618
21754         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21755
21756         local file=$DIR/$tfile
21757         rm -f $file
21758
21759         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21760                 error "multiop file write failed"
21761         $MULTIOP $file oO_RDONLY:r4063232_c &
21762         PID=$!
21763
21764         sleep 2
21765
21766         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21767         kill -USR1 $PID
21768
21769         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21770         rm -f $file
21771 }
21772 run_test 315 "read should be accounted"
21773
21774 test_316() {
21775         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21776         large_xattr_enabled || skip_env "ea_inode feature disabled"
21777
21778         rm -rf $DIR/$tdir/d
21779         mkdir -p $DIR/$tdir/d
21780         chown nobody $DIR/$tdir/d
21781         touch $DIR/$tdir/d/file
21782
21783         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21784 }
21785 run_test 316 "lfs mv"
21786
21787 test_317() {
21788         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21789                 skip "Need MDS version at least 2.11.53"
21790         if [ "$ost1_FSTYPE" == "zfs" ]; then
21791                 skip "LU-10370: no implementation for ZFS"
21792         fi
21793
21794         local trunc_sz
21795         local grant_blk_size
21796
21797         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21798                         awk '/grant_block_size:/ { print $2; exit; }')
21799         #
21800         # Create File of size 5M. Truncate it to below size's and verify
21801         # blocks count.
21802         #
21803         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21804                 error "Create file $DIR/$tfile failed"
21805         stack_trap "rm -f $DIR/$tfile" EXIT
21806
21807         for trunc_sz in 2097152 4097 4000 509 0; do
21808                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21809                         error "truncate $tfile to $trunc_sz failed"
21810                 local sz=$(stat --format=%s $DIR/$tfile)
21811                 local blk=$(stat --format=%b $DIR/$tfile)
21812                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21813                                      grant_blk_size) * 8))
21814
21815                 if [[ $blk -ne $trunc_blk ]]; then
21816                         $(which stat) $DIR/$tfile
21817                         error "Expected Block $trunc_blk got $blk for $tfile"
21818                 fi
21819
21820                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21821                         error "Expected Size $trunc_sz got $sz for $tfile"
21822         done
21823
21824         #
21825         # sparse file test
21826         # Create file with a hole and write actual two blocks. Block count
21827         # must be 16.
21828         #
21829         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21830                 conv=fsync || error "Create file : $DIR/$tfile"
21831
21832         # Calculate the final truncate size.
21833         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21834
21835         #
21836         # truncate to size $trunc_sz bytes. Strip the last block
21837         # The block count must drop to 8
21838         #
21839         $TRUNCATE $DIR/$tfile $trunc_sz ||
21840                 error "truncate $tfile to $trunc_sz failed"
21841
21842         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
21843         sz=$(stat --format=%s $DIR/$tfile)
21844         blk=$(stat --format=%b $DIR/$tfile)
21845
21846         if [[ $blk -ne $trunc_bsz ]]; then
21847                 $(which stat) $DIR/$tfile
21848                 error "Expected Block $trunc_bsz got $blk for $tfile"
21849         fi
21850
21851         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21852                 error "Expected Size $trunc_sz got $sz for $tfile"
21853 }
21854 run_test 317 "Verify blocks get correctly update after truncate"
21855
21856 test_318() {
21857         local old_max_active=$($LCTL get_param -n \
21858                             llite.*.max_read_ahead_async_active 2>/dev/null)
21859
21860         $LCTL set_param llite.*.max_read_ahead_async_active=256
21861         local max_active=$($LCTL get_param -n \
21862                            llite.*.max_read_ahead_async_active 2>/dev/null)
21863         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
21864
21865         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
21866                 error "set max_read_ahead_async_active should succeed"
21867
21868         $LCTL set_param llite.*.max_read_ahead_async_active=512
21869         max_active=$($LCTL get_param -n \
21870                      llite.*.max_read_ahead_async_active 2>/dev/null)
21871         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
21872
21873         # restore @max_active
21874         [ $old_max_active -ne 0 ] && $LCTL set_param \
21875                 llite.*.max_read_ahead_async_active=$old_max_active
21876
21877         local old_threshold=$($LCTL get_param -n \
21878                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21879         local max_per_file_mb=$($LCTL get_param -n \
21880                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
21881
21882         local invalid=$(($max_per_file_mb + 1))
21883         $LCTL set_param \
21884                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
21885                         && error "set $invalid should fail"
21886
21887         local valid=$(($invalid - 1))
21888         $LCTL set_param \
21889                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
21890                         error "set $valid should succeed"
21891         local threshold=$($LCTL get_param -n \
21892                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21893         [ $threshold -eq $valid ] || error \
21894                 "expect threshold $valid got $threshold"
21895         $LCTL set_param \
21896                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
21897 }
21898 run_test 318 "Verify async readahead tunables"
21899
21900 test_319() {
21901         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
21902
21903         local before=$(date +%s)
21904         local evict
21905         local mdir=$DIR/$tdir
21906         local file=$mdir/xxx
21907
21908         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
21909         touch $file
21910
21911 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
21912         $LCTL set_param fail_val=5 fail_loc=0x8000032c
21913         $LFS mv -m1 $file &
21914
21915         sleep 1
21916         dd if=$file of=/dev/null
21917         wait
21918         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
21919           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
21920
21921         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
21922 }
21923 run_test 319 "lost lease lock on migrate error"
21924
21925 test_398a() { # LU-4198
21926         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21927         $LCTL set_param ldlm.namespaces.*.lru_size=clear
21928
21929         # request a new lock on client
21930         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21931
21932         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21933         local lock_count=$($LCTL get_param -n \
21934                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21935         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
21936
21937         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
21938
21939         # no lock cached, should use lockless IO and not enqueue new lock
21940         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21941         lock_count=$($LCTL get_param -n \
21942                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21943         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
21944 }
21945 run_test 398a "direct IO should cancel lock otherwise lockless"
21946
21947 test_398b() { # LU-4198
21948         which fio || skip_env "no fio installed"
21949         $LFS setstripe -c -1 $DIR/$tfile
21950
21951         local size=12
21952         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
21953
21954         local njobs=4
21955         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
21956         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21957                 --numjobs=$njobs --fallocate=none \
21958                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21959                 --filename=$DIR/$tfile &
21960         bg_pid=$!
21961
21962         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
21963         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
21964                 --numjobs=$njobs --fallocate=none \
21965                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21966                 --filename=$DIR/$tfile || true
21967         wait $bg_pid
21968
21969         rm -rf $DIR/$tfile
21970 }
21971 run_test 398b "DIO and buffer IO race"
21972
21973 test_398c() { # LU-4198
21974         which fio || skip_env "no fio installed"
21975
21976         saved_debug=$($LCTL get_param -n debug)
21977         $LCTL set_param debug=0
21978
21979         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
21980         ((size /= 1024)) # by megabytes
21981         ((size /= 2)) # write half of the OST at most
21982         [ $size -gt 40 ] && size=40 #reduce test time anyway
21983
21984         $LFS setstripe -c 1 $DIR/$tfile
21985
21986         # it seems like ldiskfs reserves more space than necessary if the
21987         # writing blocks are not mapped, so it extends the file firstly
21988         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
21989         cancel_lru_locks osc
21990
21991         # clear and verify rpc_stats later
21992         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
21993
21994         local njobs=4
21995         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
21996         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
21997                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
21998                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21999                 --filename=$DIR/$tfile
22000         [ $? -eq 0 ] || error "fio write error"
22001
22002         [ $($LCTL get_param -n \
22003          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22004                 error "Locks were requested while doing AIO"
22005
22006         # get the percentage of 1-page I/O
22007         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22008                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22009                 awk '{print $7}')
22010         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22011
22012         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22013         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22014                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22015                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22016                 --filename=$DIR/$tfile
22017         [ $? -eq 0 ] || error "fio mixed read write error"
22018
22019         echo "AIO with large block size ${size}M"
22020         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22021                 --numjobs=1 --fallocate=none --ioengine=libaio \
22022                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22023                 --filename=$DIR/$tfile
22024         [ $? -eq 0 ] || error "fio large block size failed"
22025
22026         rm -rf $DIR/$tfile
22027         $LCTL set_param debug="$saved_debug"
22028 }
22029 run_test 398c "run fio to test AIO"
22030
22031 test_398d() { #  LU-13846
22032         test -f aiocp || skip_env "no aiocp installed"
22033         local aio_file=$DIR/aio_file
22034
22035         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22036
22037         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22038         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22039
22040         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22041         rm -rf $DIR/$tfile $aio_file
22042 }
22043 run_test 398d "run aiocp to verify block size > stripe size"
22044
22045 test_fake_rw() {
22046         local read_write=$1
22047         if [ "$read_write" = "write" ]; then
22048                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22049         elif [ "$read_write" = "read" ]; then
22050                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22051         else
22052                 error "argument error"
22053         fi
22054
22055         # turn off debug for performance testing
22056         local saved_debug=$($LCTL get_param -n debug)
22057         $LCTL set_param debug=0
22058
22059         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22060
22061         # get ost1 size - $FSNAME-OST0000
22062         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22063         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22064         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22065
22066         if [ "$read_write" = "read" ]; then
22067                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
22068         fi
22069
22070         local start_time=$(date +%s.%N)
22071         $dd_cmd bs=1M count=$blocks oflag=sync ||
22072                 error "real dd $read_write error"
22073         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22074
22075         if [ "$read_write" = "write" ]; then
22076                 rm -f $DIR/$tfile
22077         fi
22078
22079         # define OBD_FAIL_OST_FAKE_RW           0x238
22080         do_facet ost1 $LCTL set_param fail_loc=0x238
22081
22082         local start_time=$(date +%s.%N)
22083         $dd_cmd bs=1M count=$blocks oflag=sync ||
22084                 error "fake dd $read_write error"
22085         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22086
22087         if [ "$read_write" = "write" ]; then
22088                 # verify file size
22089                 cancel_lru_locks osc
22090                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22091                         error "$tfile size not $blocks MB"
22092         fi
22093         do_facet ost1 $LCTL set_param fail_loc=0
22094
22095         echo "fake $read_write $duration_fake vs. normal $read_write" \
22096                 "$duration in seconds"
22097         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22098                 error_not_in_vm "fake write is slower"
22099
22100         $LCTL set_param -n debug="$saved_debug"
22101         rm -f $DIR/$tfile
22102 }
22103 test_399a() { # LU-7655 for OST fake write
22104         remote_ost_nodsh && skip "remote OST with nodsh"
22105
22106         test_fake_rw write
22107 }
22108 run_test 399a "fake write should not be slower than normal write"
22109
22110 test_399b() { # LU-8726 for OST fake read
22111         remote_ost_nodsh && skip "remote OST with nodsh"
22112         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22113                 skip_env "ldiskfs only test"
22114         fi
22115
22116         test_fake_rw read
22117 }
22118 run_test 399b "fake read should not be slower than normal read"
22119
22120 test_400a() { # LU-1606, was conf-sanity test_74
22121         if ! which $CC > /dev/null 2>&1; then
22122                 skip_env "$CC is not installed"
22123         fi
22124
22125         local extra_flags=''
22126         local out=$TMP/$tfile
22127         local prefix=/usr/include/lustre
22128         local prog
22129
22130         # Oleg removes c files in his test rig so test if any c files exist
22131         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22132                 skip_env "Needed c test files are missing"
22133
22134         if ! [[ -d $prefix ]]; then
22135                 # Assume we're running in tree and fixup the include path.
22136                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22137                 extra_flags+=" -L$LUSTRE/utils/.lib"
22138         fi
22139
22140         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22141                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22142                         error "client api broken"
22143         done
22144         rm -f $out
22145 }
22146 run_test 400a "Lustre client api program can compile and link"
22147
22148 test_400b() { # LU-1606, LU-5011
22149         local header
22150         local out=$TMP/$tfile
22151         local prefix=/usr/include/linux/lustre
22152
22153         # We use a hard coded prefix so that this test will not fail
22154         # when run in tree. There are headers in lustre/include/lustre/
22155         # that are not packaged (like lustre_idl.h) and have more
22156         # complicated include dependencies (like config.h and lnet/types.h).
22157         # Since this test about correct packaging we just skip them when
22158         # they don't exist (see below) rather than try to fixup cppflags.
22159
22160         if ! which $CC > /dev/null 2>&1; then
22161                 skip_env "$CC is not installed"
22162         fi
22163
22164         for header in $prefix/*.h; do
22165                 if ! [[ -f "$header" ]]; then
22166                         continue
22167                 fi
22168
22169                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22170                         continue # lustre_ioctl.h is internal header
22171                 fi
22172
22173                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22174                         error "cannot compile '$header'"
22175         done
22176         rm -f $out
22177 }
22178 run_test 400b "packaged headers can be compiled"
22179
22180 test_401a() { #LU-7437
22181         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22182         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22183
22184         #count the number of parameters by "list_param -R"
22185         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22186         #count the number of parameters by listing proc files
22187         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22188         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22189         echo "proc_dirs='$proc_dirs'"
22190         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22191         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22192                       sort -u | wc -l)
22193
22194         [ $params -eq $procs ] ||
22195                 error "found $params parameters vs. $procs proc files"
22196
22197         # test the list_param -D option only returns directories
22198         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22199         #count the number of parameters by listing proc directories
22200         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22201                 sort -u | wc -l)
22202
22203         [ $params -eq $procs ] ||
22204                 error "found $params parameters vs. $procs proc files"
22205 }
22206 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22207
22208 test_401b() {
22209         local save=$($LCTL get_param -n jobid_var)
22210         local tmp=testing
22211
22212         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
22213                 error "no error returned when setting bad parameters"
22214
22215         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
22216         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22217
22218         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
22219         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
22220         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22221 }
22222 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22223
22224 test_401c() {
22225         local jobid_var_old=$($LCTL get_param -n jobid_var)
22226         local jobid_var_new
22227
22228         $LCTL set_param jobid_var= &&
22229                 error "no error returned for 'set_param a='"
22230
22231         jobid_var_new=$($LCTL get_param -n jobid_var)
22232         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22233                 error "jobid_var was changed by setting without value"
22234
22235         $LCTL set_param jobid_var &&
22236                 error "no error returned for 'set_param a'"
22237
22238         jobid_var_new=$($LCTL get_param -n jobid_var)
22239         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22240                 error "jobid_var was changed by setting without value"
22241 }
22242 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22243
22244 test_401d() {
22245         local jobid_var_old=$($LCTL get_param -n jobid_var)
22246         local jobid_var_new
22247         local new_value="foo=bar"
22248
22249         $LCTL set_param jobid_var=$new_value ||
22250                 error "'set_param a=b' did not accept a value containing '='"
22251
22252         jobid_var_new=$($LCTL get_param -n jobid_var)
22253         [[ "$jobid_var_new" == "$new_value" ]] ||
22254                 error "'set_param a=b' failed on a value containing '='"
22255
22256         # Reset the jobid_var to test the other format
22257         $LCTL set_param jobid_var=$jobid_var_old
22258         jobid_var_new=$($LCTL get_param -n jobid_var)
22259         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22260                 error "failed to reset jobid_var"
22261
22262         $LCTL set_param jobid_var $new_value ||
22263                 error "'set_param a b' did not accept a value containing '='"
22264
22265         jobid_var_new=$($LCTL get_param -n jobid_var)
22266         [[ "$jobid_var_new" == "$new_value" ]] ||
22267                 error "'set_param a b' failed on a value containing '='"
22268
22269         $LCTL set_param jobid_var $jobid_var_old
22270         jobid_var_new=$($LCTL get_param -n jobid_var)
22271         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22272                 error "failed to reset jobid_var"
22273 }
22274 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22275
22276 test_402() {
22277         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22278         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22279                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22280         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22281                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22282                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22283         remote_mds_nodsh && skip "remote MDS with nodsh"
22284
22285         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22286 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22287         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22288         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22289                 echo "Touch failed - OK"
22290 }
22291 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22292
22293 test_403() {
22294         local file1=$DIR/$tfile.1
22295         local file2=$DIR/$tfile.2
22296         local tfile=$TMP/$tfile
22297
22298         rm -f $file1 $file2 $tfile
22299
22300         touch $file1
22301         ln $file1 $file2
22302
22303         # 30 sec OBD_TIMEOUT in ll_getattr()
22304         # right before populating st_nlink
22305         $LCTL set_param fail_loc=0x80001409
22306         stat -c %h $file1 > $tfile &
22307
22308         # create an alias, drop all locks and reclaim the dentry
22309         < $file2
22310         cancel_lru_locks mdc
22311         cancel_lru_locks osc
22312         sysctl -w vm.drop_caches=2
22313
22314         wait
22315
22316         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22317
22318         rm -f $tfile $file1 $file2
22319 }
22320 run_test 403 "i_nlink should not drop to zero due to aliasing"
22321
22322 test_404() { # LU-6601
22323         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22324                 skip "Need server version newer than 2.8.52"
22325         remote_mds_nodsh && skip "remote MDS with nodsh"
22326
22327         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22328                 awk '/osp .*-osc-MDT/ { print $4}')
22329
22330         local osp
22331         for osp in $mosps; do
22332                 echo "Deactivate: " $osp
22333                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22334                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22335                         awk -vp=$osp '$4 == p { print $2 }')
22336                 [ $stat = IN ] || {
22337                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22338                         error "deactivate error"
22339                 }
22340                 echo "Activate: " $osp
22341                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22342                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22343                         awk -vp=$osp '$4 == p { print $2 }')
22344                 [ $stat = UP ] || {
22345                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22346                         error "activate error"
22347                 }
22348         done
22349 }
22350 run_test 404 "validate manual {de}activated works properly for OSPs"
22351
22352 test_405() {
22353         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22354         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22355                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22356                         skip "Layout swap lock is not supported"
22357
22358         check_swap_layouts_support
22359         check_swap_layout_no_dom $DIR
22360
22361         test_mkdir $DIR/$tdir
22362         swap_lock_test -d $DIR/$tdir ||
22363                 error "One layout swap locked test failed"
22364 }
22365 run_test 405 "Various layout swap lock tests"
22366
22367 test_406() {
22368         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22369         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22370         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22372         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22373                 skip "Need MDS version at least 2.8.50"
22374
22375         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22376         local test_pool=$TESTNAME
22377
22378         pool_add $test_pool || error "pool_add failed"
22379         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22380                 error "pool_add_targets failed"
22381
22382         save_layout_restore_at_exit $MOUNT
22383
22384         # parent set default stripe count only, child will stripe from both
22385         # parent and fs default
22386         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22387                 error "setstripe $MOUNT failed"
22388         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22389         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22390         for i in $(seq 10); do
22391                 local f=$DIR/$tdir/$tfile.$i
22392                 touch $f || error "touch failed"
22393                 local count=$($LFS getstripe -c $f)
22394                 [ $count -eq $OSTCOUNT ] ||
22395                         error "$f stripe count $count != $OSTCOUNT"
22396                 local offset=$($LFS getstripe -i $f)
22397                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22398                 local size=$($LFS getstripe -S $f)
22399                 [ $size -eq $((def_stripe_size * 2)) ] ||
22400                         error "$f stripe size $size != $((def_stripe_size * 2))"
22401                 local pool=$($LFS getstripe -p $f)
22402                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22403         done
22404
22405         # change fs default striping, delete parent default striping, now child
22406         # will stripe from new fs default striping only
22407         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22408                 error "change $MOUNT default stripe failed"
22409         $LFS setstripe -c 0 $DIR/$tdir ||
22410                 error "delete $tdir default stripe failed"
22411         for i in $(seq 11 20); do
22412                 local f=$DIR/$tdir/$tfile.$i
22413                 touch $f || error "touch $f failed"
22414                 local count=$($LFS getstripe -c $f)
22415                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22416                 local offset=$($LFS getstripe -i $f)
22417                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22418                 local size=$($LFS getstripe -S $f)
22419                 [ $size -eq $def_stripe_size ] ||
22420                         error "$f stripe size $size != $def_stripe_size"
22421                 local pool=$($LFS getstripe -p $f)
22422                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22423         done
22424
22425         unlinkmany $DIR/$tdir/$tfile. 1 20
22426
22427         local f=$DIR/$tdir/$tfile
22428         pool_remove_all_targets $test_pool $f
22429         pool_remove $test_pool $f
22430 }
22431 run_test 406 "DNE support fs default striping"
22432
22433 test_407() {
22434         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22435         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22436                 skip "Need MDS version at least 2.8.55"
22437         remote_mds_nodsh && skip "remote MDS with nodsh"
22438
22439         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22440                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22441         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22442                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22443         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22444
22445         #define OBD_FAIL_DT_TXN_STOP    0x2019
22446         for idx in $(seq $MDSCOUNT); do
22447                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22448         done
22449         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22450         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22451                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22452         true
22453 }
22454 run_test 407 "transaction fail should cause operation fail"
22455
22456 test_408() {
22457         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22458
22459         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22460         lctl set_param fail_loc=0x8000040a
22461         # let ll_prepare_partial_page() fail
22462         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22463
22464         rm -f $DIR/$tfile
22465
22466         # create at least 100 unused inodes so that
22467         # shrink_icache_memory(0) should not return 0
22468         touch $DIR/$tfile-{0..100}
22469         rm -f $DIR/$tfile-{0..100}
22470         sync
22471
22472         echo 2 > /proc/sys/vm/drop_caches
22473 }
22474 run_test 408 "drop_caches should not hang due to page leaks"
22475
22476 test_409()
22477 {
22478         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22479
22480         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22481         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22482         touch $DIR/$tdir/guard || error "(2) Fail to create"
22483
22484         local PREFIX=$(str_repeat 'A' 128)
22485         echo "Create 1K hard links start at $(date)"
22486         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22487                 error "(3) Fail to hard link"
22488
22489         echo "Links count should be right although linkEA overflow"
22490         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22491         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22492         [ $linkcount -eq 1001 ] ||
22493                 error "(5) Unexpected hard links count: $linkcount"
22494
22495         echo "List all links start at $(date)"
22496         ls -l $DIR/$tdir/foo > /dev/null ||
22497                 error "(6) Fail to list $DIR/$tdir/foo"
22498
22499         echo "Unlink hard links start at $(date)"
22500         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22501                 error "(7) Fail to unlink"
22502         echo "Unlink hard links finished at $(date)"
22503 }
22504 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22505
22506 test_410()
22507 {
22508         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22509                 skip "Need client version at least 2.9.59"
22510         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22511                 skip "Need MODULES build"
22512
22513         # Create a file, and stat it from the kernel
22514         local testfile=$DIR/$tfile
22515         touch $testfile
22516
22517         local run_id=$RANDOM
22518         local my_ino=$(stat --format "%i" $testfile)
22519
22520         # Try to insert the module. This will always fail as the
22521         # module is designed to not be inserted.
22522         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22523             &> /dev/null
22524
22525         # Anything but success is a test failure
22526         dmesg | grep -q \
22527             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22528             error "no inode match"
22529 }
22530 run_test 410 "Test inode number returned from kernel thread"
22531
22532 cleanup_test411_cgroup() {
22533         trap 0
22534         rmdir "$1"
22535 }
22536
22537 test_411() {
22538         local cg_basedir=/sys/fs/cgroup/memory
22539         # LU-9966
22540         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22541                 skip "no setup for cgroup"
22542
22543         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22544                 error "test file creation failed"
22545         cancel_lru_locks osc
22546
22547         # Create a very small memory cgroup to force a slab allocation error
22548         local cgdir=$cg_basedir/osc_slab_alloc
22549         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22550         trap "cleanup_test411_cgroup $cgdir" EXIT
22551         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22552         echo 1M > $cgdir/memory.limit_in_bytes
22553
22554         # Should not LBUG, just be killed by oom-killer
22555         # dd will return 0 even allocation failure in some environment.
22556         # So don't check return value
22557         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22558         cleanup_test411_cgroup $cgdir
22559
22560         return 0
22561 }
22562 run_test 411 "Slab allocation error with cgroup does not LBUG"
22563
22564 test_412() {
22565         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22566         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22567                 skip "Need server version at least 2.10.55"
22568         fi
22569
22570         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22571                 error "mkdir failed"
22572         $LFS getdirstripe $DIR/$tdir
22573         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22574         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22575                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22576         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22577         [ $stripe_count -eq 2 ] ||
22578                 error "expect 2 get $stripe_count"
22579 }
22580 run_test 412 "mkdir on specific MDTs"
22581
22582 test_qos_mkdir() {
22583         local mkdir_cmd=$1
22584         local stripe_count=$2
22585         local mdts=$(comma_list $(mdts_nodes))
22586
22587         local testdir
22588         local lmv_qos_prio_free
22589         local lmv_qos_threshold_rr
22590         local lmv_qos_maxage
22591         local lod_qos_prio_free
22592         local lod_qos_threshold_rr
22593         local lod_qos_maxage
22594         local count
22595         local i
22596
22597         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22598         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22599         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22600                 head -n1)
22601         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22602         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22603         stack_trap "$LCTL set_param \
22604                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22605         stack_trap "$LCTL set_param \
22606                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22607         stack_trap "$LCTL set_param \
22608                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22609
22610         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22611                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22612         lod_qos_prio_free=${lod_qos_prio_free%%%}
22613         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22614                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22615         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22616         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22617                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22618         stack_trap "do_nodes $mdts $LCTL set_param \
22619                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22620         stack_trap "do_nodes $mdts $LCTL set_param \
22621                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22622                 EXIT
22623         stack_trap "do_nodes $mdts $LCTL set_param \
22624                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22625
22626         echo
22627         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22628
22629         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22630         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22631
22632         testdir=$DIR/$tdir-s$stripe_count/rr
22633
22634         for i in $(seq $((100 * MDSCOUNT))); do
22635                 eval $mkdir_cmd $testdir/subdir$i ||
22636                         error "$mkdir_cmd subdir$i failed"
22637         done
22638
22639         for i in $(seq $MDSCOUNT); do
22640                 count=$($LFS getdirstripe -i $testdir/* |
22641                                 grep ^$((i - 1))$ | wc -l)
22642                 echo "$count directories created on MDT$((i - 1))"
22643                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22644
22645                 if [ $stripe_count -gt 1 ]; then
22646                         count=$($LFS getdirstripe $testdir/* |
22647                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22648                         echo "$count stripes created on MDT$((i - 1))"
22649                         # deviation should < 5% of average
22650                         [ $count -lt $((95 * stripe_count)) ] ||
22651                         [ $count -gt $((105 * stripe_count)) ] &&
22652                                 error "stripes are not evenly distributed"
22653                 fi
22654         done
22655
22656         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22657         do_nodes $mdts $LCTL set_param \
22658                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22659
22660         echo
22661         echo "Check for uneven MDTs: "
22662
22663         local ffree
22664         local bavail
22665         local max
22666         local min
22667         local max_index
22668         local min_index
22669         local tmp
22670
22671         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22672         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22673         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22674
22675         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22676         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22677         max_index=0
22678         min_index=0
22679         for ((i = 1; i < ${#ffree[@]}; i++)); do
22680                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22681                 if [ $tmp -gt $max ]; then
22682                         max=$tmp
22683                         max_index=$i
22684                 fi
22685                 if [ $tmp -lt $min ]; then
22686                         min=$tmp
22687                         min_index=$i
22688                 fi
22689         done
22690
22691         [ ${ffree[min_index]} -eq 0 ] &&
22692                 skip "no free files in MDT$min_index"
22693         [ ${ffree[min_index]} -gt 100000000 ] &&
22694                 skip "too much free files in MDT$min_index"
22695
22696         # Check if we need to generate uneven MDTs
22697         local threshold=50
22698         local diff=$(((max - min) * 100 / min))
22699         local value="$(generate_string 1024)"
22700
22701         while [ $diff -lt $threshold ]; do
22702                 # generate uneven MDTs, create till $threshold% diff
22703                 echo -n "weight diff=$diff% must be > $threshold% ..."
22704                 count=$((${ffree[min_index]} / 10))
22705                 # 50 sec per 10000 files in vm
22706                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22707                         skip "$count files to create"
22708                 echo "Fill MDT$min_index with $count files"
22709                 [ -d $DIR/$tdir-MDT$min_index ] ||
22710                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22711                         error "mkdir $tdir-MDT$min_index failed"
22712                 for i in $(seq $count); do
22713                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22714                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22715                                 error "create f$j_$i failed"
22716                         setfattr -n user.413b -v $value \
22717                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22718                                 error "setfattr f$j_$i failed"
22719                 done
22720
22721                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22722                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22723                 max=$(((${ffree[max_index]} >> 8) * \
22724                         (${bavail[max_index]} * bsize >> 16)))
22725                 min=$(((${ffree[min_index]} >> 8) * \
22726                         (${bavail[min_index]} * bsize >> 16)))
22727                 diff=$(((max - min) * 100 / min))
22728         done
22729
22730         echo "MDT filesfree available: ${ffree[@]}"
22731         echo "MDT blocks available: ${bavail[@]}"
22732         echo "weight diff=$diff%"
22733
22734         echo
22735         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22736
22737         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22738         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22739         # decrease statfs age, so that it can be updated in time
22740         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22741         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22742
22743         sleep 1
22744
22745         testdir=$DIR/$tdir-s$stripe_count/qos
22746
22747         for i in $(seq $((100 * MDSCOUNT))); do
22748                 eval $mkdir_cmd $testdir/subdir$i ||
22749                         error "$mkdir_cmd subdir$i failed"
22750         done
22751
22752         for i in $(seq $MDSCOUNT); do
22753                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22754                         wc -l)
22755                 echo "$count directories created on MDT$((i - 1))"
22756
22757                 if [ $stripe_count -gt 1 ]; then
22758                         count=$($LFS getdirstripe $testdir/* |
22759                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22760                         echo "$count stripes created on MDT$((i - 1))"
22761                 fi
22762         done
22763
22764         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
22765         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22766
22767         # D-value should > 10% of averge
22768         [ $((max - min)) -lt 10 ] &&
22769                 error "subdirs shouldn't be evenly distributed"
22770
22771         # ditto
22772         if [ $stripe_count -gt 1 ]; then
22773                 max=$($LFS getdirstripe $testdir/* |
22774                         grep -P "^\s+$max_index\t" | wc -l)
22775                 min=$($LFS getdirstripe $testdir/* |
22776                         grep -P "^\s+$min_index\t" | wc -l)
22777                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22778                         error "stripes shouldn't be evenly distributed"|| true
22779         fi
22780 }
22781
22782 test_413a() {
22783         [ $MDSCOUNT -lt 2 ] &&
22784                 skip "We need at least 2 MDTs for this test"
22785
22786         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22787                 skip "Need server version at least 2.12.52"
22788
22789         local stripe_count
22790
22791         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22792                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22793                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22794                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22795                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22796         done
22797 }
22798 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22799
22800 test_413b() {
22801         [ $MDSCOUNT -lt 2 ] &&
22802                 skip "We need at least 2 MDTs for this test"
22803
22804         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22805                 skip "Need server version at least 2.12.52"
22806
22807         local stripe_count
22808
22809         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22810                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22811                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22812                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22813                 $LFS setdirstripe -D -c $stripe_count \
22814                         $DIR/$tdir-s$stripe_count/rr ||
22815                         error "setdirstripe failed"
22816                 $LFS setdirstripe -D -c $stripe_count \
22817                         $DIR/$tdir-s$stripe_count/qos ||
22818                         error "setdirstripe failed"
22819                 test_qos_mkdir "mkdir" $stripe_count
22820         done
22821 }
22822 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
22823
22824 test_414() {
22825 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
22826         $LCTL set_param fail_loc=0x80000521
22827         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
22828         rm -f $DIR/$tfile
22829 }
22830 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
22831
22832 test_415() {
22833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22834         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22835                 skip "Need server version at least 2.11.52"
22836
22837         # LU-11102
22838         local total
22839         local setattr_pid
22840         local start_time
22841         local end_time
22842         local duration
22843
22844         total=500
22845         # this test may be slow on ZFS
22846         [ "$mds1_FSTYPE" == "zfs" ] && total=100
22847
22848         # though this test is designed for striped directory, let's test normal
22849         # directory too since lock is always saved as CoS lock.
22850         test_mkdir $DIR/$tdir || error "mkdir $tdir"
22851         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
22852
22853         (
22854                 while true; do
22855                         touch $DIR/$tdir
22856                 done
22857         ) &
22858         setattr_pid=$!
22859
22860         start_time=$(date +%s)
22861         for i in $(seq $total); do
22862                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
22863                         > /dev/null
22864         done
22865         end_time=$(date +%s)
22866         duration=$((end_time - start_time))
22867
22868         kill -9 $setattr_pid
22869
22870         echo "rename $total files took $duration sec"
22871         [ $duration -lt 100 ] || error "rename took $duration sec"
22872 }
22873 run_test 415 "lock revoke is not missing"
22874
22875 test_416() {
22876         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22877                 skip "Need server version at least 2.11.55"
22878
22879         # define OBD_FAIL_OSD_TXN_START    0x19a
22880         do_facet mds1 lctl set_param fail_loc=0x19a
22881
22882         lfs mkdir -c $MDSCOUNT $DIR/$tdir
22883
22884         true
22885 }
22886 run_test 416 "transaction start failure won't cause system hung"
22887
22888 cleanup_417() {
22889         trap 0
22890         do_nodes $(comma_list $(mdts_nodes)) \
22891                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
22892         do_nodes $(comma_list $(mdts_nodes)) \
22893                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
22894         do_nodes $(comma_list $(mdts_nodes)) \
22895                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
22896 }
22897
22898 test_417() {
22899         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22900         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
22901                 skip "Need MDS version at least 2.11.56"
22902
22903         trap cleanup_417 RETURN EXIT
22904
22905         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
22906         do_nodes $(comma_list $(mdts_nodes)) \
22907                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
22908         $LFS migrate -m 0 $DIR/$tdir.1 &&
22909                 error "migrate dir $tdir.1 should fail"
22910
22911         do_nodes $(comma_list $(mdts_nodes)) \
22912                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
22913         $LFS mkdir -i 1 $DIR/$tdir.2 &&
22914                 error "create remote dir $tdir.2 should fail"
22915
22916         do_nodes $(comma_list $(mdts_nodes)) \
22917                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
22918         $LFS mkdir -c 2 $DIR/$tdir.3 &&
22919                 error "create striped dir $tdir.3 should fail"
22920         true
22921 }
22922 run_test 417 "disable remote dir, striped dir and dir migration"
22923
22924 # Checks that the outputs of df [-i] and lfs df [-i] match
22925 #
22926 # usage: check_lfs_df <blocks | inodes> <mountpoint>
22927 check_lfs_df() {
22928         local dir=$2
22929         local inodes
22930         local df_out
22931         local lfs_df_out
22932         local count
22933         local passed=false
22934
22935         # blocks or inodes
22936         [ "$1" == "blocks" ] && inodes= || inodes="-i"
22937
22938         for count in {1..100}; do
22939                 cancel_lru_locks
22940                 sync; sleep 0.2
22941
22942                 # read the lines of interest
22943                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
22944                         error "df $inodes $dir | tail -n +2 failed"
22945                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
22946                         error "lfs df $inodes $dir | grep summary: failed"
22947
22948                 # skip first substrings of each output as they are different
22949                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
22950                 # compare the two outputs
22951                 passed=true
22952                 for i in {1..5}; do
22953                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
22954                 done
22955                 $passed && break
22956         done
22957
22958         if ! $passed; then
22959                 df -P $inodes $dir
22960                 echo
22961                 lfs df $inodes $dir
22962                 error "df and lfs df $1 output mismatch: "      \
22963                       "df ${inodes}: ${df_out[*]}, "            \
22964                       "lfs df ${inodes}: ${lfs_df_out[*]}"
22965         fi
22966 }
22967
22968 test_418() {
22969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22970
22971         local dir=$DIR/$tdir
22972         local numfiles=$((RANDOM % 4096 + 2))
22973         local numblocks=$((RANDOM % 256 + 1))
22974
22975         wait_delete_completed
22976         test_mkdir $dir
22977
22978         # check block output
22979         check_lfs_df blocks $dir
22980         # check inode output
22981         check_lfs_df inodes $dir
22982
22983         # create a single file and retest
22984         echo "Creating a single file and testing"
22985         createmany -o $dir/$tfile- 1 &>/dev/null ||
22986                 error "creating 1 file in $dir failed"
22987         check_lfs_df blocks $dir
22988         check_lfs_df inodes $dir
22989
22990         # create a random number of files
22991         echo "Creating $((numfiles - 1)) files and testing"
22992         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
22993                 error "creating $((numfiles - 1)) files in $dir failed"
22994
22995         # write a random number of blocks to the first test file
22996         echo "Writing $numblocks 4K blocks and testing"
22997         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
22998                 count=$numblocks &>/dev/null ||
22999                 error "dd to $dir/${tfile}-0 failed"
23000
23001         # retest
23002         check_lfs_df blocks $dir
23003         check_lfs_df inodes $dir
23004
23005         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23006                 error "unlinking $numfiles files in $dir failed"
23007 }
23008 run_test 418 "df and lfs df outputs match"
23009
23010 test_419()
23011 {
23012         local dir=$DIR/$tdir
23013
23014         mkdir -p $dir
23015         touch $dir/file
23016
23017         cancel_lru_locks mdc
23018
23019         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23020         $LCTL set_param fail_loc=0x1410
23021         cat $dir/file
23022         $LCTL set_param fail_loc=0
23023         rm -rf $dir
23024 }
23025 run_test 419 "Verify open file by name doesn't crash kernel"
23026
23027 test_420()
23028 {
23029         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23030                 skip "Need MDS version at least 2.12.53"
23031
23032         local SAVE_UMASK=$(umask)
23033         local dir=$DIR/$tdir
23034         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23035
23036         mkdir -p $dir
23037         umask 0000
23038         mkdir -m03777 $dir/testdir
23039         ls -dn $dir/testdir
23040         # Need to remove trailing '.' when SELinux is enabled
23041         local dirperms=$(ls -dn $dir/testdir |
23042                          awk '{ sub(/\.$/, "", $1); print $1}')
23043         [ $dirperms == "drwxrwsrwt" ] ||
23044                 error "incorrect perms on $dir/testdir"
23045
23046         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23047                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23048         ls -n $dir/testdir/testfile
23049         local fileperms=$(ls -n $dir/testdir/testfile |
23050                           awk '{ sub(/\.$/, "", $1); print $1}')
23051         [ $fileperms == "-rwxr-xr-x" ] ||
23052                 error "incorrect perms on $dir/testdir/testfile"
23053
23054         umask $SAVE_UMASK
23055 }
23056 run_test 420 "clear SGID bit on non-directories for non-members"
23057
23058 test_421a() {
23059         local cnt
23060         local fid1
23061         local fid2
23062
23063         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23064                 skip "Need MDS version at least 2.12.54"
23065
23066         test_mkdir $DIR/$tdir
23067         createmany -o $DIR/$tdir/f 3
23068         cnt=$(ls -1 $DIR/$tdir | wc -l)
23069         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23070
23071         fid1=$(lfs path2fid $DIR/$tdir/f1)
23072         fid2=$(lfs path2fid $DIR/$tdir/f2)
23073         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23074
23075         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23076         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23077
23078         cnt=$(ls -1 $DIR/$tdir | wc -l)
23079         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23080
23081         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23082         createmany -o $DIR/$tdir/f 3
23083         cnt=$(ls -1 $DIR/$tdir | wc -l)
23084         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23085
23086         fid1=$(lfs path2fid $DIR/$tdir/f1)
23087         fid2=$(lfs path2fid $DIR/$tdir/f2)
23088         echo "remove using fsname $FSNAME"
23089         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23090
23091         cnt=$(ls -1 $DIR/$tdir | wc -l)
23092         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23093 }
23094 run_test 421a "simple rm by fid"
23095
23096 test_421b() {
23097         local cnt
23098         local FID1
23099         local FID2
23100
23101         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23102                 skip "Need MDS version at least 2.12.54"
23103
23104         test_mkdir $DIR/$tdir
23105         createmany -o $DIR/$tdir/f 3
23106         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23107         MULTIPID=$!
23108
23109         FID1=$(lfs path2fid $DIR/$tdir/f1)
23110         FID2=$(lfs path2fid $DIR/$tdir/f2)
23111         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23112
23113         kill -USR1 $MULTIPID
23114         wait
23115
23116         cnt=$(ls $DIR/$tdir | wc -l)
23117         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23118 }
23119 run_test 421b "rm by fid on open file"
23120
23121 test_421c() {
23122         local cnt
23123         local FIDS
23124
23125         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23126                 skip "Need MDS version at least 2.12.54"
23127
23128         test_mkdir $DIR/$tdir
23129         createmany -o $DIR/$tdir/f 3
23130         touch $DIR/$tdir/$tfile
23131         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23132         cnt=$(ls -1 $DIR/$tdir | wc -l)
23133         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23134
23135         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23136         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23137
23138         cnt=$(ls $DIR/$tdir | wc -l)
23139         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23140 }
23141 run_test 421c "rm by fid against hardlinked files"
23142
23143 test_421d() {
23144         local cnt
23145         local FIDS
23146
23147         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23148                 skip "Need MDS version at least 2.12.54"
23149
23150         test_mkdir $DIR/$tdir
23151         createmany -o $DIR/$tdir/f 4097
23152         cnt=$(ls -1 $DIR/$tdir | wc -l)
23153         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23154
23155         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23156         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23157
23158         cnt=$(ls $DIR/$tdir | wc -l)
23159         rm -rf $DIR/$tdir
23160         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23161 }
23162 run_test 421d "rmfid en masse"
23163
23164 test_421e() {
23165         local cnt
23166         local FID
23167
23168         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23169         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23170                 skip "Need MDS version at least 2.12.54"
23171
23172         mkdir -p $DIR/$tdir
23173         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23174         createmany -o $DIR/$tdir/striped_dir/f 512
23175         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23176         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23177
23178         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23179                 sed "s/[/][^:]*://g")
23180         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23181
23182         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23183         rm -rf $DIR/$tdir
23184         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23185 }
23186 run_test 421e "rmfid in DNE"
23187
23188 test_421f() {
23189         local cnt
23190         local FID
23191
23192         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23193                 skip "Need MDS version at least 2.12.54"
23194
23195         test_mkdir $DIR/$tdir
23196         touch $DIR/$tdir/f
23197         cnt=$(ls -1 $DIR/$tdir | wc -l)
23198         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23199
23200         FID=$(lfs path2fid $DIR/$tdir/f)
23201         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23202         # rmfid should fail
23203         cnt=$(ls -1 $DIR/$tdir | wc -l)
23204         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23205
23206         chmod a+rw $DIR/$tdir
23207         ls -la $DIR/$tdir
23208         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23209         # rmfid should fail
23210         cnt=$(ls -1 $DIR/$tdir | wc -l)
23211         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23212
23213         rm -f $DIR/$tdir/f
23214         $RUNAS touch $DIR/$tdir/f
23215         FID=$(lfs path2fid $DIR/$tdir/f)
23216         echo "rmfid as root"
23217         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23218         cnt=$(ls -1 $DIR/$tdir | wc -l)
23219         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23220
23221         rm -f $DIR/$tdir/f
23222         $RUNAS touch $DIR/$tdir/f
23223         cnt=$(ls -1 $DIR/$tdir | wc -l)
23224         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23225         FID=$(lfs path2fid $DIR/$tdir/f)
23226         # rmfid w/o user_fid2path mount option should fail
23227         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23228         cnt=$(ls -1 $DIR/$tdir | wc -l)
23229         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23230
23231         umount_client $MOUNT || error "failed to umount client"
23232         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23233                 error "failed to mount client'"
23234
23235         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23236         # rmfid should succeed
23237         cnt=$(ls -1 $DIR/$tdir | wc -l)
23238         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23239
23240         # rmfid shouldn't allow to remove files due to dir's permission
23241         chmod a+rwx $DIR/$tdir
23242         touch $DIR/$tdir/f
23243         ls -la $DIR/$tdir
23244         FID=$(lfs path2fid $DIR/$tdir/f)
23245         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23246
23247         umount_client $MOUNT || error "failed to umount client"
23248         mount_client $MOUNT "$MOUNT_OPTS" ||
23249                 error "failed to mount client'"
23250
23251 }
23252 run_test 421f "rmfid checks permissions"
23253
23254 test_421g() {
23255         local cnt
23256         local FIDS
23257
23258         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23259         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23260                 skip "Need MDS version at least 2.12.54"
23261
23262         mkdir -p $DIR/$tdir
23263         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23264         createmany -o $DIR/$tdir/striped_dir/f 512
23265         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23266         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23267
23268         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23269                 sed "s/[/][^:]*://g")
23270
23271         rm -f $DIR/$tdir/striped_dir/f1*
23272         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23273         removed=$((512 - cnt))
23274
23275         # few files have been just removed, so we expect
23276         # rmfid to fail on their fids
23277         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23278         [ $removed != $errors ] && error "$errors != $removed"
23279
23280         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23281         rm -rf $DIR/$tdir
23282         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23283 }
23284 run_test 421g "rmfid to return errors properly"
23285
23286 test_422() {
23287         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23288         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23289         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23290         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23291         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23292
23293         local amc=$(at_max_get client)
23294         local amo=$(at_max_get mds1)
23295         local timeout=`lctl get_param -n timeout`
23296
23297         at_max_set 0 client
23298         at_max_set 0 mds1
23299
23300 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23301         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23302                         fail_val=$(((2*timeout + 10)*1000))
23303         touch $DIR/$tdir/d3/file &
23304         sleep 2
23305 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23306         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23307                         fail_val=$((2*timeout + 5))
23308         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23309         local pid=$!
23310         sleep 1
23311         kill -9 $pid
23312         sleep $((2 * timeout))
23313         echo kill $pid
23314         kill -9 $pid
23315         lctl mark touch
23316         touch $DIR/$tdir/d2/file3
23317         touch $DIR/$tdir/d2/file4
23318         touch $DIR/$tdir/d2/file5
23319
23320         wait
23321         at_max_set $amc client
23322         at_max_set $amo mds1
23323
23324         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23325         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23326                 error "Watchdog is always throttled"
23327 }
23328 run_test 422 "kill a process with RPC in progress"
23329
23330 stat_test() {
23331     df -h $MOUNT &
23332     df -h $MOUNT &
23333     df -h $MOUNT &
23334     df -h $MOUNT &
23335     df -h $MOUNT &
23336     df -h $MOUNT &
23337 }
23338
23339 test_423() {
23340     local _stats
23341     # ensure statfs cache is expired
23342     sleep 2;
23343
23344     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23345     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23346
23347     return 0
23348 }
23349 run_test 423 "statfs should return a right data"
23350
23351 test_424() {
23352 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23353         $LCTL set_param fail_loc=0x80000522
23354         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23355         rm -f $DIR/$tfile
23356 }
23357 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23358
23359 prep_801() {
23360         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23361         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23362                 skip "Need server version at least 2.9.55"
23363
23364         start_full_debug_logging
23365 }
23366
23367 post_801() {
23368         stop_full_debug_logging
23369 }
23370
23371 barrier_stat() {
23372         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23373                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23374                            awk '/The barrier for/ { print $7 }')
23375                 echo $st
23376         else
23377                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23378                 echo \'$st\'
23379         fi
23380 }
23381
23382 barrier_expired() {
23383         local expired
23384
23385         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23386                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23387                           awk '/will be expired/ { print $7 }')
23388         else
23389                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23390         fi
23391
23392         echo $expired
23393 }
23394
23395 test_801a() {
23396         prep_801
23397
23398         echo "Start barrier_freeze at: $(date)"
23399         #define OBD_FAIL_BARRIER_DELAY          0x2202
23400         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23401         # Do not reduce barrier time - See LU-11873
23402         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23403
23404         sleep 2
23405         local b_status=$(barrier_stat)
23406         echo "Got barrier status at: $(date)"
23407         [ "$b_status" = "'freezing_p1'" ] ||
23408                 error "(1) unexpected barrier status $b_status"
23409
23410         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23411         wait
23412         b_status=$(barrier_stat)
23413         [ "$b_status" = "'frozen'" ] ||
23414                 error "(2) unexpected barrier status $b_status"
23415
23416         local expired=$(barrier_expired)
23417         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23418         sleep $((expired + 3))
23419
23420         b_status=$(barrier_stat)
23421         [ "$b_status" = "'expired'" ] ||
23422                 error "(3) unexpected barrier status $b_status"
23423
23424         # Do not reduce barrier time - See LU-11873
23425         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23426                 error "(4) fail to freeze barrier"
23427
23428         b_status=$(barrier_stat)
23429         [ "$b_status" = "'frozen'" ] ||
23430                 error "(5) unexpected barrier status $b_status"
23431
23432         echo "Start barrier_thaw at: $(date)"
23433         #define OBD_FAIL_BARRIER_DELAY          0x2202
23434         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23435         do_facet mgs $LCTL barrier_thaw $FSNAME &
23436
23437         sleep 2
23438         b_status=$(barrier_stat)
23439         echo "Got barrier status at: $(date)"
23440         [ "$b_status" = "'thawing'" ] ||
23441                 error "(6) unexpected barrier status $b_status"
23442
23443         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23444         wait
23445         b_status=$(barrier_stat)
23446         [ "$b_status" = "'thawed'" ] ||
23447                 error "(7) unexpected barrier status $b_status"
23448
23449         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23450         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23451         do_facet mgs $LCTL barrier_freeze $FSNAME
23452
23453         b_status=$(barrier_stat)
23454         [ "$b_status" = "'failed'" ] ||
23455                 error "(8) unexpected barrier status $b_status"
23456
23457         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23458         do_facet mgs $LCTL barrier_thaw $FSNAME
23459
23460         post_801
23461 }
23462 run_test 801a "write barrier user interfaces and stat machine"
23463
23464 test_801b() {
23465         prep_801
23466
23467         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23468         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23469         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23470         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23471         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23472
23473         cancel_lru_locks mdc
23474
23475         # 180 seconds should be long enough
23476         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23477
23478         local b_status=$(barrier_stat)
23479         [ "$b_status" = "'frozen'" ] ||
23480                 error "(6) unexpected barrier status $b_status"
23481
23482         mkdir $DIR/$tdir/d0/d10 &
23483         mkdir_pid=$!
23484
23485         touch $DIR/$tdir/d1/f13 &
23486         touch_pid=$!
23487
23488         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23489         ln_pid=$!
23490
23491         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23492         mv_pid=$!
23493
23494         rm -f $DIR/$tdir/d4/f12 &
23495         rm_pid=$!
23496
23497         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
23498
23499         # To guarantee taht the 'stat' is not blocked
23500         b_status=$(barrier_stat)
23501         [ "$b_status" = "'frozen'" ] ||
23502                 error "(8) unexpected barrier status $b_status"
23503
23504         # let above commands to run at background
23505         sleep 5
23506
23507         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
23508         ps -p $touch_pid || error "(10) touch should be blocked"
23509         ps -p $ln_pid || error "(11) link should be blocked"
23510         ps -p $mv_pid || error "(12) rename should be blocked"
23511         ps -p $rm_pid || error "(13) unlink should be blocked"
23512
23513         b_status=$(barrier_stat)
23514         [ "$b_status" = "'frozen'" ] ||
23515                 error "(14) unexpected barrier status $b_status"
23516
23517         do_facet mgs $LCTL barrier_thaw $FSNAME
23518         b_status=$(barrier_stat)
23519         [ "$b_status" = "'thawed'" ] ||
23520                 error "(15) unexpected barrier status $b_status"
23521
23522         wait $mkdir_pid || error "(16) mkdir should succeed"
23523         wait $touch_pid || error "(17) touch should succeed"
23524         wait $ln_pid || error "(18) link should succeed"
23525         wait $mv_pid || error "(19) rename should succeed"
23526         wait $rm_pid || error "(20) unlink should succeed"
23527
23528         post_801
23529 }
23530 run_test 801b "modification will be blocked by write barrier"
23531
23532 test_801c() {
23533         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23534
23535         prep_801
23536
23537         stop mds2 || error "(1) Fail to stop mds2"
23538
23539         do_facet mgs $LCTL barrier_freeze $FSNAME 30
23540
23541         local b_status=$(barrier_stat)
23542         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
23543                 do_facet mgs $LCTL barrier_thaw $FSNAME
23544                 error "(2) unexpected barrier status $b_status"
23545         }
23546
23547         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23548                 error "(3) Fail to rescan barrier bitmap"
23549
23550         # Do not reduce barrier time - See LU-11873
23551         do_facet mgs $LCTL barrier_freeze $FSNAME 20
23552
23553         b_status=$(barrier_stat)
23554         [ "$b_status" = "'frozen'" ] ||
23555                 error "(4) unexpected barrier status $b_status"
23556
23557         do_facet mgs $LCTL barrier_thaw $FSNAME
23558         b_status=$(barrier_stat)
23559         [ "$b_status" = "'thawed'" ] ||
23560                 error "(5) unexpected barrier status $b_status"
23561
23562         local devname=$(mdsdevname 2)
23563
23564         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
23565
23566         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23567                 error "(7) Fail to rescan barrier bitmap"
23568
23569         post_801
23570 }
23571 run_test 801c "rescan barrier bitmap"
23572
23573 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
23574 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
23575 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
23576 saved_MOUNT_OPTS=$MOUNT_OPTS
23577
23578 cleanup_802a() {
23579         trap 0
23580
23581         stopall
23582         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
23583         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
23584         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
23585         MOUNT_OPTS=$saved_MOUNT_OPTS
23586         setupall
23587 }
23588
23589 test_802a() {
23590         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
23591         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23592         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23593                 skip "Need server version at least 2.9.55"
23594
23595         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
23596
23597         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23598
23599         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23600                 error "(2) Fail to copy"
23601
23602         trap cleanup_802a EXIT
23603
23604         # sync by force before remount as readonly
23605         sync; sync_all_data; sleep 3; sync_all_data
23606
23607         stopall
23608
23609         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
23610         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
23611         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
23612
23613         echo "Mount the server as read only"
23614         setupall server_only || error "(3) Fail to start servers"
23615
23616         echo "Mount client without ro should fail"
23617         mount_client $MOUNT &&
23618                 error "(4) Mount client without 'ro' should fail"
23619
23620         echo "Mount client with ro should succeed"
23621         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
23622         mount_client $MOUNT ||
23623                 error "(5) Mount client with 'ro' should succeed"
23624
23625         echo "Modify should be refused"
23626         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23627
23628         echo "Read should be allowed"
23629         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23630                 error "(7) Read should succeed under ro mode"
23631
23632         cleanup_802a
23633 }
23634 run_test 802a "simulate readonly device"
23635
23636 test_802b() {
23637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23638         remote_mds_nodsh && skip "remote MDS with nodsh"
23639
23640         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
23641                 skip "readonly option not available"
23642
23643         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
23644
23645         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23646                 error "(2) Fail to copy"
23647
23648         # write back all cached data before setting MDT to readonly
23649         cancel_lru_locks
23650         sync_all_data
23651
23652         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
23653         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
23654
23655         echo "Modify should be refused"
23656         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23657
23658         echo "Read should be allowed"
23659         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23660                 error "(7) Read should succeed under ro mode"
23661
23662         # disable readonly
23663         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
23664 }
23665 run_test 802b "be able to set MDTs to readonly"
23666
23667 test_803() {
23668         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23669         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23670                 skip "MDS needs to be newer than 2.10.54"
23671
23672         mkdir -p $DIR/$tdir
23673         # Create some objects on all MDTs to trigger related logs objects
23674         for idx in $(seq $MDSCOUNT); do
23675                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
23676                         $DIR/$tdir/dir${idx} ||
23677                         error "Fail to create $DIR/$tdir/dir${idx}"
23678         done
23679
23680         sync; sleep 3
23681         wait_delete_completed # ensure old test cleanups are finished
23682         echo "before create:"
23683         $LFS df -i $MOUNT
23684         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23685
23686         for i in {1..10}; do
23687                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
23688                         error "Fail to create $DIR/$tdir/foo$i"
23689         done
23690
23691         sync; sleep 3
23692         echo "after create:"
23693         $LFS df -i $MOUNT
23694         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23695
23696         # allow for an llog to be cleaned up during the test
23697         [ $after_used -ge $((before_used + 10 - 1)) ] ||
23698                 error "before ($before_used) + 10 > after ($after_used)"
23699
23700         for i in {1..10}; do
23701                 rm -rf $DIR/$tdir/foo$i ||
23702                         error "Fail to remove $DIR/$tdir/foo$i"
23703         done
23704
23705         sleep 3 # avoid MDT return cached statfs
23706         wait_delete_completed
23707         echo "after unlink:"
23708         $LFS df -i $MOUNT
23709         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23710
23711         # allow for an llog to be created during the test
23712         [ $after_used -le $((before_used + 1)) ] ||
23713                 error "after ($after_used) > before ($before_used) + 1"
23714 }
23715 run_test 803 "verify agent object for remote object"
23716
23717 test_804() {
23718         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23719         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23720                 skip "MDS needs to be newer than 2.10.54"
23721         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
23722
23723         mkdir -p $DIR/$tdir
23724         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
23725                 error "Fail to create $DIR/$tdir/dir0"
23726
23727         local fid=$($LFS path2fid $DIR/$tdir/dir0)
23728         local dev=$(mdsdevname 2)
23729
23730         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23731                 grep ${fid} || error "NOT found agent entry for dir0"
23732
23733         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
23734                 error "Fail to create $DIR/$tdir/dir1"
23735
23736         touch $DIR/$tdir/dir1/foo0 ||
23737                 error "Fail to create $DIR/$tdir/dir1/foo0"
23738         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
23739         local rc=0
23740
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
23748         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
23749                 error "Fail to rename foo0 to foo1"
23750         if [ $rc -eq 0 ]; then
23751                 for idx in $(seq $MDSCOUNT); do
23752                         dev=$(mdsdevname $idx)
23753                         do_facet mds${idx} \
23754                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23755                         grep ${fid} && rc=$idx
23756                 done
23757         fi
23758
23759         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
23760                 error "Fail to rename foo1 to foo2"
23761         if [ $rc -eq 0 ]; then
23762                 for idx in $(seq $MDSCOUNT); do
23763                         dev=$(mdsdevname $idx)
23764                         do_facet mds${idx} \
23765                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23766                         grep ${fid} && rc=$idx
23767                 done
23768         fi
23769
23770         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
23771
23772         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
23773                 error "Fail to link to $DIR/$tdir/dir1/foo2"
23774         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
23775                 error "Fail to rename foo2 to foo0"
23776         unlink $DIR/$tdir/dir1/foo0 ||
23777                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
23778         rm -rf $DIR/$tdir/dir0 ||
23779                 error "Fail to rm $DIR/$tdir/dir0"
23780
23781         for idx in $(seq $MDSCOUNT); do
23782                 dev=$(mdsdevname $idx)
23783                 rc=0
23784
23785                 stop mds${idx}
23786                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
23787                         rc=$?
23788                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
23789                         error "mount mds$idx failed"
23790                 df $MOUNT > /dev/null 2>&1
23791
23792                 # e2fsck should not return error
23793                 [ $rc -eq 0 ] ||
23794                         error "e2fsck detected error on MDT${idx}: rc=$rc"
23795         done
23796 }
23797 run_test 804 "verify agent entry for remote entry"
23798
23799 cleanup_805() {
23800         do_facet $SINGLEMDS zfs set quota=$old $fsset
23801         unlinkmany $DIR/$tdir/f- 1000000
23802         trap 0
23803 }
23804
23805 test_805() {
23806         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
23807         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
23808         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
23809                 skip "netfree not implemented before 0.7"
23810         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
23811                 skip "Need MDS version at least 2.10.57"
23812
23813         local fsset
23814         local freekb
23815         local usedkb
23816         local old
23817         local quota
23818         local pref="osd-zfs.$FSNAME-MDT0000."
23819
23820         # limit available space on MDS dataset to meet nospace issue
23821         # quickly. then ZFS 0.7.2 can use reserved space if asked
23822         # properly (using netfree flag in osd_declare_destroy()
23823         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
23824         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
23825                 gawk '{print $3}')
23826         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
23827         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
23828         let "usedkb=usedkb-freekb"
23829         let "freekb=freekb/2"
23830         if let "freekb > 5000"; then
23831                 let "freekb=5000"
23832         fi
23833         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
23834         trap cleanup_805 EXIT
23835         mkdir $DIR/$tdir
23836         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
23837                 error "Can't set PFL layout"
23838         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
23839         rm -rf $DIR/$tdir || error "not able to remove"
23840         do_facet $SINGLEMDS zfs set quota=$old $fsset
23841         trap 0
23842 }
23843 run_test 805 "ZFS can remove from full fs"
23844
23845 # Size-on-MDS test
23846 check_lsom_data()
23847 {
23848         local file=$1
23849         local size=$($LFS getsom -s $file)
23850         local expect=$(stat -c %s $file)
23851
23852         [[ $size == $expect ]] ||
23853                 error "$file expected size: $expect, got: $size"
23854
23855         local blocks=$($LFS getsom -b $file)
23856         expect=$(stat -c %b $file)
23857         [[ $blocks == $expect ]] ||
23858                 error "$file expected blocks: $expect, got: $blocks"
23859 }
23860
23861 check_lsom_size()
23862 {
23863         local size=$($LFS getsom -s $1)
23864         local expect=$2
23865
23866         [[ $size == $expect ]] ||
23867                 error "$file expected size: $expect, got: $size"
23868 }
23869
23870 test_806() {
23871         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23872                 skip "Need MDS version at least 2.11.52"
23873
23874         local bs=1048576
23875
23876         touch $DIR/$tfile || error "touch $tfile failed"
23877
23878         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23879         save_lustre_params client "llite.*.xattr_cache" > $save
23880         lctl set_param llite.*.xattr_cache=0
23881         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23882
23883         # single-threaded write
23884         echo "Test SOM for single-threaded write"
23885         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
23886                 error "write $tfile failed"
23887         check_lsom_size $DIR/$tfile $bs
23888
23889         local num=32
23890         local size=$(($num * $bs))
23891         local offset=0
23892         local i
23893
23894         echo "Test SOM for single client multi-threaded($num) write"
23895         $TRUNCATE $DIR/$tfile 0
23896         for ((i = 0; i < $num; i++)); do
23897                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23898                 local pids[$i]=$!
23899                 offset=$((offset + $bs))
23900         done
23901         for (( i=0; i < $num; i++ )); do
23902                 wait ${pids[$i]}
23903         done
23904         check_lsom_size $DIR/$tfile $size
23905
23906         $TRUNCATE $DIR/$tfile 0
23907         for ((i = 0; i < $num; i++)); do
23908                 offset=$((offset - $bs))
23909                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23910                 local pids[$i]=$!
23911         done
23912         for (( i=0; i < $num; i++ )); do
23913                 wait ${pids[$i]}
23914         done
23915         check_lsom_size $DIR/$tfile $size
23916
23917         # multi-client writes
23918         num=$(get_node_count ${CLIENTS//,/ })
23919         size=$(($num * $bs))
23920         offset=0
23921         i=0
23922
23923         echo "Test SOM for multi-client ($num) writes"
23924         $TRUNCATE $DIR/$tfile 0
23925         for client in ${CLIENTS//,/ }; do
23926                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23927                 local pids[$i]=$!
23928                 i=$((i + 1))
23929                 offset=$((offset + $bs))
23930         done
23931         for (( i=0; i < $num; i++ )); do
23932                 wait ${pids[$i]}
23933         done
23934         check_lsom_size $DIR/$tfile $offset
23935
23936         i=0
23937         $TRUNCATE $DIR/$tfile 0
23938         for client in ${CLIENTS//,/ }; do
23939                 offset=$((offset - $bs))
23940                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23941                 local pids[$i]=$!
23942                 i=$((i + 1))
23943         done
23944         for (( i=0; i < $num; i++ )); do
23945                 wait ${pids[$i]}
23946         done
23947         check_lsom_size $DIR/$tfile $size
23948
23949         # verify truncate
23950         echo "Test SOM for truncate"
23951         $TRUNCATE $DIR/$tfile 1048576
23952         check_lsom_size $DIR/$tfile 1048576
23953         $TRUNCATE $DIR/$tfile 1234
23954         check_lsom_size $DIR/$tfile 1234
23955
23956         # verify SOM blocks count
23957         echo "Verify SOM block count"
23958         $TRUNCATE $DIR/$tfile 0
23959         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
23960                 error "failed to write file $tfile"
23961         check_lsom_data $DIR/$tfile
23962 }
23963 run_test 806 "Verify Lazy Size on MDS"
23964
23965 test_807() {
23966         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23967         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23968                 skip "Need MDS version at least 2.11.52"
23969
23970         # Registration step
23971         changelog_register || error "changelog_register failed"
23972         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
23973         changelog_users $SINGLEMDS | grep -q $cl_user ||
23974                 error "User $cl_user not found in changelog_users"
23975
23976         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23977         save_lustre_params client "llite.*.xattr_cache" > $save
23978         lctl set_param llite.*.xattr_cache=0
23979         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23980
23981         rm -rf $DIR/$tdir || error "rm $tdir failed"
23982         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23983         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
23984         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
23985         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
23986                 error "truncate $tdir/trunc failed"
23987
23988         local bs=1048576
23989         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
23990                 error "write $tfile failed"
23991
23992         # multi-client wirtes
23993         local num=$(get_node_count ${CLIENTS//,/ })
23994         local offset=0
23995         local i=0
23996
23997         echo "Test SOM for multi-client ($num) writes"
23998         touch $DIR/$tfile || error "touch $tfile failed"
23999         $TRUNCATE $DIR/$tfile 0
24000         for client in ${CLIENTS//,/ }; do
24001                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24002                 local pids[$i]=$!
24003                 i=$((i + 1))
24004                 offset=$((offset + $bs))
24005         done
24006         for (( i=0; i < $num; i++ )); do
24007                 wait ${pids[$i]}
24008         done
24009
24010         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24011         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24012         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24013         check_lsom_data $DIR/$tdir/trunc
24014         check_lsom_data $DIR/$tdir/single_dd
24015         check_lsom_data $DIR/$tfile
24016
24017         rm -rf $DIR/$tdir
24018         # Deregistration step
24019         changelog_deregister || error "changelog_deregister failed"
24020 }
24021 run_test 807 "verify LSOM syncing tool"
24022
24023 check_som_nologged()
24024 {
24025         local lines=$($LFS changelog $FSNAME-MDT0000 |
24026                 grep 'x=trusted.som' | wc -l)
24027         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24028 }
24029
24030 test_808() {
24031         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24032                 skip "Need MDS version at least 2.11.55"
24033
24034         # Registration step
24035         changelog_register || error "changelog_register failed"
24036
24037         touch $DIR/$tfile || error "touch $tfile failed"
24038         check_som_nologged
24039
24040         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24041                 error "write $tfile failed"
24042         check_som_nologged
24043
24044         $TRUNCATE $DIR/$tfile 1234
24045         check_som_nologged
24046
24047         $TRUNCATE $DIR/$tfile 1048576
24048         check_som_nologged
24049
24050         # Deregistration step
24051         changelog_deregister || error "changelog_deregister failed"
24052 }
24053 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24054
24055 check_som_nodata()
24056 {
24057         $LFS getsom $1
24058         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24059 }
24060
24061 test_809() {
24062         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24063                 skip "Need MDS version at least 2.11.56"
24064
24065         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24066                 error "failed to create DoM-only file $DIR/$tfile"
24067         touch $DIR/$tfile || error "touch $tfile failed"
24068         check_som_nodata $DIR/$tfile
24069
24070         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24071                 error "write $tfile failed"
24072         check_som_nodata $DIR/$tfile
24073
24074         $TRUNCATE $DIR/$tfile 1234
24075         check_som_nodata $DIR/$tfile
24076
24077         $TRUNCATE $DIR/$tfile 4097
24078         check_som_nodata $DIR/$file
24079 }
24080 run_test 809 "Verify no SOM xattr store for DoM-only files"
24081
24082 test_810() {
24083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24084         $GSS && skip_env "could not run with gss"
24085         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24086                 skip "OST < 2.12.58 doesn't align checksum"
24087
24088         set_checksums 1
24089         stack_trap "set_checksums $ORIG_CSUM" EXIT
24090         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24091
24092         local csum
24093         local before
24094         local after
24095         for csum in $CKSUM_TYPES; do
24096                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24097                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24098                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24099                         eval set -- $i
24100                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24101                         before=$(md5sum $DIR/$tfile)
24102                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24103                         after=$(md5sum $DIR/$tfile)
24104                         [ "$before" == "$after" ] ||
24105                                 error "$csum: $before != $after bs=$1 seek=$2"
24106                 done
24107         done
24108 }
24109 run_test 810 "partial page writes on ZFS (LU-11663)"
24110
24111 test_812a() {
24112         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24113                 skip "OST < 2.12.51 doesn't support this fail_loc"
24114         [ "$SHARED_KEY" = true ] &&
24115                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24116
24117         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24118         # ensure ost1 is connected
24119         stat $DIR/$tfile >/dev/null || error "can't stat"
24120         wait_osc_import_state client ost1 FULL
24121         # no locks, no reqs to let the connection idle
24122         cancel_lru_locks osc
24123
24124         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24125 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24126         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24127         wait_osc_import_state client ost1 CONNECTING
24128         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24129
24130         stat $DIR/$tfile >/dev/null || error "can't stat file"
24131 }
24132 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24133
24134 test_812b() { # LU-12378
24135         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24136                 skip "OST < 2.12.51 doesn't support this fail_loc"
24137         [ "$SHARED_KEY" = true ] &&
24138                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24139
24140         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24141         # ensure ost1 is connected
24142         stat $DIR/$tfile >/dev/null || error "can't stat"
24143         wait_osc_import_state client ost1 FULL
24144         # no locks, no reqs to let the connection idle
24145         cancel_lru_locks osc
24146
24147         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24148 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24149         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24150         wait_osc_import_state client ost1 CONNECTING
24151         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24152
24153         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24154         wait_osc_import_state client ost1 IDLE
24155 }
24156 run_test 812b "do not drop no resend request for idle connect"
24157
24158 test_813() {
24159         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24160         [ -z "$file_heat_sav" ] && skip "no file heat support"
24161
24162         local readsample
24163         local writesample
24164         local readbyte
24165         local writebyte
24166         local readsample1
24167         local writesample1
24168         local readbyte1
24169         local writebyte1
24170
24171         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24172         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24173
24174         $LCTL set_param -n llite.*.file_heat=1
24175         echo "Turn on file heat"
24176         echo "Period second: $period_second, Decay percentage: $decay_pct"
24177
24178         echo "QQQQ" > $DIR/$tfile
24179         echo "QQQQ" > $DIR/$tfile
24180         echo "QQQQ" > $DIR/$tfile
24181         cat $DIR/$tfile > /dev/null
24182         cat $DIR/$tfile > /dev/null
24183         cat $DIR/$tfile > /dev/null
24184         cat $DIR/$tfile > /dev/null
24185
24186         local out=$($LFS heat_get $DIR/$tfile)
24187
24188         $LFS heat_get $DIR/$tfile
24189         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24190         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24191         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24192         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24193
24194         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24195         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24196         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24197         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24198
24199         sleep $((period_second + 3))
24200         echo "Sleep $((period_second + 3)) seconds..."
24201         # The recursion formula to calculate the heat of the file f is as
24202         # follow:
24203         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24204         # Where Hi is the heat value in the period between time points i*I and
24205         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24206         # to the weight of Ci.
24207         out=$($LFS heat_get $DIR/$tfile)
24208         $LFS heat_get $DIR/$tfile
24209         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24210         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24211         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24212         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24213
24214         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24215                 error "read sample ($readsample) is wrong"
24216         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24217                 error "write sample ($writesample) is wrong"
24218         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24219                 error "read bytes ($readbyte) is wrong"
24220         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24221                 error "write bytes ($writebyte) is wrong"
24222
24223         echo "QQQQ" > $DIR/$tfile
24224         echo "QQQQ" > $DIR/$tfile
24225         echo "QQQQ" > $DIR/$tfile
24226         cat $DIR/$tfile > /dev/null
24227         cat $DIR/$tfile > /dev/null
24228         cat $DIR/$tfile > /dev/null
24229         cat $DIR/$tfile > /dev/null
24230
24231         sleep $((period_second + 3))
24232         echo "Sleep $((period_second + 3)) seconds..."
24233
24234         out=$($LFS heat_get $DIR/$tfile)
24235         $LFS heat_get $DIR/$tfile
24236         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24237         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24238         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24239         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24240
24241         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24242                 4 * $decay_pct) / 100") -eq 1 ] ||
24243                 error "read sample ($readsample1) is wrong"
24244         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24245                 3 * $decay_pct) / 100") -eq 1 ] ||
24246                 error "write sample ($writesample1) is wrong"
24247         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24248                 20 * $decay_pct) / 100") -eq 1 ] ||
24249                 error "read bytes ($readbyte1) is wrong"
24250         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24251                 15 * $decay_pct) / 100") -eq 1 ] ||
24252                 error "write bytes ($writebyte1) is wrong"
24253
24254         echo "Turn off file heat for the file $DIR/$tfile"
24255         $LFS heat_set -o $DIR/$tfile
24256
24257         echo "QQQQ" > $DIR/$tfile
24258         echo "QQQQ" > $DIR/$tfile
24259         echo "QQQQ" > $DIR/$tfile
24260         cat $DIR/$tfile > /dev/null
24261         cat $DIR/$tfile > /dev/null
24262         cat $DIR/$tfile > /dev/null
24263         cat $DIR/$tfile > /dev/null
24264
24265         out=$($LFS heat_get $DIR/$tfile)
24266         $LFS heat_get $DIR/$tfile
24267         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24268         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24269         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24270         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24271
24272         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24273         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24274         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24275         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24276
24277         echo "Trun on file heat for the file $DIR/$tfile"
24278         $LFS heat_set -O $DIR/$tfile
24279
24280         echo "QQQQ" > $DIR/$tfile
24281         echo "QQQQ" > $DIR/$tfile
24282         echo "QQQQ" > $DIR/$tfile
24283         cat $DIR/$tfile > /dev/null
24284         cat $DIR/$tfile > /dev/null
24285         cat $DIR/$tfile > /dev/null
24286         cat $DIR/$tfile > /dev/null
24287
24288         out=$($LFS heat_get $DIR/$tfile)
24289         $LFS heat_get $DIR/$tfile
24290         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24291         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24292         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24293         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24294
24295         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24296         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24297         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24298         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24299
24300         $LFS heat_set -c $DIR/$tfile
24301         $LCTL set_param -n llite.*.file_heat=0
24302         echo "Turn off file heat support for the Lustre filesystem"
24303
24304         echo "QQQQ" > $DIR/$tfile
24305         echo "QQQQ" > $DIR/$tfile
24306         echo "QQQQ" > $DIR/$tfile
24307         cat $DIR/$tfile > /dev/null
24308         cat $DIR/$tfile > /dev/null
24309         cat $DIR/$tfile > /dev/null
24310         cat $DIR/$tfile > /dev/null
24311
24312         out=$($LFS heat_get $DIR/$tfile)
24313         $LFS heat_get $DIR/$tfile
24314         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24315         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24316         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24317         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24318
24319         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24320         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24321         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24322         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24323
24324         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24325         rm -f $DIR/$tfile
24326 }
24327 run_test 813 "File heat verfication"
24328
24329 test_814()
24330 {
24331         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24332         echo -n y >> $DIR/$tfile
24333         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24334         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24335 }
24336 run_test 814 "sparse cp works as expected (LU-12361)"
24337
24338 test_815()
24339 {
24340         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24341         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24342 }
24343 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24344
24345 test_816() {
24346         [ "$SHARED_KEY" = true ] &&
24347                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24348
24349         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24350         # ensure ost1 is connected
24351         stat $DIR/$tfile >/dev/null || error "can't stat"
24352         wait_osc_import_state client ost1 FULL
24353         # no locks, no reqs to let the connection idle
24354         cancel_lru_locks osc
24355         lru_resize_disable osc
24356         local before
24357         local now
24358         before=$($LCTL get_param -n \
24359                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24360
24361         wait_osc_import_state client ost1 IDLE
24362         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24363         now=$($LCTL get_param -n \
24364               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24365         [ $before == $now ] || error "lru_size changed $before != $now"
24366 }
24367 run_test 816 "do not reset lru_resize on idle reconnect"
24368
24369 cleanup_817() {
24370         umount $tmpdir
24371         exportfs -u localhost:$DIR/nfsexp
24372         rm -rf $DIR/nfsexp
24373 }
24374
24375 test_817() {
24376         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24377
24378         mkdir -p $DIR/nfsexp
24379         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24380                 error "failed to export nfs"
24381
24382         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24383         stack_trap cleanup_817 EXIT
24384
24385         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24386                 error "failed to mount nfs to $tmpdir"
24387
24388         cp /bin/true $tmpdir
24389         $DIR/nfsexp/true || error "failed to execute 'true' command"
24390 }
24391 run_test 817 "nfsd won't cache write lock for exec file"
24392
24393 test_818() {
24394         mkdir $DIR/$tdir
24395         $LFS setstripe -c1 -i0 $DIR/$tfile
24396         $LFS setstripe -c1 -i1 $DIR/$tfile
24397         stop $SINGLEMDS
24398         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24399         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24400         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24401                 error "start $SINGLEMDS failed"
24402         rm -rf $DIR/$tdir
24403 }
24404 run_test 818 "unlink with failed llog"
24405
24406 test_819a() {
24407         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24408         cancel_lru_locks osc
24409         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24410         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24411         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24412         rm -f $TDIR/$tfile
24413 }
24414 run_test 819a "too big niobuf in read"
24415
24416 test_819b() {
24417         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24418         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24419         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24420         cancel_lru_locks osc
24421         sleep 1
24422         rm -f $TDIR/$tfile
24423 }
24424 run_test 819b "too big niobuf in write"
24425
24426
24427 function test_820_start_ost() {
24428         sleep 5
24429
24430         for num in $(seq $OSTCOUNT); do
24431                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24432         done
24433 }
24434
24435 test_820() {
24436         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24437
24438         mkdir $DIR/$tdir
24439         umount_client $MOUNT || error "umount failed"
24440         for num in $(seq $OSTCOUNT); do
24441                 stop ost$num
24442         done
24443
24444         # mount client with no active OSTs
24445         # so that the client can't initialize max LOV EA size
24446         # from OSC notifications
24447         mount_client $MOUNT || error "mount failed"
24448         # delay OST starting to keep this 0 max EA size for a while
24449         test_820_start_ost &
24450
24451         # create a directory on MDS2
24452         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24453                 error "Failed to create directory"
24454         # open intent should update default EA size
24455         # see mdc_update_max_ea_from_body()
24456         # notice this is the very first RPC to MDS2
24457         cp /etc/services $DIR/$tdir/mds2 ||
24458                 error "Failed to copy files to mds$n"
24459 }
24460 run_test 820 "update max EA from open intent"
24461
24462 #
24463 # tests that do cleanup/setup should be run at the end
24464 #
24465
24466 test_900() {
24467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24468         local ls
24469
24470         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
24471         $LCTL set_param fail_loc=0x903
24472
24473         cancel_lru_locks MGC
24474
24475         FAIL_ON_ERROR=true cleanup
24476         FAIL_ON_ERROR=true setup
24477 }
24478 run_test 900 "umount should not race with any mgc requeue thread"
24479
24480 # LUS-6253/LU-11185
24481 test_901() {
24482         local oldc
24483         local newc
24484         local olds
24485         local news
24486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24487
24488         # some get_param have a bug to handle dot in param name
24489         cancel_lru_locks MGC
24490         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24491         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24492         umount_client $MOUNT || error "umount failed"
24493         mount_client $MOUNT || error "mount failed"
24494         cancel_lru_locks MGC
24495         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24496         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24497
24498         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
24499         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
24500
24501         return 0
24502 }
24503 run_test 901 "don't leak a mgc lock on client umount"
24504
24505 # LU-13377
24506 test_902() {
24507         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
24508                 skip "client does not have LU-13377 fix"
24509         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
24510         $LCTL set_param fail_loc=0x1415
24511         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24512         cancel_lru_locks osc
24513         rm -f $DIR/$tfile
24514 }
24515 run_test 902 "test short write doesn't hang lustre"
24516
24517 complete $SECONDS
24518 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
24519 check_and_cleanup_lustre
24520 if [ "$I_MOUNTED" != "yes" ]; then
24521         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
24522 fi
24523 exit_status