Whamcloud - gitweb
a0db0c0b68c62d6bfb2fc9dca91f61d0fbf5f307
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-9795 LU-9795 LU-9795 LU-9795
49         ALWAYS_EXCEPT+=" 17n     60a     133g    300f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64 fi
65
66 # skip nfs tests on kernels >= 4.12.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
68         # bug number:   LU-12661
69         ALWAYS_EXCEPT+=" 817"
70 fi
71 # skip cgroup tests on RHEL8.1 kernels until they are fixed
72 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
73       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
74         # bug number:   LU-13063
75         ALWAYS_EXCEPT+=" 411"
76 fi
77
78 #                                  5          12     8   12  (min)"
79 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
80
81 if [ "$mds1_FSTYPE" = "zfs" ]; then
82         # bug number for skipped test:
83         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
84         #                                               13    (min)"
85         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
86 fi
87
88 # Get the SLES distro version
89 #
90 # Returns a version string that should only be used in comparing
91 # strings returned by version_code()
92 sles_version_code()
93 {
94         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
95
96         # All SuSE Linux versions have one decimal. version_code expects two
97         local sles_version=$version.0
98         version_code $sles_version
99 }
100
101 # Check if we are running on Ubuntu or SLES so we can make decisions on
102 # what tests to run
103 if [ -r /etc/SuSE-release ]; then
104         sles_version=$(sles_version_code)
105         [ $sles_version -lt $(version_code 11.4.0) ] &&
106                 # bug number for skipped test: LU-4341
107                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
108         [ $sles_version -lt $(version_code 12.0.0) ] &&
109                 # bug number for skipped test: LU-3703
110                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
111 elif [ -r /etc/os-release ]; then
112         if grep -qi ubuntu /etc/os-release; then
113                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
114                                                 -e 's/^VERSION=//p' \
115                                                 /etc/os-release |
116                                                 awk '{ print $1 }'))
117
118                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
119                         # bug number for skipped test:
120                         #                LU-10334 LU-10366
121                         ALWAYS_EXCEPT+=" 103a     410"
122                 fi
123         fi
124 fi
125
126 build_test_filter
127 FAIL_ON_ERROR=false
128
129 cleanup() {
130         echo -n "cln.."
131         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
132         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
133 }
134 setup() {
135         echo -n "mnt.."
136         load_modules
137         setupall || exit 10
138         echo "done"
139 }
140
141 check_swap_layouts_support()
142 {
143         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
144                 skip "Does not support layout lock."
145 }
146
147 check_swap_layout_no_dom()
148 {
149         local FOLDER=$1
150         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
151         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
152 }
153
154 check_and_setup_lustre
155 DIR=${DIR:-$MOUNT}
156 assert_DIR
157
158 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
159
160 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
161 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
162 rm -rf $DIR/[Rdfs][0-9]*
163
164 # $RUNAS_ID may get set incorrectly somewhere else
165 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
166         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
167
168 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
169
170 if [ "${ONLY}" = "MOUNT" ] ; then
171         echo "Lustre is up, please go on"
172         exit
173 fi
174
175 echo "preparing for tests involving mounts"
176 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
177 touch $EXT2_DEV
178 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
179 echo # add a newline after mke2fs.
180
181 umask 077
182
183 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
184 lctl set_param debug=-1 2> /dev/null || true
185 test_0a() {
186         touch $DIR/$tfile
187         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
188         rm $DIR/$tfile
189         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
190 }
191 run_test 0a "touch; rm ====================="
192
193 test_0b() {
194         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
195         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
196 }
197 run_test 0b "chmod 0755 $DIR ============================="
198
199 test_0c() {
200         $LCTL get_param mdc.*.import | grep "state: FULL" ||
201                 error "import not FULL"
202         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
203                 error "bad target"
204 }
205 run_test 0c "check import proc"
206
207 test_0d() { # LU-3397
208         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
209                 skip "proc exports not supported before 2.10.57"
210
211         local mgs_exp="mgs.MGS.exports"
212         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
213         local exp_client_nid
214         local exp_client_version
215         local exp_val
216         local imp_val
217         local temp_imp=$DIR/$tfile.import
218         local temp_exp=$DIR/$tfile.export
219
220         # save mgc import file to $temp_imp
221         $LCTL get_param mgc.*.import | tee $temp_imp
222         # Check if client uuid is found in MGS export
223         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
224                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
225                         $client_uuid ] &&
226                         break;
227         done
228         # save mgs export file to $temp_exp
229         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
230
231         # Compare the value of field "connect_flags"
232         imp_val=$(grep "connect_flags" $temp_imp)
233         exp_val=$(grep "connect_flags" $temp_exp)
234         [ "$exp_val" == "$imp_val" ] ||
235                 error "export flags '$exp_val' != import flags '$imp_val'"
236
237         # Compare the value of client version
238         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
239         exp_val=$(version_code $exp_client_version)
240         imp_val=$CLIENT_VERSION
241         [ "$exp_val" == "$imp_val" ] ||
242                 error "export client version '$exp_val' != '$imp_val'"
243 }
244 run_test 0d "check export proc ============================="
245
246 test_1() {
247         test_mkdir $DIR/$tdir
248         test_mkdir $DIR/$tdir/d2
249         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
250         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
251         rmdir $DIR/$tdir/d2
252         rmdir $DIR/$tdir
253         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
254 }
255 run_test 1 "mkdir; remkdir; rmdir"
256
257 test_2() {
258         test_mkdir $DIR/$tdir
259         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
260         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
261         rm -r $DIR/$tdir
262         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
263 }
264 run_test 2 "mkdir; touch; rmdir; check file"
265
266 test_3() {
267         test_mkdir $DIR/$tdir
268         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
269         touch $DIR/$tdir/$tfile
270         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
271         rm -r $DIR/$tdir
272         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
273 }
274 run_test 3 "mkdir; touch; rmdir; check dir"
275
276 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
277 test_4() {
278         test_mkdir -i 1 $DIR/$tdir
279
280         touch $DIR/$tdir/$tfile ||
281                 error "Create file under remote directory failed"
282
283         rmdir $DIR/$tdir &&
284                 error "Expect error removing in-use dir $DIR/$tdir"
285
286         test -d $DIR/$tdir || error "Remote directory disappeared"
287
288         rm -rf $DIR/$tdir || error "remove remote dir error"
289 }
290 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
291
292 test_5() {
293         test_mkdir $DIR/$tdir
294         test_mkdir $DIR/$tdir/d2
295         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
296         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
297         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
298 }
299 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
300
301 test_6a() {
302         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
303         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
304         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
305                 error "$tfile does not have perm 0666 or UID $UID"
306         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
307         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
308                 error "$tfile should be 0666 and owned by UID $UID"
309 }
310 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
311
312 test_6c() {
313         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
314
315         touch $DIR/$tfile
316         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
317         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
318                 error "$tfile should be owned by UID $RUNAS_ID"
319         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
320         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
321                 error "$tfile should be owned by UID $RUNAS_ID"
322 }
323 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
324
325 test_6e() {
326         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
327
328         touch $DIR/$tfile
329         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
330         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
331                 error "$tfile should be owned by GID $UID"
332         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
333         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
334                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
335 }
336 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
337
338 test_6g() {
339         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
340
341         test_mkdir $DIR/$tdir
342         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
343         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
344         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
345         test_mkdir $DIR/$tdir/d/subdir
346         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
347                 error "$tdir/d/subdir should be GID $RUNAS_GID"
348         if [[ $MDSCOUNT -gt 1 ]]; then
349                 # check remote dir sgid inherite
350                 $LFS mkdir -i 0 $DIR/$tdir.local ||
351                         error "mkdir $tdir.local failed"
352                 chmod g+s $DIR/$tdir.local ||
353                         error "chmod $tdir.local failed"
354                 chgrp $RUNAS_GID $DIR/$tdir.local ||
355                         error "chgrp $tdir.local failed"
356                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
357                         error "mkdir $tdir.remote failed"
358                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
359                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
360                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
361                         error "$tdir.remote should be mode 02755"
362         fi
363 }
364 run_test 6g "verify new dir in sgid dir inherits group"
365
366 test_6h() { # bug 7331
367         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
368
369         touch $DIR/$tfile || error "touch failed"
370         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
371         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
372                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
373         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
374                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
375 }
376 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
377
378 test_7a() {
379         test_mkdir $DIR/$tdir
380         $MCREATE $DIR/$tdir/$tfile
381         chmod 0666 $DIR/$tdir/$tfile
382         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
383                 error "$tdir/$tfile should be mode 0666"
384 }
385 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
386
387 test_7b() {
388         if [ ! -d $DIR/$tdir ]; then
389                 test_mkdir $DIR/$tdir
390         fi
391         $MCREATE $DIR/$tdir/$tfile
392         echo -n foo > $DIR/$tdir/$tfile
393         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
394         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
395 }
396 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
397
398 test_8() {
399         test_mkdir $DIR/$tdir
400         touch $DIR/$tdir/$tfile
401         chmod 0666 $DIR/$tdir/$tfile
402         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
403                 error "$tfile mode not 0666"
404 }
405 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
406
407 test_9() {
408         test_mkdir $DIR/$tdir
409         test_mkdir $DIR/$tdir/d2
410         test_mkdir $DIR/$tdir/d2/d3
411         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
412 }
413 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
414
415 test_10() {
416         test_mkdir $DIR/$tdir
417         test_mkdir $DIR/$tdir/d2
418         touch $DIR/$tdir/d2/$tfile
419         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
420                 error "$tdir/d2/$tfile not a file"
421 }
422 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
423
424 test_11() {
425         test_mkdir $DIR/$tdir
426         test_mkdir $DIR/$tdir/d2
427         chmod 0666 $DIR/$tdir/d2
428         chmod 0705 $DIR/$tdir/d2
429         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
430                 error "$tdir/d2 mode not 0705"
431 }
432 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
433
434 test_12() {
435         test_mkdir $DIR/$tdir
436         touch $DIR/$tdir/$tfile
437         chmod 0666 $DIR/$tdir/$tfile
438         chmod 0654 $DIR/$tdir/$tfile
439         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
440                 error "$tdir/d2 mode not 0654"
441 }
442 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
443
444 test_13() {
445         test_mkdir $DIR/$tdir
446         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
447         >  $DIR/$tdir/$tfile
448         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
449                 error "$tdir/$tfile size not 0 after truncate"
450 }
451 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
452
453 test_14() {
454         test_mkdir $DIR/$tdir
455         touch $DIR/$tdir/$tfile
456         rm $DIR/$tdir/$tfile
457         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
458 }
459 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
460
461 test_15() {
462         test_mkdir $DIR/$tdir
463         touch $DIR/$tdir/$tfile
464         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
465         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
466                 error "$tdir/${tfile_2} not a file after rename"
467         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
468 }
469 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
470
471 test_16() {
472         test_mkdir $DIR/$tdir
473         touch $DIR/$tdir/$tfile
474         rm -rf $DIR/$tdir/$tfile
475         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
476 }
477 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
478
479 test_17a() {
480         test_mkdir $DIR/$tdir
481         touch $DIR/$tdir/$tfile
482         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
483         ls -l $DIR/$tdir
484         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
485                 error "$tdir/l-exist not a symlink"
486         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
487                 error "$tdir/l-exist not referencing a file"
488         rm -f $DIR/$tdir/l-exist
489         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
490 }
491 run_test 17a "symlinks: create, remove (real)"
492
493 test_17b() {
494         test_mkdir $DIR/$tdir
495         ln -s no-such-file $DIR/$tdir/l-dangle
496         ls -l $DIR/$tdir
497         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
498                 error "$tdir/l-dangle not referencing no-such-file"
499         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
500                 error "$tdir/l-dangle not referencing non-existent file"
501         rm -f $DIR/$tdir/l-dangle
502         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
503 }
504 run_test 17b "symlinks: create, remove (dangling)"
505
506 test_17c() { # bug 3440 - don't save failed open RPC for replay
507         test_mkdir $DIR/$tdir
508         ln -s foo $DIR/$tdir/$tfile
509         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
510 }
511 run_test 17c "symlinks: open dangling (should return error)"
512
513 test_17d() {
514         test_mkdir $DIR/$tdir
515         ln -s foo $DIR/$tdir/$tfile
516         touch $DIR/$tdir/$tfile || error "creating to new symlink"
517 }
518 run_test 17d "symlinks: create dangling"
519
520 test_17e() {
521         test_mkdir $DIR/$tdir
522         local foo=$DIR/$tdir/$tfile
523         ln -s $foo $foo || error "create symlink failed"
524         ls -l $foo || error "ls -l failed"
525         ls $foo && error "ls not failed" || true
526 }
527 run_test 17e "symlinks: create recursive symlink (should return error)"
528
529 test_17f() {
530         test_mkdir $DIR/$tdir
531         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
532         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
533         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
534         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
535         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
536         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
537         ls -l  $DIR/$tdir
538 }
539 run_test 17f "symlinks: long and very long symlink name"
540
541 # str_repeat(S, N) generate a string that is string S repeated N times
542 str_repeat() {
543         local s=$1
544         local n=$2
545         local ret=''
546         while [ $((n -= 1)) -ge 0 ]; do
547                 ret=$ret$s
548         done
549         echo $ret
550 }
551
552 # Long symlinks and LU-2241
553 test_17g() {
554         test_mkdir $DIR/$tdir
555         local TESTS="59 60 61 4094 4095"
556
557         # Fix for inode size boundary in 2.1.4
558         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
559                 TESTS="4094 4095"
560
561         # Patch not applied to 2.2 or 2.3 branches
562         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
563         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
564                 TESTS="4094 4095"
565
566         for i in $TESTS; do
567                 local SYMNAME=$(str_repeat 'x' $i)
568                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
569                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
570         done
571 }
572 run_test 17g "symlinks: really long symlink name and inode boundaries"
573
574 test_17h() { #bug 17378
575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
576         remote_mds_nodsh && skip "remote MDS with nodsh"
577
578         local mdt_idx
579
580         test_mkdir $DIR/$tdir
581         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
582         $LFS setstripe -c -1 $DIR/$tdir
583         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
584         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
585         touch $DIR/$tdir/$tfile || true
586 }
587 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
588
589 test_17i() { #bug 20018
590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
591         remote_mds_nodsh && skip "remote MDS with nodsh"
592
593         local foo=$DIR/$tdir/$tfile
594         local mdt_idx
595
596         test_mkdir -c1 $DIR/$tdir
597         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
598         ln -s $foo $foo || error "create symlink failed"
599 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
600         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
601         ls -l $foo && error "error not detected"
602         return 0
603 }
604 run_test 17i "don't panic on short symlink (should return error)"
605
606 test_17k() { #bug 22301
607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
608         [[ -z "$(which rsync 2>/dev/null)" ]] &&
609                 skip "no rsync command"
610         rsync --help | grep -q xattr ||
611                 skip_env "$(rsync --version | head -n1) does not support xattrs"
612         test_mkdir $DIR/$tdir
613         test_mkdir $DIR/$tdir.new
614         touch $DIR/$tdir/$tfile
615         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
616         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
617                 error "rsync failed with xattrs enabled"
618 }
619 run_test 17k "symlinks: rsync with xattrs enabled"
620
621 test_17l() { # LU-279
622         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
623                 skip "no getfattr command"
624
625         test_mkdir $DIR/$tdir
626         touch $DIR/$tdir/$tfile
627         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
628         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
629                 # -h to not follow symlinks. -m '' to list all the xattrs.
630                 # grep to remove first line: '# file: $path'.
631                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
632                 do
633                         lgetxattr_size_check $path $xattr ||
634                                 error "lgetxattr_size_check $path $xattr failed"
635                 done
636         done
637 }
638 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
639
640 # LU-1540
641 test_17m() {
642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
643         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
644         remote_mds_nodsh && skip "remote MDS with nodsh"
645         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
646         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
647                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
648
649         local short_sym="0123456789"
650         local wdir=$DIR/$tdir
651         local i
652
653         test_mkdir $wdir
654         long_sym=$short_sym
655         # create a long symlink file
656         for ((i = 0; i < 4; ++i)); do
657                 long_sym=${long_sym}${long_sym}
658         done
659
660         echo "create 512 short and long symlink files under $wdir"
661         for ((i = 0; i < 256; ++i)); do
662                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
663                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
664         done
665
666         echo "erase them"
667         rm -f $wdir/*
668         sync
669         wait_delete_completed
670
671         echo "recreate the 512 symlink files with a shorter string"
672         for ((i = 0; i < 512; ++i)); do
673                 # rewrite the symlink file with a shorter string
674                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
675                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
676         done
677
678         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
679         local devname=$(mdsdevname $mds_index)
680
681         echo "stop and checking mds${mds_index}:"
682         # e2fsck should not return error
683         stop mds${mds_index}
684         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
685         rc=$?
686
687         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
688                 error "start mds${mds_index} failed"
689         df $MOUNT > /dev/null 2>&1
690         [ $rc -eq 0 ] ||
691                 error "e2fsck detected error for short/long symlink: rc=$rc"
692         rm -f $wdir/*
693 }
694 run_test 17m "run e2fsck against MDT which contains short/long symlink"
695
696 check_fs_consistency_17n() {
697         local mdt_index
698         local rc=0
699
700         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
701         # so it only check MDT1/MDT2 instead of all of MDTs.
702         for mdt_index in 1 2; do
703                 local devname=$(mdsdevname $mdt_index)
704                 # e2fsck should not return error
705                 stop mds${mdt_index}
706                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
707                         rc=$((rc + $?))
708
709                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
710                         error "mount mds$mdt_index failed"
711                 df $MOUNT > /dev/null 2>&1
712         done
713         return $rc
714 }
715
716 test_17n() {
717         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
719         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
720         remote_mds_nodsh && skip "remote MDS with nodsh"
721         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
722         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
723                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
724
725         local i
726
727         test_mkdir $DIR/$tdir
728         for ((i=0; i<10; i++)); do
729                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
730                         error "create remote dir error $i"
731                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
732                         error "create files under remote dir failed $i"
733         done
734
735         check_fs_consistency_17n ||
736                 error "e2fsck report error after create files under remote dir"
737
738         for ((i = 0; i < 10; i++)); do
739                 rm -rf $DIR/$tdir/remote_dir_${i} ||
740                         error "destroy remote dir error $i"
741         done
742
743         check_fs_consistency_17n ||
744                 error "e2fsck report error after unlink files under remote dir"
745
746         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
747                 skip "lustre < 2.4.50 does not support migrate mv"
748
749         for ((i = 0; i < 10; i++)); do
750                 mkdir -p $DIR/$tdir/remote_dir_${i}
751                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
752                         error "create files under remote dir failed $i"
753                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
754                         error "migrate remote dir error $i"
755         done
756         check_fs_consistency_17n || error "e2fsck report error after migration"
757
758         for ((i = 0; i < 10; i++)); do
759                 rm -rf $DIR/$tdir/remote_dir_${i} ||
760                         error "destroy remote dir error $i"
761         done
762
763         check_fs_consistency_17n || error "e2fsck report error after unlink"
764 }
765 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
766
767 test_17o() {
768         remote_mds_nodsh && skip "remote MDS with nodsh"
769         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
770                 skip "Need MDS version at least 2.3.64"
771
772         local wdir=$DIR/${tdir}o
773         local mdt_index
774         local rc=0
775
776         test_mkdir $wdir
777         touch $wdir/$tfile
778         mdt_index=$($LFS getstripe -m $wdir/$tfile)
779         mdt_index=$((mdt_index + 1))
780
781         cancel_lru_locks mdc
782         #fail mds will wait the failover finish then set
783         #following fail_loc to avoid interfer the recovery process.
784         fail mds${mdt_index}
785
786         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
787         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
788         ls -l $wdir/$tfile && rc=1
789         do_facet mds${mdt_index} lctl set_param fail_loc=0
790         [[ $rc -eq 0 ]] || error "stat file should fail"
791 }
792 run_test 17o "stat file with incompat LMA feature"
793
794 test_18() {
795         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
796         ls $DIR || error "Failed to ls $DIR: $?"
797 }
798 run_test 18 "touch .../f ; ls ... =============================="
799
800 test_19a() {
801         touch $DIR/$tfile
802         ls -l $DIR
803         rm $DIR/$tfile
804         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
805 }
806 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
807
808 test_19b() {
809         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
810 }
811 run_test 19b "ls -l .../f19 (should return error) =============="
812
813 test_19c() {
814         [ $RUNAS_ID -eq $UID ] &&
815                 skip_env "RUNAS_ID = UID = $UID -- skipping"
816
817         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
818 }
819 run_test 19c "$RUNAS touch .../f19 (should return error) =="
820
821 test_19d() {
822         cat $DIR/f19 && error || true
823 }
824 run_test 19d "cat .../f19 (should return error) =============="
825
826 test_20() {
827         touch $DIR/$tfile
828         rm $DIR/$tfile
829         touch $DIR/$tfile
830         rm $DIR/$tfile
831         touch $DIR/$tfile
832         rm $DIR/$tfile
833         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
834 }
835 run_test 20 "touch .../f ; ls -l ..."
836
837 test_21() {
838         test_mkdir $DIR/$tdir
839         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
840         ln -s dangle $DIR/$tdir/link
841         echo foo >> $DIR/$tdir/link
842         cat $DIR/$tdir/dangle
843         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
844         $CHECKSTAT -f -t file $DIR/$tdir/link ||
845                 error "$tdir/link not linked to a file"
846 }
847 run_test 21 "write to dangling link"
848
849 test_22() {
850         local wdir=$DIR/$tdir
851         test_mkdir $wdir
852         chown $RUNAS_ID:$RUNAS_GID $wdir
853         (cd $wdir || error "cd $wdir failed";
854                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
855                 $RUNAS tar xf -)
856         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
857         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
858         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
859                 error "checkstat -u failed"
860 }
861 run_test 22 "unpack tar archive as non-root user"
862
863 # was test_23
864 test_23a() {
865         test_mkdir $DIR/$tdir
866         local file=$DIR/$tdir/$tfile
867
868         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
869         openfile -f O_CREAT:O_EXCL $file &&
870                 error "$file recreate succeeded" || true
871 }
872 run_test 23a "O_CREAT|O_EXCL in subdir"
873
874 test_23b() { # bug 18988
875         test_mkdir $DIR/$tdir
876         local file=$DIR/$tdir/$tfile
877
878         rm -f $file
879         echo foo > $file || error "write filed"
880         echo bar >> $file || error "append filed"
881         $CHECKSTAT -s 8 $file || error "wrong size"
882         rm $file
883 }
884 run_test 23b "O_APPEND check"
885
886 # LU-9409, size with O_APPEND and tiny writes
887 test_23c() {
888         local file=$DIR/$tfile
889
890         # single dd
891         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
892         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
893         rm -f $file
894
895         # racing tiny writes
896         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
897         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
898         wait
899         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
900         rm -f $file
901
902         #racing tiny & normal writes
903         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
905         wait
906         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
907         rm -f $file
908
909         #racing tiny & normal writes 2, ugly numbers
910         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
911         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
912         wait
913         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
914         rm -f $file
915 }
916 run_test 23c "O_APPEND size checks for tiny writes"
917
918 # LU-11069 file offset is correct after appending writes
919 test_23d() {
920         local file=$DIR/$tfile
921         local offset
922
923         echo CentaurHauls > $file
924         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
925         if ((offset != 26)); then
926                 error "wrong offset, expected 26, got '$offset'"
927         fi
928 }
929 run_test 23d "file offset is correct after appending writes"
930
931 # rename sanity
932 test_24a() {
933         echo '-- same directory rename'
934         test_mkdir $DIR/$tdir
935         touch $DIR/$tdir/$tfile.1
936         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
937         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
938 }
939 run_test 24a "rename file to non-existent target"
940
941 test_24b() {
942         test_mkdir $DIR/$tdir
943         touch $DIR/$tdir/$tfile.{1,2}
944         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
945         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
946         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
947 }
948 run_test 24b "rename file to existing target"
949
950 test_24c() {
951         test_mkdir $DIR/$tdir
952         test_mkdir $DIR/$tdir/d$testnum.1
953         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
954         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
955         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
956 }
957 run_test 24c "rename directory to non-existent target"
958
959 test_24d() {
960         test_mkdir -c1 $DIR/$tdir
961         test_mkdir -c1 $DIR/$tdir/d$testnum.1
962         test_mkdir -c1 $DIR/$tdir/d$testnum.2
963         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
964         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
965         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
966 }
967 run_test 24d "rename directory to existing target"
968
969 test_24e() {
970         echo '-- cross directory renames --'
971         test_mkdir $DIR/R5a
972         test_mkdir $DIR/R5b
973         touch $DIR/R5a/f
974         mv $DIR/R5a/f $DIR/R5b/g
975         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
976         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
977 }
978 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
979
980 test_24f() {
981         test_mkdir $DIR/R6a
982         test_mkdir $DIR/R6b
983         touch $DIR/R6a/f $DIR/R6b/g
984         mv $DIR/R6a/f $DIR/R6b/g
985         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
986         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
987 }
988 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
989
990 test_24g() {
991         test_mkdir $DIR/R7a
992         test_mkdir $DIR/R7b
993         test_mkdir $DIR/R7a/d
994         mv $DIR/R7a/d $DIR/R7b/e
995         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
996         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
997 }
998 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
999
1000 test_24h() {
1001         test_mkdir -c1 $DIR/R8a
1002         test_mkdir -c1 $DIR/R8b
1003         test_mkdir -c1 $DIR/R8a/d
1004         test_mkdir -c1 $DIR/R8b/e
1005         mrename $DIR/R8a/d $DIR/R8b/e
1006         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1007         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1008 }
1009 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1010
1011 test_24i() {
1012         echo "-- rename error cases"
1013         test_mkdir $DIR/R9
1014         test_mkdir $DIR/R9/a
1015         touch $DIR/R9/f
1016         mrename $DIR/R9/f $DIR/R9/a
1017         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1018         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1019         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1020 }
1021 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1022
1023 test_24j() {
1024         test_mkdir $DIR/R10
1025         mrename $DIR/R10/f $DIR/R10/g
1026         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1027         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1028         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1029 }
1030 run_test 24j "source does not exist ============================"
1031
1032 test_24k() {
1033         test_mkdir $DIR/R11a
1034         test_mkdir $DIR/R11a/d
1035         touch $DIR/R11a/f
1036         mv $DIR/R11a/f $DIR/R11a/d
1037         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1038         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1039 }
1040 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1041
1042 # bug 2429 - rename foo foo foo creates invalid file
1043 test_24l() {
1044         f="$DIR/f24l"
1045         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1046 }
1047 run_test 24l "Renaming a file to itself ========================"
1048
1049 test_24m() {
1050         f="$DIR/f24m"
1051         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1052         # on ext3 this does not remove either the source or target files
1053         # though the "expected" operation would be to remove the source
1054         $CHECKSTAT -t file ${f} || error "${f} missing"
1055         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1056 }
1057 run_test 24m "Renaming a file to a hard link to itself ========="
1058
1059 test_24n() {
1060     f="$DIR/f24n"
1061     # this stats the old file after it was renamed, so it should fail
1062     touch ${f}
1063     $CHECKSTAT ${f} || error "${f} missing"
1064     mv ${f} ${f}.rename
1065     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1066     $CHECKSTAT -a ${f} || error "${f} exists"
1067 }
1068 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1069
1070 test_24o() {
1071         test_mkdir $DIR/$tdir
1072         rename_many -s random -v -n 10 $DIR/$tdir
1073 }
1074 run_test 24o "rename of files during htree split"
1075
1076 test_24p() {
1077         test_mkdir $DIR/R12a
1078         test_mkdir $DIR/R12b
1079         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1080         mrename $DIR/R12a $DIR/R12b
1081         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1082         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1083         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1084         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1085 }
1086 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1087
1088 cleanup_multiop_pause() {
1089         trap 0
1090         kill -USR1 $MULTIPID
1091 }
1092
1093 test_24q() {
1094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1095
1096         test_mkdir $DIR/R13a
1097         test_mkdir $DIR/R13b
1098         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1099         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1100         MULTIPID=$!
1101
1102         trap cleanup_multiop_pause EXIT
1103         mrename $DIR/R13a $DIR/R13b
1104         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1105         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1106         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1107         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1108         cleanup_multiop_pause
1109         wait $MULTIPID || error "multiop close failed"
1110 }
1111 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1112
1113 test_24r() { #bug 3789
1114         test_mkdir $DIR/R14a
1115         test_mkdir $DIR/R14a/b
1116         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1117         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1118         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1119 }
1120 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1121
1122 test_24s() {
1123         test_mkdir $DIR/R15a
1124         test_mkdir $DIR/R15a/b
1125         test_mkdir $DIR/R15a/b/c
1126         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1127         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1128         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1129 }
1130 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1131 test_24t() {
1132         test_mkdir $DIR/R16a
1133         test_mkdir $DIR/R16a/b
1134         test_mkdir $DIR/R16a/b/c
1135         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1136         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1137         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1138 }
1139 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1140
1141 test_24u() { # bug12192
1142         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1143         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1144 }
1145 run_test 24u "create stripe file"
1146
1147 simple_cleanup_common() {
1148         local rc=0
1149         trap 0
1150         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1151
1152         local start=$SECONDS
1153         rm -rf $DIR/$tdir
1154         rc=$?
1155         wait_delete_completed
1156         echo "cleanup time $((SECONDS - start))"
1157         return $rc
1158 }
1159
1160 max_pages_per_rpc() {
1161         local mdtname="$(printf "MDT%04x" ${1:-0})"
1162         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1163 }
1164
1165 test_24v() {
1166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1167
1168         local nrfiles=${COUNT:-100000}
1169         local fname="$DIR/$tdir/$tfile"
1170
1171         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1172         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1173
1174         test_mkdir "$(dirname $fname)"
1175         # assume MDT0000 has the fewest inodes
1176         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1177         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1178         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1179
1180         trap simple_cleanup_common EXIT
1181
1182         createmany -m "$fname" $nrfiles
1183
1184         cancel_lru_locks mdc
1185         lctl set_param mdc.*.stats clear
1186
1187         # was previously test_24D: LU-6101
1188         # readdir() returns correct number of entries after cursor reload
1189         local num_ls=$(ls $DIR/$tdir | wc -l)
1190         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1191         local num_all=$(ls -a $DIR/$tdir | wc -l)
1192         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1193                 [ $num_all -ne $((nrfiles + 2)) ]; then
1194                         error "Expected $nrfiles files, got $num_ls " \
1195                                 "($num_uniq unique $num_all .&..)"
1196         fi
1197         # LU-5 large readdir
1198         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1199         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1200         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1201         # take into account of overhead in lu_dirpage header and end mark in
1202         # each page, plus one in rpc_num calculation.
1203         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1204         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1205         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1206         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1207         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1208         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1209         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1210         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1211                 error "large readdir doesn't take effect: " \
1212                       "$mds_readpage should be about $rpc_max"
1213
1214         simple_cleanup_common
1215 }
1216 run_test 24v "list large directory (test hash collision, b=17560)"
1217
1218 test_24w() { # bug21506
1219         SZ1=234852
1220         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1221         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1222         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1223         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1224         [[ "$SZ1" -eq "$SZ2" ]] ||
1225                 error "Error reading at the end of the file $tfile"
1226 }
1227 run_test 24w "Reading a file larger than 4Gb"
1228
1229 test_24x() {
1230         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1232         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1233                 skip "Need MDS version at least 2.7.56"
1234
1235         local MDTIDX=1
1236         local remote_dir=$DIR/$tdir/remote_dir
1237
1238         test_mkdir $DIR/$tdir
1239         $LFS mkdir -i $MDTIDX $remote_dir ||
1240                 error "create remote directory failed"
1241
1242         test_mkdir $DIR/$tdir/src_dir
1243         touch $DIR/$tdir/src_file
1244         test_mkdir $remote_dir/tgt_dir
1245         touch $remote_dir/tgt_file
1246
1247         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1248                 error "rename dir cross MDT failed!"
1249
1250         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1251                 error "rename file cross MDT failed!"
1252
1253         touch $DIR/$tdir/ln_file
1254         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1255                 error "ln file cross MDT failed"
1256
1257         rm -rf $DIR/$tdir || error "Can not delete directories"
1258 }
1259 run_test 24x "cross MDT rename/link"
1260
1261 test_24y() {
1262         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1264
1265         local remote_dir=$DIR/$tdir/remote_dir
1266         local mdtidx=1
1267
1268         test_mkdir $DIR/$tdir
1269         $LFS mkdir -i $mdtidx $remote_dir ||
1270                 error "create remote directory failed"
1271
1272         test_mkdir $remote_dir/src_dir
1273         touch $remote_dir/src_file
1274         test_mkdir $remote_dir/tgt_dir
1275         touch $remote_dir/tgt_file
1276
1277         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1278                 error "rename subdir in the same remote dir failed!"
1279
1280         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1281                 error "rename files in the same remote dir failed!"
1282
1283         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1284                 error "link files in the same remote dir failed!"
1285
1286         rm -rf $DIR/$tdir || error "Can not delete directories"
1287 }
1288 run_test 24y "rename/link on the same dir should succeed"
1289
1290 test_24z() {
1291         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1292         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1293                 skip "Need MDS version at least 2.12.51"
1294
1295         local index
1296
1297         for index in 0 1; do
1298                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1299                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1300         done
1301
1302         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1303
1304         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1305         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1306
1307         local mdts=$(comma_list $(mdts_nodes))
1308
1309         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1310         stack_trap "do_nodes $mdts $LCTL \
1311                 set_param mdt.*.enable_remote_rename=1" EXIT
1312
1313         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1314
1315         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1316         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1317 }
1318 run_test 24z "cross-MDT rename is done as cp"
1319
1320 test_24A() { # LU-3182
1321         local NFILES=5000
1322
1323         rm -rf $DIR/$tdir
1324         test_mkdir $DIR/$tdir
1325         trap simple_cleanup_common EXIT
1326         createmany -m $DIR/$tdir/$tfile $NFILES
1327         local t=$(ls $DIR/$tdir | wc -l)
1328         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1329         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1330         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1331            [ $v -ne $((NFILES + 2)) ] ; then
1332                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1333         fi
1334
1335         simple_cleanup_common || error "Can not delete directories"
1336 }
1337 run_test 24A "readdir() returns correct number of entries."
1338
1339 test_24B() { # LU-4805
1340         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1341
1342         local count
1343
1344         test_mkdir $DIR/$tdir
1345         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1346                 error "create striped dir failed"
1347
1348         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1349         [ $count -eq 2 ] || error "Expected 2, got $count"
1350
1351         touch $DIR/$tdir/striped_dir/a
1352
1353         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1354         [ $count -eq 3 ] || error "Expected 3, got $count"
1355
1356         touch $DIR/$tdir/striped_dir/.f
1357
1358         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1359         [ $count -eq 4 ] || error "Expected 4, got $count"
1360
1361         rm -rf $DIR/$tdir || error "Can not delete directories"
1362 }
1363 run_test 24B "readdir for striped dir return correct number of entries"
1364
1365 test_24C() {
1366         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1367
1368         mkdir $DIR/$tdir
1369         mkdir $DIR/$tdir/d0
1370         mkdir $DIR/$tdir/d1
1371
1372         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1373                 error "create striped dir failed"
1374
1375         cd $DIR/$tdir/d0/striped_dir
1376
1377         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1378         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1379         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1380
1381         [ "$d0_ino" = "$parent_ino" ] ||
1382                 error ".. wrong, expect $d0_ino, get $parent_ino"
1383
1384         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1385                 error "mv striped dir failed"
1386
1387         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1388
1389         [ "$d1_ino" = "$parent_ino" ] ||
1390                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1391 }
1392 run_test 24C "check .. in striped dir"
1393
1394 test_24E() {
1395         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1397
1398         mkdir -p $DIR/$tdir
1399         mkdir $DIR/$tdir/src_dir
1400         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1401                 error "create remote source failed"
1402
1403         touch $DIR/$tdir/src_dir/src_child/a
1404
1405         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1406                 error "create remote target dir failed"
1407
1408         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1409                 error "create remote target child failed"
1410
1411         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1412                 error "rename dir cross MDT failed!"
1413
1414         find $DIR/$tdir
1415
1416         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1417                 error "src_child still exists after rename"
1418
1419         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1420                 error "missing file(a) after rename"
1421
1422         rm -rf $DIR/$tdir || error "Can not delete directories"
1423 }
1424 run_test 24E "cross MDT rename/link"
1425
1426 test_24F () {
1427         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1428
1429         local repeats=1000
1430         [ "$SLOW" = "no" ] && repeats=100
1431
1432         mkdir -p $DIR/$tdir
1433
1434         echo "$repeats repeats"
1435         for ((i = 0; i < repeats; i++)); do
1436                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1437                 touch $DIR/$tdir/test/a || error "touch fails"
1438                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1439                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1440         done
1441
1442         true
1443 }
1444 run_test 24F "hash order vs readdir (LU-11330)"
1445
1446 test_25a() {
1447         echo '== symlink sanity ============================================='
1448
1449         test_mkdir $DIR/d25
1450         ln -s d25 $DIR/s25
1451         touch $DIR/s25/foo ||
1452                 error "File creation in symlinked directory failed"
1453 }
1454 run_test 25a "create file in symlinked directory ==============="
1455
1456 test_25b() {
1457         [ ! -d $DIR/d25 ] && test_25a
1458         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1459 }
1460 run_test 25b "lookup file in symlinked directory ==============="
1461
1462 test_26a() {
1463         test_mkdir $DIR/d26
1464         test_mkdir $DIR/d26/d26-2
1465         ln -s d26/d26-2 $DIR/s26
1466         touch $DIR/s26/foo || error "File creation failed"
1467 }
1468 run_test 26a "multiple component symlink ======================="
1469
1470 test_26b() {
1471         test_mkdir -p $DIR/$tdir/d26-2
1472         ln -s $tdir/d26-2/foo $DIR/s26-2
1473         touch $DIR/s26-2 || error "File creation failed"
1474 }
1475 run_test 26b "multiple component symlink at end of lookup ======"
1476
1477 test_26c() {
1478         test_mkdir $DIR/d26.2
1479         touch $DIR/d26.2/foo
1480         ln -s d26.2 $DIR/s26.2-1
1481         ln -s s26.2-1 $DIR/s26.2-2
1482         ln -s s26.2-2 $DIR/s26.2-3
1483         chmod 0666 $DIR/s26.2-3/foo
1484 }
1485 run_test 26c "chain of symlinks"
1486
1487 # recursive symlinks (bug 439)
1488 test_26d() {
1489         ln -s d26-3/foo $DIR/d26-3
1490 }
1491 run_test 26d "create multiple component recursive symlink"
1492
1493 test_26e() {
1494         [ ! -h $DIR/d26-3 ] && test_26d
1495         rm $DIR/d26-3
1496 }
1497 run_test 26e "unlink multiple component recursive symlink"
1498
1499 # recursive symlinks (bug 7022)
1500 test_26f() {
1501         test_mkdir $DIR/$tdir
1502         test_mkdir $DIR/$tdir/$tfile
1503         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1504         test_mkdir -p lndir/bar1
1505         test_mkdir $DIR/$tdir/$tfile/$tfile
1506         cd $tfile                || error "cd $tfile failed"
1507         ln -s .. dotdot          || error "ln dotdot failed"
1508         ln -s dotdot/lndir lndir || error "ln lndir failed"
1509         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1510         output=`ls $tfile/$tfile/lndir/bar1`
1511         [ "$output" = bar1 ] && error "unexpected output"
1512         rm -r $tfile             || error "rm $tfile failed"
1513         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1514 }
1515 run_test 26f "rm -r of a directory which has recursive symlink"
1516
1517 test_27a() {
1518         test_mkdir $DIR/$tdir
1519         $LFS getstripe $DIR/$tdir
1520         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1521         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1522         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1523 }
1524 run_test 27a "one stripe file"
1525
1526 test_27b() {
1527         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1528
1529         test_mkdir $DIR/$tdir
1530         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1531         $LFS getstripe -c $DIR/$tdir/$tfile
1532         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1533                 error "two-stripe file doesn't have two stripes"
1534
1535         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1536 }
1537 run_test 27b "create and write to two stripe file"
1538
1539 # 27c family tests specific striping, setstripe -o
1540 test_27ca() {
1541         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1542         test_mkdir -p $DIR/$tdir
1543         local osts="1"
1544
1545         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1546         $LFS getstripe -i $DIR/$tdir/$tfile
1547         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1548                 error "stripe not on specified OST"
1549
1550         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1551 }
1552 run_test 27ca "one stripe on specified OST"
1553
1554 test_27cb() {
1555         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1556         test_mkdir -p $DIR/$tdir
1557         local osts="1,0"
1558         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1559         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1560         echo "$getstripe"
1561
1562         # Strip getstripe output to a space separated list of OSTs
1563         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1564                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1565         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1566                 error "stripes not on specified OSTs"
1567
1568         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1569 }
1570 run_test 27cb "two stripes on specified OSTs"
1571
1572 test_27cc() {
1573         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1574         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1575                 skip "server does not support overstriping"
1576
1577         test_mkdir -p $DIR/$tdir
1578         local osts="0,0"
1579         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1580         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1581         echo "$getstripe"
1582
1583         # Strip getstripe output to a space separated list of OSTs
1584         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1585                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1586         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1587                 error "stripes not on specified OSTs"
1588
1589         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1590 }
1591 run_test 27cc "two stripes on the same OST"
1592
1593 test_27cd() {
1594         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1595         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1596                 skip "server does not support overstriping"
1597         test_mkdir -p $DIR/$tdir
1598         local osts="0,1,1,0"
1599         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1600         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1601         echo "$getstripe"
1602
1603         # Strip getstripe output to a space separated list of OSTs
1604         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1605                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1606         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1607                 error "stripes not on specified OSTs"
1608
1609         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1610 }
1611 run_test 27cd "four stripes on two OSTs"
1612
1613 test_27ce() {
1614         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1615                 skip_env "too many osts, skipping"
1616         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1617                 skip "server does not support overstriping"
1618         # We do one more stripe than we have OSTs
1619         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1620                 skip_env "ea_inode feature disabled"
1621
1622         test_mkdir -p $DIR/$tdir
1623         local osts=""
1624         for i in $(seq 0 $OSTCOUNT);
1625         do
1626                 osts=$osts"0"
1627                 if [ $i -ne $OSTCOUNT ]; then
1628                         osts=$osts","
1629                 fi
1630         done
1631         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1632         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1633         echo "$getstripe"
1634
1635         # Strip getstripe output to a space separated list of OSTs
1636         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1637                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1638         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1639                 error "stripes not on specified OSTs"
1640
1641         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1642 }
1643 run_test 27ce "more stripes than OSTs with -o"
1644
1645 test_27cf() {
1646         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1647         local pid=0
1648
1649         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1650         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1651         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1652         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1653                 error "failed to set $osp_proc=0"
1654
1655         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1656         pid=$!
1657         sleep 1
1658         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1659         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1660                 error "failed to set $osp_proc=1"
1661         wait $pid
1662         [[ $pid -ne 0 ]] ||
1663                 error "should return error due to $osp_proc=0"
1664 }
1665 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1666
1667 test_27d() {
1668         test_mkdir $DIR/$tdir
1669         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1670                 error "setstripe failed"
1671         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1672         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1673 }
1674 run_test 27d "create file with default settings"
1675
1676 test_27e() {
1677         # LU-5839 adds check for existed layout before setting it
1678         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1679                 skip "Need MDS version at least 2.7.56"
1680
1681         test_mkdir $DIR/$tdir
1682         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1683         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1684         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1685 }
1686 run_test 27e "setstripe existing file (should return error)"
1687
1688 test_27f() {
1689         test_mkdir $DIR/$tdir
1690         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1691                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1692         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1693                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1694         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1695         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1696 }
1697 run_test 27f "setstripe with bad stripe size (should return error)"
1698
1699 test_27g() {
1700         test_mkdir $DIR/$tdir
1701         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1702         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1703                 error "$DIR/$tdir/$tfile has object"
1704 }
1705 run_test 27g "$LFS getstripe with no objects"
1706
1707 test_27ga() {
1708         test_mkdir $DIR/$tdir
1709         touch $DIR/$tdir/$tfile || error "touch failed"
1710         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1711         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1712         local rc=$?
1713         (( rc == 2 )) || error "getstripe did not return ENOENT"
1714 }
1715 run_test 27ga "$LFS getstripe with missing file (should return error)"
1716
1717 test_27i() {
1718         test_mkdir $DIR/$tdir
1719         touch $DIR/$tdir/$tfile || error "touch failed"
1720         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1721                 error "missing objects"
1722 }
1723 run_test 27i "$LFS getstripe with some objects"
1724
1725 test_27j() {
1726         test_mkdir $DIR/$tdir
1727         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1728                 error "setstripe failed" || true
1729 }
1730 run_test 27j "setstripe with bad stripe offset (should return error)"
1731
1732 test_27k() { # bug 2844
1733         test_mkdir $DIR/$tdir
1734         local file=$DIR/$tdir/$tfile
1735         local ll_max_blksize=$((4 * 1024 * 1024))
1736         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1737         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1738         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1739         dd if=/dev/zero of=$file bs=4k count=1
1740         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1741         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1742 }
1743 run_test 27k "limit i_blksize for broken user apps"
1744
1745 test_27l() {
1746         mcreate $DIR/$tfile || error "creating file"
1747         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1748                 error "setstripe should have failed" || true
1749 }
1750 run_test 27l "check setstripe permissions (should return error)"
1751
1752 test_27m() {
1753         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1754
1755         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1756                 skip_env "multiple clients -- skipping"
1757
1758         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1759                    head -n1)
1760         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1761                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1762         fi
1763         trap simple_cleanup_common EXIT
1764         test_mkdir $DIR/$tdir
1765         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1766         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1767                 error "dd should fill OST0"
1768         i=2
1769         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1770                 i=$((i + 1))
1771                 [ $i -gt 256 ] && break
1772         done
1773         i=$((i + 1))
1774         touch $DIR/$tdir/$tfile.$i
1775         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1776             awk '{print $1}'| grep -w "0") ] &&
1777                 error "OST0 was full but new created file still use it"
1778         i=$((i + 1))
1779         touch $DIR/$tdir/$tfile.$i
1780         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1781             awk '{print $1}'| grep -w "0") ] &&
1782                 error "OST0 was full but new created file still use it"
1783         simple_cleanup_common
1784 }
1785 run_test 27m "create file while OST0 was full"
1786
1787 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1788 # if the OST isn't full anymore.
1789 reset_enospc() {
1790         local ostidx=${1:-""}
1791         local delay
1792         local ready
1793         local get_prealloc
1794
1795         local list=$(comma_list $(osts_nodes))
1796         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1797
1798         do_nodes $list lctl set_param fail_loc=0
1799         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1800         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1801                 awk '{print $1 * 2;exit;}')
1802         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1803                         grep -v \"^0$\""
1804         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1805 }
1806
1807 __exhaust_precreations() {
1808         local OSTIDX=$1
1809         local FAILLOC=$2
1810         local FAILIDX=${3:-$OSTIDX}
1811         local ofacet=ost$((OSTIDX + 1))
1812
1813         test_mkdir -p -c1 $DIR/$tdir
1814         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1815         local mfacet=mds$((mdtidx + 1))
1816         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1817
1818         local OST=$(ostname_from_index $OSTIDX)
1819
1820         # on the mdt's osc
1821         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1822         local last_id=$(do_facet $mfacet lctl get_param -n \
1823                         osp.$mdtosc_proc1.prealloc_last_id)
1824         local next_id=$(do_facet $mfacet lctl get_param -n \
1825                         osp.$mdtosc_proc1.prealloc_next_id)
1826
1827         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1828         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1829
1830         test_mkdir -p $DIR/$tdir/${OST}
1831         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1832 #define OBD_FAIL_OST_ENOSPC              0x215
1833         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1834         echo "Creating to objid $last_id on ost $OST..."
1835         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1836         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1837         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1838 }
1839
1840 exhaust_precreations() {
1841         __exhaust_precreations $1 $2 $3
1842         sleep_maxage
1843 }
1844
1845 exhaust_all_precreations() {
1846         local i
1847         for (( i=0; i < OSTCOUNT; i++ )) ; do
1848                 __exhaust_precreations $i $1 -1
1849         done
1850         sleep_maxage
1851 }
1852
1853 test_27n() {
1854         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1856         remote_mds_nodsh && skip "remote MDS with nodsh"
1857         remote_ost_nodsh && skip "remote OST with nodsh"
1858
1859         reset_enospc
1860         rm -f $DIR/$tdir/$tfile
1861         exhaust_precreations 0 0x80000215
1862         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1863         touch $DIR/$tdir/$tfile || error "touch failed"
1864         $LFS getstripe $DIR/$tdir/$tfile
1865         reset_enospc
1866 }
1867 run_test 27n "create file with some full OSTs"
1868
1869 test_27o() {
1870         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1872         remote_mds_nodsh && skip "remote MDS with nodsh"
1873         remote_ost_nodsh && skip "remote OST with nodsh"
1874
1875         reset_enospc
1876         rm -f $DIR/$tdir/$tfile
1877         exhaust_all_precreations 0x215
1878
1879         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1880
1881         reset_enospc
1882         rm -rf $DIR/$tdir/*
1883 }
1884 run_test 27o "create file with all full OSTs (should error)"
1885
1886 test_27p() {
1887         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1889         remote_mds_nodsh && skip "remote MDS with nodsh"
1890         remote_ost_nodsh && skip "remote OST with nodsh"
1891
1892         reset_enospc
1893         rm -f $DIR/$tdir/$tfile
1894         test_mkdir $DIR/$tdir
1895
1896         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1897         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1898         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1899
1900         exhaust_precreations 0 0x80000215
1901         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1902         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1903         $LFS getstripe $DIR/$tdir/$tfile
1904
1905         reset_enospc
1906 }
1907 run_test 27p "append to a truncated file with some full OSTs"
1908
1909 test_27q() {
1910         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1912         remote_mds_nodsh && skip "remote MDS with nodsh"
1913         remote_ost_nodsh && skip "remote OST with nodsh"
1914
1915         reset_enospc
1916         rm -f $DIR/$tdir/$tfile
1917
1918         test_mkdir $DIR/$tdir
1919         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1920         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1921                 error "truncate $DIR/$tdir/$tfile failed"
1922         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1923
1924         exhaust_all_precreations 0x215
1925
1926         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1927         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1928
1929         reset_enospc
1930 }
1931 run_test 27q "append to truncated file with all OSTs full (should error)"
1932
1933 test_27r() {
1934         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1936         remote_mds_nodsh && skip "remote MDS with nodsh"
1937         remote_ost_nodsh && skip "remote OST with nodsh"
1938
1939         reset_enospc
1940         rm -f $DIR/$tdir/$tfile
1941         exhaust_precreations 0 0x80000215
1942
1943         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1944
1945         reset_enospc
1946 }
1947 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1948
1949 test_27s() { # bug 10725
1950         test_mkdir $DIR/$tdir
1951         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1952         local stripe_count=0
1953         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1954         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1955                 error "stripe width >= 2^32 succeeded" || true
1956
1957 }
1958 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1959
1960 test_27t() { # bug 10864
1961         WDIR=$(pwd)
1962         WLFS=$(which lfs)
1963         cd $DIR
1964         touch $tfile
1965         $WLFS getstripe $tfile
1966         cd $WDIR
1967 }
1968 run_test 27t "check that utils parse path correctly"
1969
1970 test_27u() { # bug 4900
1971         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1972         remote_mds_nodsh && skip "remote MDS with nodsh"
1973
1974         local index
1975         local list=$(comma_list $(mdts_nodes))
1976
1977 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1978         do_nodes $list $LCTL set_param fail_loc=0x139
1979         test_mkdir -p $DIR/$tdir
1980         trap simple_cleanup_common EXIT
1981         createmany -o $DIR/$tdir/t- 1000
1982         do_nodes $list $LCTL set_param fail_loc=0
1983
1984         TLOG=$TMP/$tfile.getstripe
1985         $LFS getstripe $DIR/$tdir > $TLOG
1986         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1987         unlinkmany $DIR/$tdir/t- 1000
1988         trap 0
1989         [[ $OBJS -gt 0 ]] &&
1990                 error "$OBJS objects created on OST-0. See $TLOG" ||
1991                 rm -f $TLOG
1992 }
1993 run_test 27u "skip object creation on OSC w/o objects"
1994
1995 test_27v() { # bug 4900
1996         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1998         remote_mds_nodsh && skip "remote MDS with nodsh"
1999         remote_ost_nodsh && skip "remote OST with nodsh"
2000
2001         exhaust_all_precreations 0x215
2002         reset_enospc
2003
2004         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2005
2006         touch $DIR/$tdir/$tfile
2007         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2008         # all except ost1
2009         for (( i=1; i < OSTCOUNT; i++ )); do
2010                 do_facet ost$i lctl set_param fail_loc=0x705
2011         done
2012         local START=`date +%s`
2013         createmany -o $DIR/$tdir/$tfile 32
2014
2015         local FINISH=`date +%s`
2016         local TIMEOUT=`lctl get_param -n timeout`
2017         local PROCESS=$((FINISH - START))
2018         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2019                error "$FINISH - $START >= $TIMEOUT / 2"
2020         sleep $((TIMEOUT / 2 - PROCESS))
2021         reset_enospc
2022 }
2023 run_test 27v "skip object creation on slow OST"
2024
2025 test_27w() { # bug 10997
2026         test_mkdir $DIR/$tdir
2027         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2028         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2029                 error "stripe size $size != 65536" || true
2030         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2031                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2032 }
2033 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2034
2035 test_27wa() {
2036         [[ $OSTCOUNT -lt 2 ]] &&
2037                 skip_env "skipping multiple stripe count/offset test"
2038
2039         test_mkdir $DIR/$tdir
2040         for i in $(seq 1 $OSTCOUNT); do
2041                 offset=$((i - 1))
2042                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2043                         error "setstripe -c $i -i $offset failed"
2044                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2045                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2046                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2047                 [ $index -ne $offset ] &&
2048                         error "stripe offset $index != $offset" || true
2049         done
2050 }
2051 run_test 27wa "check $LFS setstripe -c -i options"
2052
2053 test_27x() {
2054         remote_ost_nodsh && skip "remote OST with nodsh"
2055         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2057
2058         OFFSET=$(($OSTCOUNT - 1))
2059         OSTIDX=0
2060         local OST=$(ostname_from_index $OSTIDX)
2061
2062         test_mkdir $DIR/$tdir
2063         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2064         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2065         sleep_maxage
2066         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2067         for i in $(seq 0 $OFFSET); do
2068                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2069                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2070                 error "OST0 was degraded but new created file still use it"
2071         done
2072         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2073 }
2074 run_test 27x "create files while OST0 is degraded"
2075
2076 test_27y() {
2077         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2078         remote_mds_nodsh && skip "remote MDS with nodsh"
2079         remote_ost_nodsh && skip "remote OST with nodsh"
2080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2081
2082         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2083         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2084                 osp.$mdtosc.prealloc_last_id)
2085         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2086                 osp.$mdtosc.prealloc_next_id)
2087         local fcount=$((last_id - next_id))
2088         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2089         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2090
2091         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2092                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2093         local OST_DEACTIVE_IDX=-1
2094         local OSC
2095         local OSTIDX
2096         local OST
2097
2098         for OSC in $MDS_OSCS; do
2099                 OST=$(osc_to_ost $OSC)
2100                 OSTIDX=$(index_from_ostuuid $OST)
2101                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2102                         OST_DEACTIVE_IDX=$OSTIDX
2103                 fi
2104                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2105                         echo $OSC "is Deactivated:"
2106                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2107                 fi
2108         done
2109
2110         OSTIDX=$(index_from_ostuuid $OST)
2111         test_mkdir $DIR/$tdir
2112         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2113
2114         for OSC in $MDS_OSCS; do
2115                 OST=$(osc_to_ost $OSC)
2116                 OSTIDX=$(index_from_ostuuid $OST)
2117                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2118                         echo $OST "is degraded:"
2119                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2120                                                 obdfilter.$OST.degraded=1
2121                 fi
2122         done
2123
2124         sleep_maxage
2125         createmany -o $DIR/$tdir/$tfile $fcount
2126
2127         for OSC in $MDS_OSCS; do
2128                 OST=$(osc_to_ost $OSC)
2129                 OSTIDX=$(index_from_ostuuid $OST)
2130                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2131                         echo $OST "is recovered from degraded:"
2132                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2133                                                 obdfilter.$OST.degraded=0
2134                 else
2135                         do_facet $SINGLEMDS lctl --device %$OSC activate
2136                 fi
2137         done
2138
2139         # all osp devices get activated, hence -1 stripe count restored
2140         local stripe_count=0
2141
2142         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2143         # devices get activated.
2144         sleep_maxage
2145         $LFS setstripe -c -1 $DIR/$tfile
2146         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2147         rm -f $DIR/$tfile
2148         [ $stripe_count -ne $OSTCOUNT ] &&
2149                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2150         return 0
2151 }
2152 run_test 27y "create files while OST0 is degraded and the rest inactive"
2153
2154 check_seq_oid()
2155 {
2156         log "check file $1"
2157
2158         lmm_count=$($LFS getstripe -c $1)
2159         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2160         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2161
2162         local old_ifs="$IFS"
2163         IFS=$'[:]'
2164         fid=($($LFS path2fid $1))
2165         IFS="$old_ifs"
2166
2167         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2168         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2169
2170         # compare lmm_seq and lu_fid->f_seq
2171         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2172         # compare lmm_object_id and lu_fid->oid
2173         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2174
2175         # check the trusted.fid attribute of the OST objects of the file
2176         local have_obdidx=false
2177         local stripe_nr=0
2178         $LFS getstripe $1 | while read obdidx oid hex seq; do
2179                 # skip lines up to and including "obdidx"
2180                 [ -z "$obdidx" ] && break
2181                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2182                 $have_obdidx || continue
2183
2184                 local ost=$((obdidx + 1))
2185                 local dev=$(ostdevname $ost)
2186                 local oid_hex
2187
2188                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2189
2190                 seq=$(echo $seq | sed -e "s/^0x//g")
2191                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2192                         oid_hex=$(echo $oid)
2193                 else
2194                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2195                 fi
2196                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2197
2198                 local ff=""
2199                 #
2200                 # Don't unmount/remount the OSTs if we don't need to do that.
2201                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2202                 # update too, until that use mount/ll_decode_filter_fid/mount.
2203                 # Re-enable when debugfs will understand new filter_fid.
2204                 #
2205                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2206                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2207                                 $dev 2>/dev/null" | grep "parent=")
2208                 fi
2209                 if [ -z "$ff" ]; then
2210                         stop ost$ost
2211                         mount_fstype ost$ost
2212                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2213                                 $(facet_mntpt ost$ost)/$obj_file)
2214                         unmount_fstype ost$ost
2215                         start ost$ost $dev $OST_MOUNT_OPTS
2216                         clients_up
2217                 fi
2218
2219                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2220
2221                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2222
2223                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2224                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2225                 #
2226                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2227                 #       stripe_size=1048576 component_id=1 component_start=0 \
2228                 #       component_end=33554432
2229                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2230                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2231                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2232                 local ff_pstripe
2233                 if grep -q 'stripe=' <<<$ff; then
2234                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2235                 else
2236                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2237                         # into f_ver in this case.  See comment on ff_parent.
2238                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2239                 fi
2240
2241                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2242                 [ $ff_pseq = $lmm_seq ] ||
2243                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2244                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2245                 [ $ff_poid = $lmm_oid ] ||
2246                         error "FF parent OID $ff_poid != $lmm_oid"
2247                 (($ff_pstripe == $stripe_nr)) ||
2248                         error "FF stripe $ff_pstripe != $stripe_nr"
2249
2250                 stripe_nr=$((stripe_nr + 1))
2251                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2252                         continue
2253                 if grep -q 'stripe_count=' <<<$ff; then
2254                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2255                                             -e 's/ .*//' <<<$ff)
2256                         [ $lmm_count = $ff_scnt ] ||
2257                                 error "FF stripe count $lmm_count != $ff_scnt"
2258                 fi
2259         done
2260 }
2261
2262 test_27z() {
2263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2264         remote_ost_nodsh && skip "remote OST with nodsh"
2265
2266         test_mkdir $DIR/$tdir
2267         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2268                 { error "setstripe -c -1 failed"; return 1; }
2269         # We need to send a write to every object to get parent FID info set.
2270         # This _should_ also work for setattr, but does not currently.
2271         # touch $DIR/$tdir/$tfile-1 ||
2272         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2273                 { error "dd $tfile-1 failed"; return 2; }
2274         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2275                 { error "setstripe -c -1 failed"; return 3; }
2276         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2277                 { error "dd $tfile-2 failed"; return 4; }
2278
2279         # make sure write RPCs have been sent to OSTs
2280         sync; sleep 5; sync
2281
2282         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2283         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2284 }
2285 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2286
2287 test_27A() { # b=19102
2288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2289
2290         save_layout_restore_at_exit $MOUNT
2291         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2292         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2293                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2294         local default_size=$($LFS getstripe -S $MOUNT)
2295         local default_offset=$($LFS getstripe -i $MOUNT)
2296         local dsize=$(do_facet $SINGLEMDS \
2297                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2298         [ $default_size -eq $dsize ] ||
2299                 error "stripe size $default_size != $dsize"
2300         [ $default_offset -eq -1 ] ||
2301                 error "stripe offset $default_offset != -1"
2302 }
2303 run_test 27A "check filesystem-wide default LOV EA values"
2304
2305 test_27B() { # LU-2523
2306         test_mkdir $DIR/$tdir
2307         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2308         touch $DIR/$tdir/f0
2309         # open f1 with O_LOV_DELAY_CREATE
2310         # rename f0 onto f1
2311         # call setstripe ioctl on open file descriptor for f1
2312         # close
2313         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2314                 $DIR/$tdir/f0
2315
2316         rm -f $DIR/$tdir/f1
2317         # open f1 with O_LOV_DELAY_CREATE
2318         # unlink f1
2319         # call setstripe ioctl on open file descriptor for f1
2320         # close
2321         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2322
2323         # Allow multiop to fail in imitation of NFS's busted semantics.
2324         true
2325 }
2326 run_test 27B "call setstripe on open unlinked file/rename victim"
2327
2328 # 27C family tests full striping and overstriping
2329 test_27Ca() { #LU-2871
2330         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2331
2332         declare -a ost_idx
2333         local index
2334         local found
2335         local i
2336         local j
2337
2338         test_mkdir $DIR/$tdir
2339         cd $DIR/$tdir
2340         for i in $(seq 0 $((OSTCOUNT - 1))); do
2341                 # set stripe across all OSTs starting from OST$i
2342                 $LFS setstripe -i $i -c -1 $tfile$i
2343                 # get striping information
2344                 ost_idx=($($LFS getstripe $tfile$i |
2345                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2346                 echo ${ost_idx[@]}
2347
2348                 # check the layout
2349                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2350                         error "${#ost_idx[@]} != $OSTCOUNT"
2351
2352                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2353                         found=0
2354                         for j in $(echo ${ost_idx[@]}); do
2355                                 if [ $index -eq $j ]; then
2356                                         found=1
2357                                         break
2358                                 fi
2359                         done
2360                         [ $found = 1 ] ||
2361                                 error "Can not find $index in ${ost_idx[@]}"
2362                 done
2363         done
2364 }
2365 run_test 27Ca "check full striping across all OSTs"
2366
2367 test_27Cb() {
2368         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2369                 skip "server does not support overstriping"
2370         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2371                 skip_env "too many osts, skipping"
2372
2373         test_mkdir -p $DIR/$tdir
2374         local setcount=$(($OSTCOUNT * 2))
2375         [ $setcount -ge 160 ] || large_xattr_enabled ||
2376                 skip_env "ea_inode feature disabled"
2377
2378         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2379                 error "setstripe failed"
2380
2381         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2382         [ $count -eq $setcount ] ||
2383                 error "stripe count $count, should be $setcount"
2384
2385         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2386                 error "overstriped should be set in pattern"
2387
2388         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2389                 error "dd failed"
2390 }
2391 run_test 27Cb "more stripes than OSTs with -C"
2392
2393 test_27Cc() {
2394         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2395                 skip "server does not support overstriping"
2396         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2397
2398         test_mkdir -p $DIR/$tdir
2399         local setcount=$(($OSTCOUNT - 1))
2400
2401         [ $setcount -ge 160 ] || large_xattr_enabled ||
2402                 skip_env "ea_inode feature disabled"
2403
2404         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2405                 error "setstripe failed"
2406
2407         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2408         [ $count -eq $setcount ] ||
2409                 error "stripe count $count, should be $setcount"
2410
2411         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2412                 error "overstriped should not be set in pattern"
2413
2414         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2415                 error "dd failed"
2416 }
2417 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2418
2419 test_27Cd() {
2420         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2421                 skip "server does not support overstriping"
2422         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2423         large_xattr_enabled || skip_env "ea_inode feature disabled"
2424
2425         test_mkdir -p $DIR/$tdir
2426         local setcount=$LOV_MAX_STRIPE_COUNT
2427
2428         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2429                 error "setstripe failed"
2430
2431         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2432         [ $count -eq $setcount ] ||
2433                 error "stripe count $count, should be $setcount"
2434
2435         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2436                 error "overstriped should be set in pattern"
2437
2438         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2439                 error "dd failed"
2440
2441         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2442 }
2443 run_test 27Cd "test maximum stripe count"
2444
2445 test_27Ce() {
2446         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2447                 skip "server does not support overstriping"
2448         test_mkdir -p $DIR/$tdir
2449
2450         pool_add $TESTNAME || error "Pool creation failed"
2451         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2452
2453         local setcount=8
2454
2455         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2456                 error "setstripe failed"
2457
2458         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2459         [ $count -eq $setcount ] ||
2460                 error "stripe count $count, should be $setcount"
2461
2462         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2463                 error "overstriped should be set in pattern"
2464
2465         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2466                 error "dd failed"
2467
2468         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2469 }
2470 run_test 27Ce "test pool with overstriping"
2471
2472 test_27Cf() {
2473         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2474                 skip "server does not support overstriping"
2475         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2476                 skip_env "too many osts, skipping"
2477
2478         test_mkdir -p $DIR/$tdir
2479
2480         local setcount=$(($OSTCOUNT * 2))
2481         [ $setcount -ge 160 ] || large_xattr_enabled ||
2482                 skip_env "ea_inode feature disabled"
2483
2484         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2485                 error "setstripe failed"
2486
2487         echo 1 > $DIR/$tdir/$tfile
2488
2489         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2490         [ $count -eq $setcount ] ||
2491                 error "stripe count $count, should be $setcount"
2492
2493         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2494                 error "overstriped should be set in pattern"
2495
2496         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2497                 error "dd failed"
2498
2499         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2500 }
2501 run_test 27Cf "test default inheritance with overstriping"
2502
2503 test_27D() {
2504         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2505         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2506         remote_mds_nodsh && skip "remote MDS with nodsh"
2507
2508         local POOL=${POOL:-testpool}
2509         local first_ost=0
2510         local last_ost=$(($OSTCOUNT - 1))
2511         local ost_step=1
2512         local ost_list=$(seq $first_ost $ost_step $last_ost)
2513         local ost_range="$first_ost $last_ost $ost_step"
2514
2515         test_mkdir $DIR/$tdir
2516         pool_add $POOL || error "pool_add failed"
2517         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2518
2519         local skip27D
2520         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2521                 skip27D+="-s 29"
2522         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2523                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2524                         skip27D+=" -s 30,31"
2525         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2526           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2527                 skip27D+=" -s 32,33"
2528         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2529                 skip27D+=" -s 34"
2530         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2531                 error "llapi_layout_test failed"
2532
2533         destroy_test_pools || error "destroy test pools failed"
2534 }
2535 run_test 27D "validate llapi_layout API"
2536
2537 # Verify that default_easize is increased from its initial value after
2538 # accessing a widely striped file.
2539 test_27E() {
2540         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2541         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2542                 skip "client does not have LU-3338 fix"
2543
2544         # 72 bytes is the minimum space required to store striping
2545         # information for a file striped across one OST:
2546         # (sizeof(struct lov_user_md_v3) +
2547         #  sizeof(struct lov_user_ost_data_v1))
2548         local min_easize=72
2549         $LCTL set_param -n llite.*.default_easize $min_easize ||
2550                 error "lctl set_param failed"
2551         local easize=$($LCTL get_param -n llite.*.default_easize)
2552
2553         [ $easize -eq $min_easize ] ||
2554                 error "failed to set default_easize"
2555
2556         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2557                 error "setstripe failed"
2558         # In order to ensure stat() call actually talks to MDS we need to
2559         # do something drastic to this file to shake off all lock, e.g.
2560         # rename it (kills lookup lock forcing cache cleaning)
2561         mv $DIR/$tfile $DIR/${tfile}-1
2562         ls -l $DIR/${tfile}-1
2563         rm $DIR/${tfile}-1
2564
2565         easize=$($LCTL get_param -n llite.*.default_easize)
2566
2567         [ $easize -gt $min_easize ] ||
2568                 error "default_easize not updated"
2569 }
2570 run_test 27E "check that default extended attribute size properly increases"
2571
2572 test_27F() { # LU-5346/LU-7975
2573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2574         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2575         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2576                 skip "Need MDS version at least 2.8.51"
2577         remote_ost_nodsh && skip "remote OST with nodsh"
2578
2579         test_mkdir $DIR/$tdir
2580         rm -f $DIR/$tdir/f0
2581         $LFS setstripe -c 2 $DIR/$tdir
2582
2583         # stop all OSTs to reproduce situation for LU-7975 ticket
2584         for num in $(seq $OSTCOUNT); do
2585                 stop ost$num
2586         done
2587
2588         # open/create f0 with O_LOV_DELAY_CREATE
2589         # truncate f0 to a non-0 size
2590         # close
2591         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2592
2593         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2594         # open/write it again to force delayed layout creation
2595         cat /etc/hosts > $DIR/$tdir/f0 &
2596         catpid=$!
2597
2598         # restart OSTs
2599         for num in $(seq $OSTCOUNT); do
2600                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2601                         error "ost$num failed to start"
2602         done
2603
2604         wait $catpid || error "cat failed"
2605
2606         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2607         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2608                 error "wrong stripecount"
2609
2610 }
2611 run_test 27F "Client resend delayed layout creation with non-zero size"
2612
2613 test_27G() { #LU-10629
2614         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2615                 skip "Need MDS version at least 2.11.51"
2616         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2617         remote_mds_nodsh && skip "remote MDS with nodsh"
2618         local POOL=${POOL:-testpool}
2619         local ostrange="0 0 1"
2620
2621         test_mkdir $DIR/$tdir
2622         touch $DIR/$tdir/$tfile.nopool
2623         pool_add $POOL || error "pool_add failed"
2624         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2625         $LFS setstripe -p $POOL $DIR/$tdir
2626
2627         local pool=$($LFS getstripe -p $DIR/$tdir)
2628
2629         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2630         touch $DIR/$tdir/$tfile.default
2631         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2632         $LFS find $DIR/$tdir -type f --pool $POOL
2633         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2634         [[ "$found" == "2" ]] ||
2635                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2636
2637         $LFS setstripe -d $DIR/$tdir
2638
2639         pool=$($LFS getstripe -p -d $DIR/$tdir)
2640
2641         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2642 }
2643 run_test 27G "Clear OST pool from stripe"
2644
2645 test_27H() {
2646         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2647                 skip "Need MDS version newer than 2.11.54"
2648         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2649         test_mkdir $DIR/$tdir
2650         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2651         touch $DIR/$tdir/$tfile
2652         $LFS getstripe -c $DIR/$tdir/$tfile
2653         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2654                 error "two-stripe file doesn't have two stripes"
2655
2656         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2657         $LFS getstripe -y $DIR/$tdir/$tfile
2658         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2659              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2660                 error "expected l_ost_idx: [02]$ not matched"
2661
2662         # make sure ost list has been cleared
2663         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2664         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2665                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2666         touch $DIR/$tdir/f3
2667         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2668 }
2669 run_test 27H "Set specific OSTs stripe"
2670
2671 test_27I() {
2672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2673         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2674         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2675                 skip "Need MDS version newer than 2.12.52"
2676         local pool=$TESTNAME
2677         local ostrange="1 1 1"
2678
2679         save_layout_restore_at_exit $MOUNT
2680         $LFS setstripe -c 2 -i 0 $MOUNT
2681         pool_add $pool || error "pool_add failed"
2682         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2683         test_mkdir $DIR/$tdir
2684         $LFS setstripe -p $pool $DIR/$tdir
2685         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2686         $LFS getstripe $DIR/$tdir/$tfile
2687 }
2688 run_test 27I "check that root dir striping does not break parent dir one"
2689
2690 test_27J() {
2691         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2692                 skip "Need MDS version newer than 2.12.51"
2693
2694         test_mkdir $DIR/$tdir
2695         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2696         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2697
2698         # create foreign file (raw way)
2699         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2700                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2701
2702         # verify foreign file (raw way)
2703         parse_foreign_file -f $DIR/$tdir/$tfile |
2704                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2705                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2706         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2707                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2708         parse_foreign_file -f $DIR/$tdir/$tfile |
2709                 grep "lov_foreign_size: 73" ||
2710                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2711         parse_foreign_file -f $DIR/$tdir/$tfile |
2712                 grep "lov_foreign_type: 1" ||
2713                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2714         parse_foreign_file -f $DIR/$tdir/$tfile |
2715                 grep "lov_foreign_flags: 0x0000DA08" ||
2716                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2717         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2718                 grep "lov_foreign_value: 0x" |
2719                 sed -e 's/lov_foreign_value: 0x//')
2720         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2721         [[ $lov = ${lov2// /} ]] ||
2722                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2723
2724         # create foreign file (lfs + API)
2725         $LFS setstripe --foreign=daos --flags 0xda08 \
2726                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2727                 error "$DIR/$tdir/${tfile}2: create failed"
2728
2729         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2730                 grep "lfm_magic:.*0x0BD70BD0" ||
2731                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2732         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2733         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2734                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2735         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2736                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2737         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2738                 grep "lfm_flags:.*0x0000DA08" ||
2739                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2740         $LFS getstripe $DIR/$tdir/${tfile}2 |
2741                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2742                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2743
2744         # modify striping should fail
2745         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2746                 error "$DIR/$tdir/$tfile: setstripe should fail"
2747         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2748                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2749
2750         # R/W should fail
2751         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2752         cat $DIR/$tdir/${tfile}2 &&
2753                 error "$DIR/$tdir/${tfile}2: read should fail"
2754         cat /etc/passwd > $DIR/$tdir/$tfile &&
2755                 error "$DIR/$tdir/$tfile: write should fail"
2756         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2757                 error "$DIR/$tdir/${tfile}2: write should fail"
2758
2759         # chmod should work
2760         chmod 222 $DIR/$tdir/$tfile ||
2761                 error "$DIR/$tdir/$tfile: chmod failed"
2762         chmod 222 $DIR/$tdir/${tfile}2 ||
2763                 error "$DIR/$tdir/${tfile}2: chmod failed"
2764
2765         # chown should work
2766         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2767                 error "$DIR/$tdir/$tfile: chown failed"
2768         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2769                 error "$DIR/$tdir/${tfile}2: chown failed"
2770
2771         # rename should work
2772         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2773                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2774         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2775                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2776
2777         #remove foreign file
2778         rm $DIR/$tdir/${tfile}.new ||
2779                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2780         rm $DIR/$tdir/${tfile}2.new ||
2781                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2782 }
2783 run_test 27J "basic ops on file with foreign LOV"
2784
2785 test_27K() {
2786         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2787                 skip "Need MDS version newer than 2.12.49"
2788
2789         test_mkdir $DIR/$tdir
2790         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2791         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2792
2793         # create foreign dir (raw way)
2794         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2795                 error "create_foreign_dir FAILED"
2796
2797         # verify foreign dir (raw way)
2798         parse_foreign_dir -d $DIR/$tdir/$tdir |
2799                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2800                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2801         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2802                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2803         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2804                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2805         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2806                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2807         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2808                 grep "lmv_foreign_value: 0x" |
2809                 sed 's/lmv_foreign_value: 0x//')
2810         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2811                 sed 's/ //g')
2812         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2813
2814         # create foreign dir (lfs + API)
2815         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2816                 $DIR/$tdir/${tdir}2 ||
2817                 error "$DIR/$tdir/${tdir}2: create failed"
2818
2819         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2820                 grep "lfm_magic:.*0x0CD50CD0" ||
2821                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2822         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2823         # - sizeof(lfm_type) - sizeof(lfm_flags)
2824         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2825                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2826         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2827                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2828         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2829                 grep "lfm_flags:.*0x0000DA05" ||
2830                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2831         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2832                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2833                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2834
2835         # file create in dir should fail
2836         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2837         touch $DIR/$tdir/${tdir}2/$tfile &&
2838                 "$DIR/${tdir}2: file create should fail"
2839
2840         # chmod should work
2841         chmod 777 $DIR/$tdir/$tdir ||
2842                 error "$DIR/$tdir: chmod failed"
2843         chmod 777 $DIR/$tdir/${tdir}2 ||
2844                 error "$DIR/${tdir}2: chmod failed"
2845
2846         # chown should work
2847         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2848                 error "$DIR/$tdir: chown failed"
2849         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2850                 error "$DIR/${tdir}2: chown failed"
2851
2852         # rename should work
2853         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2854                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2855         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2856                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2857
2858         #remove foreign dir
2859         rmdir $DIR/$tdir/${tdir}.new ||
2860                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2861         rmdir $DIR/$tdir/${tdir}2.new ||
2862                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2863 }
2864 run_test 27K "basic ops on dir with foreign LMV"
2865
2866 test_27L() {
2867         remote_mds_nodsh && skip "remote MDS with nodsh"
2868
2869         local POOL=${POOL:-$TESTNAME}
2870
2871         pool_add $POOL || error "pool_add failed"
2872
2873         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2874                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2875                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2876 }
2877 run_test 27L "lfs pool_list gives correct pool name"
2878
2879 test_27M() {
2880         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2881                 skip "Need MDS version >= than 2.12.57"
2882         remote_mds_nodsh && skip "remote MDS with nodsh"
2883         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2884
2885         test_mkdir $DIR/$tdir
2886
2887         # Set default striping on directory
2888         $LFS setstripe -C 4 $DIR/$tdir
2889
2890         echo 1 > $DIR/$tdir/${tfile}.1
2891         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2892         local setcount=4
2893         [ $count -eq $setcount ] ||
2894                 error "(1) stripe count $count, should be $setcount"
2895
2896         # Capture existing append_stripe_count setting for restore
2897         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2898         local mdts=$(comma_list $(mdts_nodes))
2899         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2900
2901         local appendcount=$orig_count
2902         echo 1 >> $DIR/$tdir/${tfile}.2_append
2903         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2904         [ $count -eq $appendcount ] ||
2905                 error "(2)stripe count $count, should be $appendcount for append"
2906
2907         # Disable O_APPEND striping, verify it works
2908         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2909
2910         # Should now get the default striping, which is 4
2911         setcount=4
2912         echo 1 >> $DIR/$tdir/${tfile}.3_append
2913         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2914         [ $count -eq $setcount ] ||
2915                 error "(3) stripe count $count, should be $setcount"
2916
2917         # Try changing the stripe count for append files
2918         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2919
2920         # Append striping is now 2 (directory default is still 4)
2921         appendcount=2
2922         echo 1 >> $DIR/$tdir/${tfile}.4_append
2923         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2924         [ $count -eq $appendcount ] ||
2925                 error "(4) stripe count $count, should be $appendcount for append"
2926
2927         # Test append stripe count of -1
2928         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2929         appendcount=$OSTCOUNT
2930         echo 1 >> $DIR/$tdir/${tfile}.5
2931         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2932         [ $count -eq $appendcount ] ||
2933                 error "(5) stripe count $count, should be $appendcount for append"
2934
2935         # Set append striping back to default of 1
2936         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2937
2938         # Try a new default striping, PFL + DOM
2939         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2940
2941         # Create normal DOM file, DOM returns stripe count == 0
2942         setcount=0
2943         touch $DIR/$tdir/${tfile}.6
2944         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2945         [ $count -eq $setcount ] ||
2946                 error "(6) stripe count $count, should be $setcount"
2947
2948         # Show
2949         appendcount=1
2950         echo 1 >> $DIR/$tdir/${tfile}.7_append
2951         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2952         [ $count -eq $appendcount ] ||
2953                 error "(7) stripe count $count, should be $appendcount for append"
2954
2955         # Clean up DOM layout
2956         $LFS setstripe -d $DIR/$tdir
2957
2958         # Now test that append striping works when layout is from root
2959         $LFS setstripe -c 2 $MOUNT
2960         # Make a special directory for this
2961         mkdir $DIR/${tdir}/${tdir}.2
2962         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2963
2964         # Verify for normal file
2965         setcount=2
2966         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2967         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2968         [ $count -eq $setcount ] ||
2969                 error "(8) stripe count $count, should be $setcount"
2970
2971         appendcount=1
2972         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2973         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2974         [ $count -eq $appendcount ] ||
2975                 error "(9) stripe count $count, should be $appendcount for append"
2976
2977         # Now test O_APPEND striping with pools
2978         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2979         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2980
2981         # Create the pool
2982         pool_add $TESTNAME || error "pool creation failed"
2983         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2984
2985         echo 1 >> $DIR/$tdir/${tfile}.10_append
2986
2987         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2988         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2989
2990         # Check that count is still correct
2991         appendcount=1
2992         echo 1 >> $DIR/$tdir/${tfile}.11_append
2993         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2994         [ $count -eq $appendcount ] ||
2995                 error "(11) stripe count $count, should be $appendcount for append"
2996
2997         # Disable O_APPEND stripe count, verify pool works separately
2998         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2999
3000         echo 1 >> $DIR/$tdir/${tfile}.12_append
3001
3002         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3003         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3004
3005         # Remove pool setting, verify it's not applied
3006         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3007
3008         echo 1 >> $DIR/$tdir/${tfile}.13_append
3009
3010         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3011         [ "$pool" = "" ] || error "(13) pool found: $pool"
3012 }
3013 run_test 27M "test O_APPEND striping"
3014
3015 test_27N() {
3016         combined_mgs_mds && skip "needs separate MGS/MDT"
3017
3018         pool_add $TESTNAME || error "pool_add failed"
3019         do_facet mgs "$LCTL pool_list $FSNAME" |
3020                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3021                 error "lctl pool_list on MGS failed"
3022 }
3023 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3024
3025 # createtest also checks that device nodes are created and
3026 # then visible correctly (#2091)
3027 test_28() { # bug 2091
3028         test_mkdir $DIR/d28
3029         $CREATETEST $DIR/d28/ct || error "createtest failed"
3030 }
3031 run_test 28 "create/mknod/mkdir with bad file types ============"
3032
3033 test_29() {
3034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3035
3036         sync; sleep 1; sync # flush out any dirty pages from previous tests
3037         cancel_lru_locks
3038         test_mkdir $DIR/d29
3039         touch $DIR/d29/foo
3040         log 'first d29'
3041         ls -l $DIR/d29
3042
3043         declare -i LOCKCOUNTORIG=0
3044         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3045                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3046         done
3047         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3048
3049         declare -i LOCKUNUSEDCOUNTORIG=0
3050         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3051                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3052         done
3053
3054         log 'second d29'
3055         ls -l $DIR/d29
3056         log 'done'
3057
3058         declare -i LOCKCOUNTCURRENT=0
3059         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3060                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3061         done
3062
3063         declare -i LOCKUNUSEDCOUNTCURRENT=0
3064         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3065                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3066         done
3067
3068         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3069                 $LCTL set_param -n ldlm.dump_namespaces ""
3070                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3071                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3072                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3073                 return 2
3074         fi
3075         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3076                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3077                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3078                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3079                 return 3
3080         fi
3081 }
3082 run_test 29 "IT_GETATTR regression  ============================"
3083
3084 test_30a() { # was test_30
3085         cp $(which ls) $DIR || cp /bin/ls $DIR
3086         $DIR/ls / || error "Can't execute binary from lustre"
3087         rm $DIR/ls
3088 }
3089 run_test 30a "execute binary from Lustre (execve) =============="
3090
3091 test_30b() {
3092         cp `which ls` $DIR || cp /bin/ls $DIR
3093         chmod go+rx $DIR/ls
3094         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3095         rm $DIR/ls
3096 }
3097 run_test 30b "execute binary from Lustre as non-root ==========="
3098
3099 test_30c() { # b=22376
3100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3101
3102         cp $(which ls) $DIR || cp /bin/ls $DIR
3103         chmod a-rw $DIR/ls
3104         cancel_lru_locks mdc
3105         cancel_lru_locks osc
3106         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3107         rm -f $DIR/ls
3108 }
3109 run_test 30c "execute binary from Lustre without read perms ===="
3110
3111 test_30d() {
3112         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3113
3114         for i in {1..10}; do
3115                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3116                 local PID=$!
3117                 sleep 1
3118                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3119                 wait $PID || error "executing dd from Lustre failed"
3120                 rm -f $DIR/$tfile
3121         done
3122
3123         rm -f $DIR/dd
3124 }
3125 run_test 30d "execute binary from Lustre while clear locks"
3126
3127 test_31a() {
3128         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3129         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3130 }
3131 run_test 31a "open-unlink file =================================="
3132
3133 test_31b() {
3134         touch $DIR/f31 || error "touch $DIR/f31 failed"
3135         ln $DIR/f31 $DIR/f31b || error "ln failed"
3136         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3137         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3138 }
3139 run_test 31b "unlink file with multiple links while open ======="
3140
3141 test_31c() {
3142         touch $DIR/f31 || error "touch $DIR/f31 failed"
3143         ln $DIR/f31 $DIR/f31c || error "ln failed"
3144         multiop_bg_pause $DIR/f31 O_uc ||
3145                 error "multiop_bg_pause for $DIR/f31 failed"
3146         MULTIPID=$!
3147         $MULTIOP $DIR/f31c Ouc
3148         kill -USR1 $MULTIPID
3149         wait $MULTIPID
3150 }
3151 run_test 31c "open-unlink file with multiple links ============="
3152
3153 test_31d() {
3154         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3155         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3156 }
3157 run_test 31d "remove of open directory ========================="
3158
3159 test_31e() { # bug 2904
3160         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3161 }
3162 run_test 31e "remove of open non-empty directory ==============="
3163
3164 test_31f() { # bug 4554
3165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3166
3167         set -vx
3168         test_mkdir $DIR/d31f
3169         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3170         cp /etc/hosts $DIR/d31f
3171         ls -l $DIR/d31f
3172         $LFS getstripe $DIR/d31f/hosts
3173         multiop_bg_pause $DIR/d31f D_c || return 1
3174         MULTIPID=$!
3175
3176         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3177         test_mkdir $DIR/d31f
3178         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3179         cp /etc/hosts $DIR/d31f
3180         ls -l $DIR/d31f
3181         $LFS getstripe $DIR/d31f/hosts
3182         multiop_bg_pause $DIR/d31f D_c || return 1
3183         MULTIPID2=$!
3184
3185         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3186         wait $MULTIPID || error "first opendir $MULTIPID failed"
3187
3188         sleep 6
3189
3190         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3191         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3192         set +vx
3193 }
3194 run_test 31f "remove of open directory with open-unlink file ==="
3195
3196 test_31g() {
3197         echo "-- cross directory link --"
3198         test_mkdir -c1 $DIR/${tdir}ga
3199         test_mkdir -c1 $DIR/${tdir}gb
3200         touch $DIR/${tdir}ga/f
3201         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3202         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3203         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3204         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3205         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3206 }
3207 run_test 31g "cross directory link==============="
3208
3209 test_31h() {
3210         echo "-- cross directory link --"
3211         test_mkdir -c1 $DIR/${tdir}
3212         test_mkdir -c1 $DIR/${tdir}/dir
3213         touch $DIR/${tdir}/f
3214         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3215         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3216         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3217         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3218         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3219 }
3220 run_test 31h "cross directory link under child==============="
3221
3222 test_31i() {
3223         echo "-- cross directory link --"
3224         test_mkdir -c1 $DIR/$tdir
3225         test_mkdir -c1 $DIR/$tdir/dir
3226         touch $DIR/$tdir/dir/f
3227         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3228         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3229         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3230         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3231         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3232 }
3233 run_test 31i "cross directory link under parent==============="
3234
3235 test_31j() {
3236         test_mkdir -c1 -p $DIR/$tdir
3237         test_mkdir -c1 -p $DIR/$tdir/dir1
3238         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3239         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3240         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3241         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3242         return 0
3243 }
3244 run_test 31j "link for directory==============="
3245
3246 test_31k() {
3247         test_mkdir -c1 -p $DIR/$tdir
3248         touch $DIR/$tdir/s
3249         touch $DIR/$tdir/exist
3250         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3251         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3252         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3253         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3254         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3255         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3256         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3257         return 0
3258 }
3259 run_test 31k "link to file: the same, non-existing, dir==============="
3260
3261 test_31m() {
3262         mkdir $DIR/d31m
3263         touch $DIR/d31m/s
3264         mkdir $DIR/d31m2
3265         touch $DIR/d31m2/exist
3266         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3267         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3268         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3269         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3270         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3271         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3272         return 0
3273 }
3274 run_test 31m "link to file: the same, non-existing, dir==============="
3275
3276 test_31n() {
3277         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3278         nlink=$(stat --format=%h $DIR/$tfile)
3279         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3280         local fd=$(free_fd)
3281         local cmd="exec $fd<$DIR/$tfile"
3282         eval $cmd
3283         cmd="exec $fd<&-"
3284         trap "eval $cmd" EXIT
3285         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3286         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3287         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3288         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3289         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3290         eval $cmd
3291 }
3292 run_test 31n "check link count of unlinked file"
3293
3294 link_one() {
3295         local tempfile=$(mktemp $1_XXXXXX)
3296         mlink $tempfile $1 2> /dev/null &&
3297                 echo "$BASHPID: link $tempfile to $1 succeeded"
3298         munlink $tempfile
3299 }
3300
3301 test_31o() { # LU-2901
3302         test_mkdir $DIR/$tdir
3303         for LOOP in $(seq 100); do
3304                 rm -f $DIR/$tdir/$tfile*
3305                 for THREAD in $(seq 8); do
3306                         link_one $DIR/$tdir/$tfile.$LOOP &
3307                 done
3308                 wait
3309                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3310                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3311                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3312                         break || true
3313         done
3314 }
3315 run_test 31o "duplicate hard links with same filename"
3316
3317 test_31p() {
3318         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3319
3320         test_mkdir $DIR/$tdir
3321         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3322         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3323
3324         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3325                 error "open unlink test1 failed"
3326         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3327                 error "open unlink test2 failed"
3328
3329         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3330                 error "test1 still exists"
3331         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3332                 error "test2 still exists"
3333 }
3334 run_test 31p "remove of open striped directory"
3335
3336 cleanup_test32_mount() {
3337         local rc=0
3338         trap 0
3339         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3340         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3341         losetup -d $loopdev || true
3342         rm -rf $DIR/$tdir
3343         return $rc
3344 }
3345
3346 test_32a() {
3347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3348
3349         echo "== more mountpoints and symlinks ================="
3350         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3351         trap cleanup_test32_mount EXIT
3352         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3353         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3354                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3355         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3356                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3357         cleanup_test32_mount
3358 }
3359 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3360
3361 test_32b() {
3362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3363
3364         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3365         trap cleanup_test32_mount EXIT
3366         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3367         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3368                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3369         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3370                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3371         cleanup_test32_mount
3372 }
3373 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3374
3375 test_32c() {
3376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3377
3378         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3379         trap cleanup_test32_mount EXIT
3380         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3381         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3382                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3383         test_mkdir -p $DIR/$tdir/d2/test_dir
3384         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3385                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3386         cleanup_test32_mount
3387 }
3388 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3389
3390 test_32d() {
3391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3392
3393         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3394         trap cleanup_test32_mount EXIT
3395         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3396         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3397                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3398         test_mkdir -p $DIR/$tdir/d2/test_dir
3399         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3400                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3401         cleanup_test32_mount
3402 }
3403 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3404
3405 test_32e() {
3406         rm -fr $DIR/$tdir
3407         test_mkdir -p $DIR/$tdir/tmp
3408         local tmp_dir=$DIR/$tdir/tmp
3409         ln -s $DIR/$tdir $tmp_dir/symlink11
3410         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3411         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3412         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3413 }
3414 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3415
3416 test_32f() {
3417         rm -fr $DIR/$tdir
3418         test_mkdir -p $DIR/$tdir/tmp
3419         local tmp_dir=$DIR/$tdir/tmp
3420         ln -s $DIR/$tdir $tmp_dir/symlink11
3421         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3422         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3423         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3424 }
3425 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3426
3427 test_32g() {
3428         local tmp_dir=$DIR/$tdir/tmp
3429         test_mkdir -p $tmp_dir
3430         test_mkdir $DIR/${tdir}2
3431         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3432         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3433         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3434         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3435         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3436         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3437 }
3438 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3439
3440 test_32h() {
3441         rm -fr $DIR/$tdir $DIR/${tdir}2
3442         tmp_dir=$DIR/$tdir/tmp
3443         test_mkdir -p $tmp_dir
3444         test_mkdir $DIR/${tdir}2
3445         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3446         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3447         ls $tmp_dir/symlink12 || error "listing symlink12"
3448         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3449 }
3450 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3451
3452 test_32i() {
3453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3454
3455         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3456         trap cleanup_test32_mount EXIT
3457         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3458         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3459                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3460         touch $DIR/$tdir/test_file
3461         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3462                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3463         cleanup_test32_mount
3464 }
3465 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3466
3467 test_32j() {
3468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3469
3470         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3471         trap cleanup_test32_mount EXIT
3472         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3473         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3474                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3475         touch $DIR/$tdir/test_file
3476         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3477                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3478         cleanup_test32_mount
3479 }
3480 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3481
3482 test_32k() {
3483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3484
3485         rm -fr $DIR/$tdir
3486         trap cleanup_test32_mount EXIT
3487         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3488         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3489                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3490         test_mkdir -p $DIR/$tdir/d2
3491         touch $DIR/$tdir/d2/test_file || error "touch failed"
3492         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3493                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3494         cleanup_test32_mount
3495 }
3496 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3497
3498 test_32l() {
3499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3500
3501         rm -fr $DIR/$tdir
3502         trap cleanup_test32_mount EXIT
3503         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3504         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3505                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3506         test_mkdir -p $DIR/$tdir/d2
3507         touch $DIR/$tdir/d2/test_file || error "touch failed"
3508         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3509                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3510         cleanup_test32_mount
3511 }
3512 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3513
3514 test_32m() {
3515         rm -fr $DIR/d32m
3516         test_mkdir -p $DIR/d32m/tmp
3517         TMP_DIR=$DIR/d32m/tmp
3518         ln -s $DIR $TMP_DIR/symlink11
3519         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3520         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3521                 error "symlink11 not a link"
3522         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3523                 error "symlink01 not a link"
3524 }
3525 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3526
3527 test_32n() {
3528         rm -fr $DIR/d32n
3529         test_mkdir -p $DIR/d32n/tmp
3530         TMP_DIR=$DIR/d32n/tmp
3531         ln -s $DIR $TMP_DIR/symlink11
3532         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3533         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3534         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3535 }
3536 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3537
3538 test_32o() {
3539         touch $DIR/$tfile
3540         test_mkdir -p $DIR/d32o/tmp
3541         TMP_DIR=$DIR/d32o/tmp
3542         ln -s $DIR/$tfile $TMP_DIR/symlink12
3543         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3544         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3545                 error "symlink12 not a link"
3546         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3547         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3548                 error "$DIR/d32o/tmp/symlink12 not file type"
3549         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3550                 error "$DIR/d32o/symlink02 not file type"
3551 }
3552 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3553
3554 test_32p() {
3555         log 32p_1
3556         rm -fr $DIR/d32p
3557         log 32p_2
3558         rm -f $DIR/$tfile
3559         log 32p_3
3560         touch $DIR/$tfile
3561         log 32p_4
3562         test_mkdir -p $DIR/d32p/tmp
3563         log 32p_5
3564         TMP_DIR=$DIR/d32p/tmp
3565         log 32p_6
3566         ln -s $DIR/$tfile $TMP_DIR/symlink12
3567         log 32p_7
3568         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3569         log 32p_8
3570         cat $DIR/d32p/tmp/symlink12 ||
3571                 error "Can't open $DIR/d32p/tmp/symlink12"
3572         log 32p_9
3573         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3574         log 32p_10
3575 }
3576 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3577
3578 test_32q() {
3579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3580
3581         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3582         trap cleanup_test32_mount EXIT
3583         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3584         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3585         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3586                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3587         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3588         cleanup_test32_mount
3589 }
3590 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3591
3592 test_32r() {
3593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3594
3595         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3596         trap cleanup_test32_mount EXIT
3597         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3598         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3599         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3600                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3601         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3602         cleanup_test32_mount
3603 }
3604 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3605
3606 test_33aa() {
3607         rm -f $DIR/$tfile
3608         touch $DIR/$tfile
3609         chmod 444 $DIR/$tfile
3610         chown $RUNAS_ID $DIR/$tfile
3611         log 33_1
3612         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3613         log 33_2
3614 }
3615 run_test 33aa "write file with mode 444 (should return error)"
3616
3617 test_33a() {
3618         rm -fr $DIR/$tdir
3619         test_mkdir $DIR/$tdir
3620         chown $RUNAS_ID $DIR/$tdir
3621         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3622                 error "$RUNAS create $tdir/$tfile failed"
3623         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3624                 error "open RDWR" || true
3625 }
3626 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3627
3628 test_33b() {
3629         rm -fr $DIR/$tdir
3630         test_mkdir $DIR/$tdir
3631         chown $RUNAS_ID $DIR/$tdir
3632         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3633 }
3634 run_test 33b "test open file with malformed flags (No panic)"
3635
3636 test_33c() {
3637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3638         remote_ost_nodsh && skip "remote OST with nodsh"
3639
3640         local ostnum
3641         local ostname
3642         local write_bytes
3643         local all_zeros
3644
3645         all_zeros=:
3646         rm -fr $DIR/$tdir
3647         test_mkdir $DIR/$tdir
3648         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3649
3650         sync
3651         for ostnum in $(seq $OSTCOUNT); do
3652                 # test-framework's OST numbering is one-based, while Lustre's
3653                 # is zero-based
3654                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3655                 # Parsing llobdstat's output sucks; we could grep the /proc
3656                 # path, but that's likely to not be as portable as using the
3657                 # llobdstat utility.  So we parse lctl output instead.
3658                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3659                         obdfilter/$ostname/stats |
3660                         awk '/^write_bytes/ {print $7}' )
3661                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3662                 if (( ${write_bytes:-0} > 0 ))
3663                 then
3664                         all_zeros=false
3665                         break;
3666                 fi
3667         done
3668
3669         $all_zeros || return 0
3670
3671         # Write four bytes
3672         echo foo > $DIR/$tdir/bar
3673         # Really write them
3674         sync
3675
3676         # Total up write_bytes after writing.  We'd better find non-zeros.
3677         for ostnum in $(seq $OSTCOUNT); do
3678                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3679                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3680                         obdfilter/$ostname/stats |
3681                         awk '/^write_bytes/ {print $7}' )
3682                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3683                 if (( ${write_bytes:-0} > 0 ))
3684                 then
3685                         all_zeros=false
3686                         break;
3687                 fi
3688         done
3689
3690         if $all_zeros
3691         then
3692                 for ostnum in $(seq $OSTCOUNT); do
3693                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3694                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3695                         do_facet ost$ostnum lctl get_param -n \
3696                                 obdfilter/$ostname/stats
3697                 done
3698                 error "OST not keeping write_bytes stats (b22312)"
3699         fi
3700 }
3701 run_test 33c "test llobdstat and write_bytes"
3702
3703 test_33d() {
3704         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3706
3707         local MDTIDX=1
3708         local remote_dir=$DIR/$tdir/remote_dir
3709
3710         test_mkdir $DIR/$tdir
3711         $LFS mkdir -i $MDTIDX $remote_dir ||
3712                 error "create remote directory failed"
3713
3714         touch $remote_dir/$tfile
3715         chmod 444 $remote_dir/$tfile
3716         chown $RUNAS_ID $remote_dir/$tfile
3717
3718         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3719
3720         chown $RUNAS_ID $remote_dir
3721         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3722                                         error "create" || true
3723         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3724                                     error "open RDWR" || true
3725         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3726 }
3727 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3728
3729 test_33e() {
3730         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3731
3732         mkdir $DIR/$tdir
3733
3734         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3735         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3736         mkdir $DIR/$tdir/local_dir
3737
3738         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3739         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3740         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3741
3742         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3743                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3744
3745         rmdir $DIR/$tdir/* || error "rmdir failed"
3746
3747         umask 777
3748         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3749         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3750         mkdir $DIR/$tdir/local_dir
3751
3752         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3753         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3754         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3755
3756         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3757                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3758
3759         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3760
3761         umask 000
3762         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3763         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3764         mkdir $DIR/$tdir/local_dir
3765
3766         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3767         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3768         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3769
3770         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3771                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3772 }
3773 run_test 33e "mkdir and striped directory should have same mode"
3774
3775 cleanup_33f() {
3776         trap 0
3777         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3778 }
3779
3780 test_33f() {
3781         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3782         remote_mds_nodsh && skip "remote MDS with nodsh"
3783
3784         mkdir $DIR/$tdir
3785         chmod go+rwx $DIR/$tdir
3786         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3787         trap cleanup_33f EXIT
3788
3789         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3790                 error "cannot create striped directory"
3791
3792         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3793                 error "cannot create files in striped directory"
3794
3795         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3796                 error "cannot remove files in striped directory"
3797
3798         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3799                 error "cannot remove striped directory"
3800
3801         cleanup_33f
3802 }
3803 run_test 33f "nonroot user can create, access, and remove a striped directory"
3804
3805 test_33g() {
3806         mkdir -p $DIR/$tdir/dir2
3807
3808         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3809         echo $err
3810         [[ $err =~ "exists" ]] || error "Not exists error"
3811 }
3812 run_test 33g "nonroot user create already existing root created file"
3813
3814 test_33h() {
3815         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3816         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3817                 skip "Need MDS version at least 2.13.50"
3818
3819         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3820                 error "mkdir $tdir failed"
3821         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3822
3823         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3824         local index2
3825
3826         for fname in $DIR/$tdir/$tfile.bak \
3827                      $DIR/$tdir/$tfile.SAV \
3828                      $DIR/$tdir/$tfile.orig \
3829                      $DIR/$tdir/$tfile~; do
3830                 touch $fname  || error "touch $fname failed"
3831                 index2=$($LFS getstripe -m $fname)
3832                 [ $index -eq $index2 ] ||
3833                         error "$fname MDT index mismatch $index != $index2"
3834         done
3835
3836         local failed=0
3837         for i in {1..250}; do
3838                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3839                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3840                         touch $fname  || error "touch $fname failed"
3841                         index2=$($LFS getstripe -m $fname)
3842                         if [[ $index != $index2 ]]; then
3843                                 failed=$((failed + 1))
3844                                 echo "$fname MDT index mismatch $index != $index2"
3845                         fi
3846                 done
3847         done
3848         echo "$failed MDT index mismatches"
3849         (( failed < 20 )) || error "MDT index mismatch $failed times"
3850
3851 }
3852 run_test 33h "temp file is located on the same MDT as target"
3853
3854 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3855 test_34a() {
3856         rm -f $DIR/f34
3857         $MCREATE $DIR/f34 || error "mcreate failed"
3858         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3859                 error "getstripe failed"
3860         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3861         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3862                 error "getstripe failed"
3863         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3864                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3865 }
3866 run_test 34a "truncate file that has not been opened ==========="
3867
3868 test_34b() {
3869         [ ! -f $DIR/f34 ] && test_34a
3870         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3871                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3872         $OPENFILE -f O_RDONLY $DIR/f34
3873         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3874                 error "getstripe failed"
3875         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3876                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3877 }
3878 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3879
3880 test_34c() {
3881         [ ! -f $DIR/f34 ] && test_34a
3882         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3883                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3884         $OPENFILE -f O_RDWR $DIR/f34
3885         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3886                 error "$LFS getstripe failed"
3887         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3888                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3889 }
3890 run_test 34c "O_RDWR opening file-with-size works =============="
3891
3892 test_34d() {
3893         [ ! -f $DIR/f34 ] && test_34a
3894         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3895                 error "dd failed"
3896         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3897                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3898         rm $DIR/f34
3899 }
3900 run_test 34d "write to sparse file ============================="
3901
3902 test_34e() {
3903         rm -f $DIR/f34e
3904         $MCREATE $DIR/f34e || error "mcreate failed"
3905         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3906         $CHECKSTAT -s 1000 $DIR/f34e ||
3907                 error "Size of $DIR/f34e not equal to 1000 bytes"
3908         $OPENFILE -f O_RDWR $DIR/f34e
3909         $CHECKSTAT -s 1000 $DIR/f34e ||
3910                 error "Size of $DIR/f34e not equal to 1000 bytes"
3911 }
3912 run_test 34e "create objects, some with size and some without =="
3913
3914 test_34f() { # bug 6242, 6243
3915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3916
3917         SIZE34F=48000
3918         rm -f $DIR/f34f
3919         $MCREATE $DIR/f34f || error "mcreate failed"
3920         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3921         dd if=$DIR/f34f of=$TMP/f34f
3922         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3923         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3924         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3925         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3926         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3927 }
3928 run_test 34f "read from a file with no objects until EOF ======="
3929
3930 test_34g() {
3931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3932
3933         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3934                 error "dd failed"
3935         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3936         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3937                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3938         cancel_lru_locks osc
3939         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3940                 error "wrong size after lock cancel"
3941
3942         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3943         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3944                 error "expanding truncate failed"
3945         cancel_lru_locks osc
3946         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3947                 error "wrong expanded size after lock cancel"
3948 }
3949 run_test 34g "truncate long file ==============================="
3950
3951 test_34h() {
3952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3953
3954         local gid=10
3955         local sz=1000
3956
3957         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3958         sync # Flush the cache so that multiop below does not block on cache
3959              # flush when getting the group lock
3960         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3961         MULTIPID=$!
3962
3963         # Since just timed wait is not good enough, let's do a sync write
3964         # that way we are sure enough time for a roundtrip + processing
3965         # passed + 2 seconds of extra margin.
3966         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3967         rm $DIR/${tfile}-1
3968         sleep 2
3969
3970         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3971                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3972                 kill -9 $MULTIPID
3973         fi
3974         wait $MULTIPID
3975         local nsz=`stat -c %s $DIR/$tfile`
3976         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3977 }
3978 run_test 34h "ftruncate file under grouplock should not block"
3979
3980 test_35a() {
3981         cp /bin/sh $DIR/f35a
3982         chmod 444 $DIR/f35a
3983         chown $RUNAS_ID $DIR/f35a
3984         $RUNAS $DIR/f35a && error || true
3985         rm $DIR/f35a
3986 }
3987 run_test 35a "exec file with mode 444 (should return and not leak)"
3988
3989 test_36a() {
3990         rm -f $DIR/f36
3991         utime $DIR/f36 || error "utime failed for MDS"
3992 }
3993 run_test 36a "MDS utime check (mknod, utime)"
3994
3995 test_36b() {
3996         echo "" > $DIR/f36
3997         utime $DIR/f36 || error "utime failed for OST"
3998 }
3999 run_test 36b "OST utime check (open, utime)"
4000
4001 test_36c() {
4002         rm -f $DIR/d36/f36
4003         test_mkdir $DIR/d36
4004         chown $RUNAS_ID $DIR/d36
4005         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4006 }
4007 run_test 36c "non-root MDS utime check (mknod, utime)"
4008
4009 test_36d() {
4010         [ ! -d $DIR/d36 ] && test_36c
4011         echo "" > $DIR/d36/f36
4012         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4013 }
4014 run_test 36d "non-root OST utime check (open, utime)"
4015
4016 test_36e() {
4017         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4018
4019         test_mkdir $DIR/$tdir
4020         touch $DIR/$tdir/$tfile
4021         $RUNAS utime $DIR/$tdir/$tfile &&
4022                 error "utime worked, expected failure" || true
4023 }
4024 run_test 36e "utime on non-owned file (should return error)"
4025
4026 subr_36fh() {
4027         local fl="$1"
4028         local LANG_SAVE=$LANG
4029         local LC_LANG_SAVE=$LC_LANG
4030         export LANG=C LC_LANG=C # for date language
4031
4032         DATESTR="Dec 20  2000"
4033         test_mkdir $DIR/$tdir
4034         lctl set_param fail_loc=$fl
4035         date; date +%s
4036         cp /etc/hosts $DIR/$tdir/$tfile
4037         sync & # write RPC generated with "current" inode timestamp, but delayed
4038         sleep 1
4039         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4040         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4041         cancel_lru_locks $OSC
4042         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4043         date; date +%s
4044         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4045                 echo "BEFORE: $LS_BEFORE" && \
4046                 echo "AFTER : $LS_AFTER" && \
4047                 echo "WANT  : $DATESTR" && \
4048                 error "$DIR/$tdir/$tfile timestamps changed" || true
4049
4050         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4051 }
4052
4053 test_36f() {
4054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4055
4056         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4057         subr_36fh "0x80000214"
4058 }
4059 run_test 36f "utime on file racing with OST BRW write =========="
4060
4061 test_36g() {
4062         remote_ost_nodsh && skip "remote OST with nodsh"
4063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4064         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4065                 skip "Need MDS version at least 2.12.51"
4066
4067         local fmd_max_age
4068         local fmd
4069         local facet="ost1"
4070         local tgt="obdfilter"
4071
4072         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4073
4074         test_mkdir $DIR/$tdir
4075         fmd_max_age=$(do_facet $facet \
4076                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4077                 head -n 1")
4078
4079         echo "FMD max age: ${fmd_max_age}s"
4080         touch $DIR/$tdir/$tfile
4081         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4082                 gawk '{cnt=cnt+$1}  END{print cnt}')
4083         echo "FMD before: $fmd"
4084         [[ $fmd == 0 ]] &&
4085                 error "FMD wasn't create by touch"
4086         sleep $((fmd_max_age + 12))
4087         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4088                 gawk '{cnt=cnt+$1}  END{print cnt}')
4089         echo "FMD after: $fmd"
4090         [[ $fmd == 0 ]] ||
4091                 error "FMD wasn't expired by ping"
4092 }
4093 run_test 36g "FMD cache expiry ====================="
4094
4095 test_36h() {
4096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4097
4098         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4099         subr_36fh "0x80000227"
4100 }
4101 run_test 36h "utime on file racing with OST BRW write =========="
4102
4103 test_36i() {
4104         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4105
4106         test_mkdir $DIR/$tdir
4107         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4108
4109         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4110         local new_mtime=$((mtime + 200))
4111
4112         #change Modify time of striped dir
4113         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4114                         error "change mtime failed"
4115
4116         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4117
4118         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4119 }
4120 run_test 36i "change mtime on striped directory"
4121
4122 # test_37 - duplicate with tests 32q 32r
4123
4124 test_38() {
4125         local file=$DIR/$tfile
4126         touch $file
4127         openfile -f O_DIRECTORY $file
4128         local RC=$?
4129         local ENOTDIR=20
4130         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4131         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4132 }
4133 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4134
4135 test_39a() { # was test_39
4136         touch $DIR/$tfile
4137         touch $DIR/${tfile}2
4138 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4139 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4140 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4141         sleep 2
4142         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4143         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4144                 echo "mtime"
4145                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4146                 echo "atime"
4147                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4148                 echo "ctime"
4149                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4150                 error "O_TRUNC didn't change timestamps"
4151         fi
4152 }
4153 run_test 39a "mtime changed on create"
4154
4155 test_39b() {
4156         test_mkdir -c1 $DIR/$tdir
4157         cp -p /etc/passwd $DIR/$tdir/fopen
4158         cp -p /etc/passwd $DIR/$tdir/flink
4159         cp -p /etc/passwd $DIR/$tdir/funlink
4160         cp -p /etc/passwd $DIR/$tdir/frename
4161         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4162
4163         sleep 1
4164         echo "aaaaaa" >> $DIR/$tdir/fopen
4165         echo "aaaaaa" >> $DIR/$tdir/flink
4166         echo "aaaaaa" >> $DIR/$tdir/funlink
4167         echo "aaaaaa" >> $DIR/$tdir/frename
4168
4169         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4170         local link_new=`stat -c %Y $DIR/$tdir/flink`
4171         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4172         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4173
4174         cat $DIR/$tdir/fopen > /dev/null
4175         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4176         rm -f $DIR/$tdir/funlink2
4177         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4178
4179         for (( i=0; i < 2; i++ )) ; do
4180                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4181                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4182                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4183                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4184
4185                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4186                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4187                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4188                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4189
4190                 cancel_lru_locks $OSC
4191                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4192         done
4193 }
4194 run_test 39b "mtime change on open, link, unlink, rename  ======"
4195
4196 # this should be set to past
4197 TEST_39_MTIME=`date -d "1 year ago" +%s`
4198
4199 # bug 11063
4200 test_39c() {
4201         touch $DIR1/$tfile
4202         sleep 2
4203         local mtime0=`stat -c %Y $DIR1/$tfile`
4204
4205         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4206         local mtime1=`stat -c %Y $DIR1/$tfile`
4207         [ "$mtime1" = $TEST_39_MTIME ] || \
4208                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4209
4210         local d1=`date +%s`
4211         echo hello >> $DIR1/$tfile
4212         local d2=`date +%s`
4213         local mtime2=`stat -c %Y $DIR1/$tfile`
4214         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4215                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4216
4217         mv $DIR1/$tfile $DIR1/$tfile-1
4218
4219         for (( i=0; i < 2; i++ )) ; do
4220                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4221                 [ "$mtime2" = "$mtime3" ] || \
4222                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4223
4224                 cancel_lru_locks $OSC
4225                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4226         done
4227 }
4228 run_test 39c "mtime change on rename ==========================="
4229
4230 # bug 21114
4231 test_39d() {
4232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4233
4234         touch $DIR1/$tfile
4235         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4236
4237         for (( i=0; i < 2; i++ )) ; do
4238                 local mtime=`stat -c %Y $DIR1/$tfile`
4239                 [ $mtime = $TEST_39_MTIME ] || \
4240                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4241
4242                 cancel_lru_locks $OSC
4243                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4244         done
4245 }
4246 run_test 39d "create, utime, stat =============================="
4247
4248 # bug 21114
4249 test_39e() {
4250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4251
4252         touch $DIR1/$tfile
4253         local mtime1=`stat -c %Y $DIR1/$tfile`
4254
4255         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4256
4257         for (( i=0; i < 2; i++ )) ; do
4258                 local mtime2=`stat -c %Y $DIR1/$tfile`
4259                 [ $mtime2 = $TEST_39_MTIME ] || \
4260                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4261
4262                 cancel_lru_locks $OSC
4263                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4264         done
4265 }
4266 run_test 39e "create, stat, utime, stat ========================"
4267
4268 # bug 21114
4269 test_39f() {
4270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4271
4272         touch $DIR1/$tfile
4273         mtime1=`stat -c %Y $DIR1/$tfile`
4274
4275         sleep 2
4276         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4277
4278         for (( i=0; i < 2; i++ )) ; do
4279                 local mtime2=`stat -c %Y $DIR1/$tfile`
4280                 [ $mtime2 = $TEST_39_MTIME ] || \
4281                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4282
4283                 cancel_lru_locks $OSC
4284                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4285         done
4286 }
4287 run_test 39f "create, stat, sleep, utime, stat ================="
4288
4289 # bug 11063
4290 test_39g() {
4291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4292
4293         echo hello >> $DIR1/$tfile
4294         local mtime1=`stat -c %Y $DIR1/$tfile`
4295
4296         sleep 2
4297         chmod o+r $DIR1/$tfile
4298
4299         for (( i=0; i < 2; i++ )) ; do
4300                 local mtime2=`stat -c %Y $DIR1/$tfile`
4301                 [ "$mtime1" = "$mtime2" ] || \
4302                         error "lost mtime: $mtime2, should be $mtime1"
4303
4304                 cancel_lru_locks $OSC
4305                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4306         done
4307 }
4308 run_test 39g "write, chmod, stat ==============================="
4309
4310 # bug 11063
4311 test_39h() {
4312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4313
4314         touch $DIR1/$tfile
4315         sleep 1
4316
4317         local d1=`date`
4318         echo hello >> $DIR1/$tfile
4319         local mtime1=`stat -c %Y $DIR1/$tfile`
4320
4321         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4322         local d2=`date`
4323         if [ "$d1" != "$d2" ]; then
4324                 echo "write and touch not within one second"
4325         else
4326                 for (( i=0; i < 2; i++ )) ; do
4327                         local mtime2=`stat -c %Y $DIR1/$tfile`
4328                         [ "$mtime2" = $TEST_39_MTIME ] || \
4329                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4330
4331                         cancel_lru_locks $OSC
4332                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4333                 done
4334         fi
4335 }
4336 run_test 39h "write, utime within one second, stat ============="
4337
4338 test_39i() {
4339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4340
4341         touch $DIR1/$tfile
4342         sleep 1
4343
4344         echo hello >> $DIR1/$tfile
4345         local mtime1=`stat -c %Y $DIR1/$tfile`
4346
4347         mv $DIR1/$tfile $DIR1/$tfile-1
4348
4349         for (( i=0; i < 2; i++ )) ; do
4350                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4351
4352                 [ "$mtime1" = "$mtime2" ] || \
4353                         error "lost mtime: $mtime2, should be $mtime1"
4354
4355                 cancel_lru_locks $OSC
4356                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4357         done
4358 }
4359 run_test 39i "write, rename, stat =============================="
4360
4361 test_39j() {
4362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4363
4364         start_full_debug_logging
4365         touch $DIR1/$tfile
4366         sleep 1
4367
4368         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4369         lctl set_param fail_loc=0x80000412
4370         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4371                 error "multiop failed"
4372         local multipid=$!
4373         local mtime1=`stat -c %Y $DIR1/$tfile`
4374
4375         mv $DIR1/$tfile $DIR1/$tfile-1
4376
4377         kill -USR1 $multipid
4378         wait $multipid || error "multiop close failed"
4379
4380         for (( i=0; i < 2; i++ )) ; do
4381                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4382                 [ "$mtime1" = "$mtime2" ] ||
4383                         error "mtime is lost on close: $mtime2, " \
4384                               "should be $mtime1"
4385
4386                 cancel_lru_locks
4387                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4388         done
4389         lctl set_param fail_loc=0
4390         stop_full_debug_logging
4391 }
4392 run_test 39j "write, rename, close, stat ======================="
4393
4394 test_39k() {
4395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4396
4397         touch $DIR1/$tfile
4398         sleep 1
4399
4400         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4401         local multipid=$!
4402         local mtime1=`stat -c %Y $DIR1/$tfile`
4403
4404         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4405
4406         kill -USR1 $multipid
4407         wait $multipid || error "multiop close failed"
4408
4409         for (( i=0; i < 2; i++ )) ; do
4410                 local mtime2=`stat -c %Y $DIR1/$tfile`
4411
4412                 [ "$mtime2" = $TEST_39_MTIME ] || \
4413                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4414
4415                 cancel_lru_locks
4416                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4417         done
4418 }
4419 run_test 39k "write, utime, close, stat ========================"
4420
4421 # this should be set to future
4422 TEST_39_ATIME=`date -d "1 year" +%s`
4423
4424 test_39l() {
4425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4426         remote_mds_nodsh && skip "remote MDS with nodsh"
4427
4428         local atime_diff=$(do_facet $SINGLEMDS \
4429                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4430         rm -rf $DIR/$tdir
4431         mkdir -p $DIR/$tdir
4432
4433         # test setting directory atime to future
4434         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4435         local atime=$(stat -c %X $DIR/$tdir)
4436         [ "$atime" = $TEST_39_ATIME ] ||
4437                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4438
4439         # test setting directory atime from future to now
4440         local now=$(date +%s)
4441         touch -a -d @$now $DIR/$tdir
4442
4443         atime=$(stat -c %X $DIR/$tdir)
4444         [ "$atime" -eq "$now"  ] ||
4445                 error "atime is not updated from future: $atime, $now"
4446
4447         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4448         sleep 3
4449
4450         # test setting directory atime when now > dir atime + atime_diff
4451         local d1=$(date +%s)
4452         ls $DIR/$tdir
4453         local d2=$(date +%s)
4454         cancel_lru_locks mdc
4455         atime=$(stat -c %X $DIR/$tdir)
4456         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4457                 error "atime is not updated  : $atime, should be $d2"
4458
4459         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4460         sleep 3
4461
4462         # test not setting directory atime when now < dir atime + atime_diff
4463         ls $DIR/$tdir
4464         cancel_lru_locks mdc
4465         atime=$(stat -c %X $DIR/$tdir)
4466         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4467                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4468
4469         do_facet $SINGLEMDS \
4470                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4471 }
4472 run_test 39l "directory atime update ==========================="
4473
4474 test_39m() {
4475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4476
4477         touch $DIR1/$tfile
4478         sleep 2
4479         local far_past_mtime=$(date -d "May 29 1953" +%s)
4480         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4481
4482         touch -m -d @$far_past_mtime $DIR1/$tfile
4483         touch -a -d @$far_past_atime $DIR1/$tfile
4484
4485         for (( i=0; i < 2; i++ )) ; do
4486                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4487                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4488                         error "atime or mtime set incorrectly"
4489
4490                 cancel_lru_locks $OSC
4491                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4492         done
4493 }
4494 run_test 39m "test atime and mtime before 1970"
4495
4496 test_39n() { # LU-3832
4497         remote_mds_nodsh && skip "remote MDS with nodsh"
4498
4499         local atime_diff=$(do_facet $SINGLEMDS \
4500                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4501         local atime0
4502         local atime1
4503         local atime2
4504
4505         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4506
4507         rm -rf $DIR/$tfile
4508         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4509         atime0=$(stat -c %X $DIR/$tfile)
4510
4511         sleep 5
4512         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4513         atime1=$(stat -c %X $DIR/$tfile)
4514
4515         sleep 5
4516         cancel_lru_locks mdc
4517         cancel_lru_locks osc
4518         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4519         atime2=$(stat -c %X $DIR/$tfile)
4520
4521         do_facet $SINGLEMDS \
4522                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4523
4524         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4525         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4526 }
4527 run_test 39n "check that O_NOATIME is honored"
4528
4529 test_39o() {
4530         TESTDIR=$DIR/$tdir/$tfile
4531         [ -e $TESTDIR ] && rm -rf $TESTDIR
4532         mkdir -p $TESTDIR
4533         cd $TESTDIR
4534         links1=2
4535         ls
4536         mkdir a b
4537         ls
4538         links2=$(stat -c %h .)
4539         [ $(($links1 + 2)) != $links2 ] &&
4540                 error "wrong links count $(($links1 + 2)) != $links2"
4541         rmdir b
4542         links3=$(stat -c %h .)
4543         [ $(($links1 + 1)) != $links3 ] &&
4544                 error "wrong links count $links1 != $links3"
4545         return 0
4546 }
4547 run_test 39o "directory cached attributes updated after create"
4548
4549 test_39p() {
4550         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4551
4552         local MDTIDX=1
4553         TESTDIR=$DIR/$tdir/$tdir
4554         [ -e $TESTDIR ] && rm -rf $TESTDIR
4555         test_mkdir -p $TESTDIR
4556         cd $TESTDIR
4557         links1=2
4558         ls
4559         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4560         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4561         ls
4562         links2=$(stat -c %h .)
4563         [ $(($links1 + 2)) != $links2 ] &&
4564                 error "wrong links count $(($links1 + 2)) != $links2"
4565         rmdir remote_dir2
4566         links3=$(stat -c %h .)
4567         [ $(($links1 + 1)) != $links3 ] &&
4568                 error "wrong links count $links1 != $links3"
4569         return 0
4570 }
4571 run_test 39p "remote directory cached attributes updated after create ========"
4572
4573 test_39r() {
4574         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4575                 skip "no atime update on old OST"
4576         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4577                 skip_env "ldiskfs only test"
4578         fi
4579
4580         local saved_adiff
4581         saved_adiff=$(do_facet ost1 \
4582                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4583         stack_trap "do_facet ost1 \
4584                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4585
4586         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4587
4588         $LFS setstripe -i 0 $DIR/$tfile
4589         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4590                 error "can't write initial file"
4591         cancel_lru_locks osc
4592
4593         # exceed atime_diff and access file
4594         sleep 6
4595         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4596
4597         local atime_cli=$(stat -c %X $DIR/$tfile)
4598         echo "client atime: $atime_cli"
4599         # allow atime update to be written to device
4600         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4601         sleep 5
4602
4603         local ostdev=$(ostdevname 1)
4604         local fid=($(lfs getstripe -y $DIR/$tfile |
4605                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4606         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4607         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4608
4609         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4610         local atime_ost=$(do_facet ost1 "$cmd" |&
4611                           awk -F'[: ]' '/atime:/ { print $4 }')
4612         (( atime_cli == atime_ost )) ||
4613                 error "atime on client $atime_cli != ost $atime_ost"
4614 }
4615 run_test 39r "lazy atime update on OST"
4616
4617 test_39q() { # LU-8041
4618         local testdir=$DIR/$tdir
4619         mkdir -p $testdir
4620         multiop_bg_pause $testdir D_c || error "multiop failed"
4621         local multipid=$!
4622         cancel_lru_locks mdc
4623         kill -USR1 $multipid
4624         local atime=$(stat -c %X $testdir)
4625         [ "$atime" -ne 0 ] || error "atime is zero"
4626 }
4627 run_test 39q "close won't zero out atime"
4628
4629 test_40() {
4630         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4631         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4632                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4633         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4634                 error "$tfile is not 4096 bytes in size"
4635 }
4636 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4637
4638 test_41() {
4639         # bug 1553
4640         small_write $DIR/f41 18
4641 }
4642 run_test 41 "test small file write + fstat ====================="
4643
4644 count_ost_writes() {
4645         lctl get_param -n ${OSC}.*.stats |
4646                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4647                         END { printf("%0.0f", writes) }'
4648 }
4649
4650 # decent default
4651 WRITEBACK_SAVE=500
4652 DIRTY_RATIO_SAVE=40
4653 MAX_DIRTY_RATIO=50
4654 BG_DIRTY_RATIO_SAVE=10
4655 MAX_BG_DIRTY_RATIO=25
4656
4657 start_writeback() {
4658         trap 0
4659         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4660         # dirty_ratio, dirty_background_ratio
4661         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4662                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4663                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4664                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4665         else
4666                 # if file not here, we are a 2.4 kernel
4667                 kill -CONT `pidof kupdated`
4668         fi
4669 }
4670
4671 stop_writeback() {
4672         # setup the trap first, so someone cannot exit the test at the
4673         # exact wrong time and mess up a machine
4674         trap start_writeback EXIT
4675         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4676         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4677                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4678                 sysctl -w vm.dirty_writeback_centisecs=0
4679                 sysctl -w vm.dirty_writeback_centisecs=0
4680                 # save and increase /proc/sys/vm/dirty_ratio
4681                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4682                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4683                 # save and increase /proc/sys/vm/dirty_background_ratio
4684                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4685                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4686         else
4687                 # if file not here, we are a 2.4 kernel
4688                 kill -STOP `pidof kupdated`
4689         fi
4690 }
4691
4692 # ensure that all stripes have some grant before we test client-side cache
4693 setup_test42() {
4694         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4695                 dd if=/dev/zero of=$i bs=4k count=1
4696                 rm $i
4697         done
4698 }
4699
4700 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4701 # file truncation, and file removal.
4702 test_42a() {
4703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4704
4705         setup_test42
4706         cancel_lru_locks $OSC
4707         stop_writeback
4708         sync; sleep 1; sync # just to be safe
4709         BEFOREWRITES=`count_ost_writes`
4710         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4711         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4712         AFTERWRITES=`count_ost_writes`
4713         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4714                 error "$BEFOREWRITES < $AFTERWRITES"
4715         start_writeback
4716 }
4717 run_test 42a "ensure that we don't flush on close"
4718
4719 test_42b() {
4720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4721
4722         setup_test42
4723         cancel_lru_locks $OSC
4724         stop_writeback
4725         sync
4726         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4727         BEFOREWRITES=$(count_ost_writes)
4728         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4729         AFTERWRITES=$(count_ost_writes)
4730         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4731                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4732         fi
4733         BEFOREWRITES=$(count_ost_writes)
4734         sync || error "sync: $?"
4735         AFTERWRITES=$(count_ost_writes)
4736         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4737                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4738         fi
4739         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4740         start_writeback
4741         return 0
4742 }
4743 run_test 42b "test destroy of file with cached dirty data ======"
4744
4745 # if these tests just want to test the effect of truncation,
4746 # they have to be very careful.  consider:
4747 # - the first open gets a {0,EOF}PR lock
4748 # - the first write conflicts and gets a {0, count-1}PW
4749 # - the rest of the writes are under {count,EOF}PW
4750 # - the open for truncate tries to match a {0,EOF}PR
4751 #   for the filesize and cancels the PWs.
4752 # any number of fixes (don't get {0,EOF} on open, match
4753 # composite locks, do smarter file size management) fix
4754 # this, but for now we want these tests to verify that
4755 # the cancellation with truncate intent works, so we
4756 # start the file with a full-file pw lock to match against
4757 # until the truncate.
4758 trunc_test() {
4759         test=$1
4760         file=$DIR/$test
4761         offset=$2
4762         cancel_lru_locks $OSC
4763         stop_writeback
4764         # prime the file with 0,EOF PW to match
4765         touch $file
4766         $TRUNCATE $file 0
4767         sync; sync
4768         # now the real test..
4769         dd if=/dev/zero of=$file bs=1024 count=100
4770         BEFOREWRITES=`count_ost_writes`
4771         $TRUNCATE $file $offset
4772         cancel_lru_locks $OSC
4773         AFTERWRITES=`count_ost_writes`
4774         start_writeback
4775 }
4776
4777 test_42c() {
4778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4779
4780         trunc_test 42c 1024
4781         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4782                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4783         rm $file
4784 }
4785 run_test 42c "test partial truncate of file with cached dirty data"
4786
4787 test_42d() {
4788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4789
4790         trunc_test 42d 0
4791         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4792                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4793         rm $file
4794 }
4795 run_test 42d "test complete truncate of file with cached dirty data"
4796
4797 test_42e() { # bug22074
4798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4799
4800         local TDIR=$DIR/${tdir}e
4801         local pages=16 # hardcoded 16 pages, don't change it.
4802         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4803         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4804         local max_dirty_mb
4805         local warmup_files
4806
4807         test_mkdir $DIR/${tdir}e
4808         $LFS setstripe -c 1 $TDIR
4809         createmany -o $TDIR/f $files
4810
4811         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4812
4813         # we assume that with $OSTCOUNT files, at least one of them will
4814         # be allocated on OST0.
4815         warmup_files=$((OSTCOUNT * max_dirty_mb))
4816         createmany -o $TDIR/w $warmup_files
4817
4818         # write a large amount of data into one file and sync, to get good
4819         # avail_grant number from OST.
4820         for ((i=0; i<$warmup_files; i++)); do
4821                 idx=$($LFS getstripe -i $TDIR/w$i)
4822                 [ $idx -ne 0 ] && continue
4823                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4824                 break
4825         done
4826         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4827         sync
4828         $LCTL get_param $proc_osc0/cur_dirty_bytes
4829         $LCTL get_param $proc_osc0/cur_grant_bytes
4830
4831         # create as much dirty pages as we can while not to trigger the actual
4832         # RPCs directly. but depends on the env, VFS may trigger flush during this
4833         # period, hopefully we are good.
4834         for ((i=0; i<$warmup_files; i++)); do
4835                 idx=$($LFS getstripe -i $TDIR/w$i)
4836                 [ $idx -ne 0 ] && continue
4837                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4838         done
4839         $LCTL get_param $proc_osc0/cur_dirty_bytes
4840         $LCTL get_param $proc_osc0/cur_grant_bytes
4841
4842         # perform the real test
4843         $LCTL set_param $proc_osc0/rpc_stats 0
4844         for ((;i<$files; i++)); do
4845                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4846                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4847         done
4848         sync
4849         $LCTL get_param $proc_osc0/rpc_stats
4850
4851         local percent=0
4852         local have_ppr=false
4853         $LCTL get_param $proc_osc0/rpc_stats |
4854                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4855                         # skip lines until we are at the RPC histogram data
4856                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4857                         $have_ppr || continue
4858
4859                         # we only want the percent stat for < 16 pages
4860                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4861
4862                         percent=$((percent + WPCT))
4863                         if [[ $percent -gt 15 ]]; then
4864                                 error "less than 16-pages write RPCs" \
4865                                       "$percent% > 15%"
4866                                 break
4867                         fi
4868                 done
4869         rm -rf $TDIR
4870 }
4871 run_test 42e "verify sub-RPC writes are not done synchronously"
4872
4873 test_43A() { # was test_43
4874         test_mkdir $DIR/$tdir
4875         cp -p /bin/ls $DIR/$tdir/$tfile
4876         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4877         pid=$!
4878         # give multiop a chance to open
4879         sleep 1
4880
4881         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4882         kill -USR1 $pid
4883         # Wait for multiop to exit
4884         wait $pid
4885 }
4886 run_test 43A "execution of file opened for write should return -ETXTBSY"
4887
4888 test_43a() {
4889         test_mkdir $DIR/$tdir
4890         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4891         $DIR/$tdir/sleep 60 &
4892         SLEEP_PID=$!
4893         # Make sure exec of $tdir/sleep wins race with truncate
4894         sleep 1
4895         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4896         kill $SLEEP_PID
4897 }
4898 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4899
4900 test_43b() {
4901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4902
4903         test_mkdir $DIR/$tdir
4904         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4905         $DIR/$tdir/sleep 60 &
4906         SLEEP_PID=$!
4907         # Make sure exec of $tdir/sleep wins race with truncate
4908         sleep 1
4909         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4910         kill $SLEEP_PID
4911 }
4912 run_test 43b "truncate of file being executed should return -ETXTBSY"
4913
4914 test_43c() {
4915         local testdir="$DIR/$tdir"
4916         test_mkdir $testdir
4917         cp $SHELL $testdir/
4918         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4919                 ( cd $testdir && md5sum -c )
4920 }
4921 run_test 43c "md5sum of copy into lustre"
4922
4923 test_44A() { # was test_44
4924         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4925
4926         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4927         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4928 }
4929 run_test 44A "zero length read from a sparse stripe"
4930
4931 test_44a() {
4932         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4933                 awk '{ print $2 }')
4934         [ -z "$nstripe" ] && skip "can't get stripe info"
4935         [[ $nstripe -gt $OSTCOUNT ]] &&
4936                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4937
4938         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4939                 awk '{ print $2 }')
4940         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4941                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4942                         awk '{ print $2 }')
4943         fi
4944
4945         OFFSETS="0 $((stride/2)) $((stride-1))"
4946         for offset in $OFFSETS; do
4947                 for i in $(seq 0 $((nstripe-1))); do
4948                         local GLOBALOFFSETS=""
4949                         # size in Bytes
4950                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4951                         local myfn=$DIR/d44a-$size
4952                         echo "--------writing $myfn at $size"
4953                         ll_sparseness_write $myfn $size ||
4954                                 error "ll_sparseness_write"
4955                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4956                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4957                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4958
4959                         for j in $(seq 0 $((nstripe-1))); do
4960                                 # size in Bytes
4961                                 size=$((((j + $nstripe )*$stride + $offset)))
4962                                 ll_sparseness_write $myfn $size ||
4963                                         error "ll_sparseness_write"
4964                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4965                         done
4966                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4967                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4968                         rm -f $myfn
4969                 done
4970         done
4971 }
4972 run_test 44a "test sparse pwrite ==============================="
4973
4974 dirty_osc_total() {
4975         tot=0
4976         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4977                 tot=$(($tot + $d))
4978         done
4979         echo $tot
4980 }
4981 do_dirty_record() {
4982         before=`dirty_osc_total`
4983         echo executing "\"$*\""
4984         eval $*
4985         after=`dirty_osc_total`
4986         echo before $before, after $after
4987 }
4988 test_45() {
4989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4990
4991         f="$DIR/f45"
4992         # Obtain grants from OST if it supports it
4993         echo blah > ${f}_grant
4994         stop_writeback
4995         sync
4996         do_dirty_record "echo blah > $f"
4997         [[ $before -eq $after ]] && error "write wasn't cached"
4998         do_dirty_record "> $f"
4999         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5000         do_dirty_record "echo blah > $f"
5001         [[ $before -eq $after ]] && error "write wasn't cached"
5002         do_dirty_record "sync"
5003         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5004         do_dirty_record "echo blah > $f"
5005         [[ $before -eq $after ]] && error "write wasn't cached"
5006         do_dirty_record "cancel_lru_locks osc"
5007         [[ $before -gt $after ]] ||
5008                 error "lock cancellation didn't lower dirty count"
5009         start_writeback
5010 }
5011 run_test 45 "osc io page accounting ============================"
5012
5013 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5014 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5015 # objects offset and an assert hit when an rpc was built with 1023's mapped
5016 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5017 test_46() {
5018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5019
5020         f="$DIR/f46"
5021         stop_writeback
5022         sync
5023         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5024         sync
5025         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5026         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5027         sync
5028         start_writeback
5029 }
5030 run_test 46 "dirtying a previously written page ================"
5031
5032 # test_47 is removed "Device nodes check" is moved to test_28
5033
5034 test_48a() { # bug 2399
5035         [ "$mds1_FSTYPE" = "zfs" ] &&
5036         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5037                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5038
5039         test_mkdir $DIR/$tdir
5040         cd $DIR/$tdir
5041         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5042         test_mkdir $DIR/$tdir
5043         touch foo || error "'touch foo' failed after recreating cwd"
5044         test_mkdir bar
5045         touch .foo || error "'touch .foo' failed after recreating cwd"
5046         test_mkdir .bar
5047         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5048         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5049         cd . || error "'cd .' failed after recreating cwd"
5050         mkdir . && error "'mkdir .' worked after recreating cwd"
5051         rmdir . && error "'rmdir .' worked after recreating cwd"
5052         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5053         cd .. || error "'cd ..' failed after recreating cwd"
5054 }
5055 run_test 48a "Access renamed working dir (should return errors)="
5056
5057 test_48b() { # bug 2399
5058         rm -rf $DIR/$tdir
5059         test_mkdir $DIR/$tdir
5060         cd $DIR/$tdir
5061         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5062         touch foo && error "'touch foo' worked after removing cwd"
5063         mkdir foo && error "'mkdir foo' worked after removing cwd"
5064         touch .foo && error "'touch .foo' worked after removing cwd"
5065         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5066         ls . > /dev/null && error "'ls .' worked after removing cwd"
5067         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5068         mkdir . && error "'mkdir .' worked after removing cwd"
5069         rmdir . && error "'rmdir .' worked after removing cwd"
5070         ln -s . foo && error "'ln -s .' worked after removing cwd"
5071         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5072 }
5073 run_test 48b "Access removed working dir (should return errors)="
5074
5075 test_48c() { # bug 2350
5076         #lctl set_param debug=-1
5077         #set -vx
5078         rm -rf $DIR/$tdir
5079         test_mkdir -p $DIR/$tdir/dir
5080         cd $DIR/$tdir/dir
5081         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5082         $TRACE touch foo && error "touch foo worked after removing cwd"
5083         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5084         touch .foo && error "touch .foo worked after removing cwd"
5085         mkdir .foo && error "mkdir .foo worked after removing cwd"
5086         $TRACE ls . && error "'ls .' worked after removing cwd"
5087         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5088         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5089         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5090         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5091         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5092 }
5093 run_test 48c "Access removed working subdir (should return errors)"
5094
5095 test_48d() { # bug 2350
5096         #lctl set_param debug=-1
5097         #set -vx
5098         rm -rf $DIR/$tdir
5099         test_mkdir -p $DIR/$tdir/dir
5100         cd $DIR/$tdir/dir
5101         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5102         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5103         $TRACE touch foo && error "'touch foo' worked after removing parent"
5104         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5105         touch .foo && error "'touch .foo' worked after removing parent"
5106         mkdir .foo && error "mkdir .foo worked after removing parent"
5107         $TRACE ls . && error "'ls .' worked after removing parent"
5108         $TRACE ls .. && error "'ls ..' worked after removing parent"
5109         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5110         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5111         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5112         true
5113 }
5114 run_test 48d "Access removed parent subdir (should return errors)"
5115
5116 test_48e() { # bug 4134
5117         #lctl set_param debug=-1
5118         #set -vx
5119         rm -rf $DIR/$tdir
5120         test_mkdir -p $DIR/$tdir/dir
5121         cd $DIR/$tdir/dir
5122         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5123         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5124         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5125         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5126         # On a buggy kernel addition of "touch foo" after cd .. will
5127         # produce kernel oops in lookup_hash_it
5128         touch ../foo && error "'cd ..' worked after recreate parent"
5129         cd $DIR
5130         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5131 }
5132 run_test 48e "Access to recreated parent subdir (should return errors)"
5133
5134 test_48f() {
5135         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5136                 skip "need MDS >= 2.13.55"
5137         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5138         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5139                 skip "needs different host for mdt1 mdt2"
5140         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5141
5142         $LFS mkdir -i0 $DIR/$tdir
5143         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5144
5145         for d in sub1 sub2 sub3; do
5146                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5147                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5148                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5149         done
5150
5151         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5152 }
5153 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5154
5155 test_49() { # LU-1030
5156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5157         remote_ost_nodsh && skip "remote OST with nodsh"
5158
5159         # get ost1 size - $FSNAME-OST0000
5160         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5161                 awk '{ print $4 }')
5162         # write 800M at maximum
5163         [[ $ost1_size -lt 2 ]] && ost1_size=2
5164         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5165
5166         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5167         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5168         local dd_pid=$!
5169
5170         # change max_pages_per_rpc while writing the file
5171         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5172         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5173         # loop until dd process exits
5174         while ps ax -opid | grep -wq $dd_pid; do
5175                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5176                 sleep $((RANDOM % 5 + 1))
5177         done
5178         # restore original max_pages_per_rpc
5179         $LCTL set_param $osc1_mppc=$orig_mppc
5180         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5181 }
5182 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5183
5184 test_50() {
5185         # bug 1485
5186         test_mkdir $DIR/$tdir
5187         cd $DIR/$tdir
5188         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5189 }
5190 run_test 50 "special situations: /proc symlinks  ==============="
5191
5192 test_51a() {    # was test_51
5193         # bug 1516 - create an empty entry right after ".." then split dir
5194         test_mkdir -c1 $DIR/$tdir
5195         touch $DIR/$tdir/foo
5196         $MCREATE $DIR/$tdir/bar
5197         rm $DIR/$tdir/foo
5198         createmany -m $DIR/$tdir/longfile 201
5199         FNUM=202
5200         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5201                 $MCREATE $DIR/$tdir/longfile$FNUM
5202                 FNUM=$(($FNUM + 1))
5203                 echo -n "+"
5204         done
5205         echo
5206         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5207 }
5208 run_test 51a "special situations: split htree with empty entry =="
5209
5210 cleanup_print_lfs_df () {
5211         trap 0
5212         $LFS df
5213         $LFS df -i
5214 }
5215
5216 test_51b() {
5217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5218
5219         local dir=$DIR/$tdir
5220         local nrdirs=$((65536 + 100))
5221
5222         # cleanup the directory
5223         rm -fr $dir
5224
5225         test_mkdir -c1 $dir
5226
5227         $LFS df
5228         $LFS df -i
5229         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5230         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5231         [[ $numfree -lt $nrdirs ]] &&
5232                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5233
5234         # need to check free space for the directories as well
5235         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5236         numfree=$(( blkfree / $(fs_inode_ksize) ))
5237         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5238
5239         trap cleanup_print_lfs_df EXIT
5240
5241         # create files
5242         createmany -d $dir/d $nrdirs || {
5243                 unlinkmany $dir/d $nrdirs
5244                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5245         }
5246
5247         # really created :
5248         nrdirs=$(ls -U $dir | wc -l)
5249
5250         # unlink all but 100 subdirectories, then check it still works
5251         local left=100
5252         local delete=$((nrdirs - left))
5253
5254         $LFS df
5255         $LFS df -i
5256
5257         # for ldiskfs the nlink count should be 1, but this is OSD specific
5258         # and so this is listed for informational purposes only
5259         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5260         unlinkmany -d $dir/d $delete ||
5261                 error "unlink of first $delete subdirs failed"
5262
5263         echo "nlink between: $(stat -c %h $dir)"
5264         local found=$(ls -U $dir | wc -l)
5265         [ $found -ne $left ] &&
5266                 error "can't find subdirs: found only $found, expected $left"
5267
5268         unlinkmany -d $dir/d $delete $left ||
5269                 error "unlink of second $left subdirs failed"
5270         # regardless of whether the backing filesystem tracks nlink accurately
5271         # or not, the nlink count shouldn't be more than "." and ".." here
5272         local after=$(stat -c %h $dir)
5273         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5274                 echo "nlink after: $after"
5275
5276         cleanup_print_lfs_df
5277 }
5278 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5279
5280 test_51d() {
5281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5282         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5283
5284         test_mkdir $DIR/$tdir
5285         createmany -o $DIR/$tdir/t- 1000
5286         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5287         for N in $(seq 0 $((OSTCOUNT - 1))); do
5288                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5289                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5290                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5291                         '($1 == '$N') { objs += 1 } \
5292                         END { printf("%0.0f", objs) }')
5293                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5294         done
5295         unlinkmany $DIR/$tdir/t- 1000
5296
5297         NLAST=0
5298         for N in $(seq 1 $((OSTCOUNT - 1))); do
5299                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5300                         error "OST $N has less objects vs OST $NLAST" \
5301                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5302                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5303                         error "OST $N has less objects vs OST $NLAST" \
5304                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5305
5306                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5307                         error "OST $N has less #0 objects vs OST $NLAST" \
5308                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5309                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5310                         error "OST $N has less #0 objects vs OST $NLAST" \
5311                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5312                 NLAST=$N
5313         done
5314         rm -f $TMP/$tfile
5315 }
5316 run_test 51d "check object distribution"
5317
5318 test_51e() {
5319         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5320                 skip_env "ldiskfs only test"
5321         fi
5322
5323         test_mkdir -c1 $DIR/$tdir
5324         test_mkdir -c1 $DIR/$tdir/d0
5325
5326         touch $DIR/$tdir/d0/foo
5327         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5328                 error "file exceed 65000 nlink limit!"
5329         unlinkmany $DIR/$tdir/d0/f- 65001
5330         return 0
5331 }
5332 run_test 51e "check file nlink limit"
5333
5334 test_51f() {
5335         test_mkdir $DIR/$tdir
5336
5337         local max=100000
5338         local ulimit_old=$(ulimit -n)
5339         local spare=20 # number of spare fd's for scripts/libraries, etc.
5340         local mdt=$($LFS getstripe -m $DIR/$tdir)
5341         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5342
5343         echo "MDT$mdt numfree=$numfree, max=$max"
5344         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5345         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5346                 while ! ulimit -n $((numfree + spare)); do
5347                         numfree=$((numfree * 3 / 4))
5348                 done
5349                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5350         else
5351                 echo "left ulimit at $ulimit_old"
5352         fi
5353
5354         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5355                 unlinkmany $DIR/$tdir/f $numfree
5356                 error "create+open $numfree files in $DIR/$tdir failed"
5357         }
5358         ulimit -n $ulimit_old
5359
5360         # if createmany exits at 120s there will be fewer than $numfree files
5361         unlinkmany $DIR/$tdir/f $numfree || true
5362 }
5363 run_test 51f "check many open files limit"
5364
5365 test_52a() {
5366         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5367         test_mkdir $DIR/$tdir
5368         touch $DIR/$tdir/foo
5369         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5370         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5371         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5372         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5373         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5374                                         error "link worked"
5375         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5376         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5377         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5378                                                      error "lsattr"
5379         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5380         cp -r $DIR/$tdir $TMP/
5381         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5382 }
5383 run_test 52a "append-only flag test (should return errors)"
5384
5385 test_52b() {
5386         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5387         test_mkdir $DIR/$tdir
5388         touch $DIR/$tdir/foo
5389         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5390         cat test > $DIR/$tdir/foo && error "cat test worked"
5391         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5392         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5393         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5394                                         error "link worked"
5395         echo foo >> $DIR/$tdir/foo && error "echo worked"
5396         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5397         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5398         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5399         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5400                                                         error "lsattr"
5401         chattr -i $DIR/$tdir/foo || error "chattr failed"
5402
5403         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5404 }
5405 run_test 52b "immutable flag test (should return errors) ======="
5406
5407 test_53() {
5408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5409         remote_mds_nodsh && skip "remote MDS with nodsh"
5410         remote_ost_nodsh && skip "remote OST with nodsh"
5411
5412         local param
5413         local param_seq
5414         local ostname
5415         local mds_last
5416         local mds_last_seq
5417         local ost_last
5418         local ost_last_seq
5419         local ost_last_id
5420         local ostnum
5421         local node
5422         local found=false
5423         local support_last_seq=true
5424
5425         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5426                 support_last_seq=false
5427
5428         # only test MDT0000
5429         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5430         local value
5431         for value in $(do_facet $SINGLEMDS \
5432                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5433                 param=$(echo ${value[0]} | cut -d "=" -f1)
5434                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5435
5436                 if $support_last_seq; then
5437                         param_seq=$(echo $param |
5438                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5439                         mds_last_seq=$(do_facet $SINGLEMDS \
5440                                        $LCTL get_param -n $param_seq)
5441                 fi
5442                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5443
5444                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5445                 node=$(facet_active_host ost$((ostnum+1)))
5446                 param="obdfilter.$ostname.last_id"
5447                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5448                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5449                         ost_last_id=$ost_last
5450
5451                         if $support_last_seq; then
5452                                 ost_last_id=$(echo $ost_last |
5453                                               awk -F':' '{print $2}' |
5454                                               sed -e "s/^0x//g")
5455                                 ost_last_seq=$(echo $ost_last |
5456                                                awk -F':' '{print $1}')
5457                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5458                         fi
5459
5460                         if [[ $ost_last_id != $mds_last ]]; then
5461                                 error "$ost_last_id != $mds_last"
5462                         else
5463                                 found=true
5464                                 break
5465                         fi
5466                 done
5467         done
5468         $found || error "can not match last_seq/last_id for $mdtosc"
5469         return 0
5470 }
5471 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5472
5473 test_54a() {
5474         perl -MSocket -e ';' || skip "no Socket perl module installed"
5475
5476         $SOCKETSERVER $DIR/socket ||
5477                 error "$SOCKETSERVER $DIR/socket failed: $?"
5478         $SOCKETCLIENT $DIR/socket ||
5479                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5480         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5481 }
5482 run_test 54a "unix domain socket test =========================="
5483
5484 test_54b() {
5485         f="$DIR/f54b"
5486         mknod $f c 1 3
5487         chmod 0666 $f
5488         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5489 }
5490 run_test 54b "char device works in lustre ======================"
5491
5492 find_loop_dev() {
5493         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5494         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5495         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5496
5497         for i in $(seq 3 7); do
5498                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5499                 LOOPDEV=$LOOPBASE$i
5500                 LOOPNUM=$i
5501                 break
5502         done
5503 }
5504
5505 cleanup_54c() {
5506         local rc=0
5507         loopdev="$DIR/loop54c"
5508
5509         trap 0
5510         $UMOUNT $DIR/$tdir || rc=$?
5511         losetup -d $loopdev || true
5512         losetup -d $LOOPDEV || true
5513         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5514         return $rc
5515 }
5516
5517 test_54c() {
5518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5519
5520         loopdev="$DIR/loop54c"
5521
5522         find_loop_dev
5523         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5524         trap cleanup_54c EXIT
5525         mknod $loopdev b 7 $LOOPNUM
5526         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5527         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5528         losetup $loopdev $DIR/$tfile ||
5529                 error "can't set up $loopdev for $DIR/$tfile"
5530         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5531         test_mkdir $DIR/$tdir
5532         mount -t ext2 $loopdev $DIR/$tdir ||
5533                 error "error mounting $loopdev on $DIR/$tdir"
5534         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5535                 error "dd write"
5536         df $DIR/$tdir
5537         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5538                 error "dd read"
5539         cleanup_54c
5540 }
5541 run_test 54c "block device works in lustre ====================="
5542
5543 test_54d() {
5544         f="$DIR/f54d"
5545         string="aaaaaa"
5546         mknod $f p
5547         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5548 }
5549 run_test 54d "fifo device works in lustre ======================"
5550
5551 test_54e() {
5552         f="$DIR/f54e"
5553         string="aaaaaa"
5554         cp -aL /dev/console $f
5555         echo $string > $f || error "echo $string to $f failed"
5556 }
5557 run_test 54e "console/tty device works in lustre ======================"
5558
5559 test_56a() {
5560         local numfiles=3
5561         local dir=$DIR/$tdir
5562
5563         rm -rf $dir
5564         test_mkdir -p $dir/dir
5565         for i in $(seq $numfiles); do
5566                 touch $dir/file$i
5567                 touch $dir/dir/file$i
5568         done
5569
5570         local numcomp=$($LFS getstripe --component-count $dir)
5571
5572         [[ $numcomp == 0 ]] && numcomp=1
5573
5574         # test lfs getstripe with --recursive
5575         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5576
5577         [[ $filenum -eq $((numfiles * 2)) ]] ||
5578                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5579         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5580         [[ $filenum -eq $numfiles ]] ||
5581                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5582         echo "$LFS getstripe showed obdidx or l_ost_idx"
5583
5584         # test lfs getstripe with file instead of dir
5585         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5586         [[ $filenum -eq 1 ]] ||
5587                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5588         echo "$LFS getstripe file1 passed"
5589
5590         #test lfs getstripe with --verbose
5591         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5592         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5593                 error "$LFS getstripe --verbose $dir: "\
5594                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5595         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5596                 error "$LFS getstripe $dir: showed lmm_magic"
5597
5598         #test lfs getstripe with -v prints lmm_fid
5599         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5600         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5601                 error "$LFS getstripe -v $dir: "\
5602                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5603         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5604                 error "$LFS getstripe $dir: showed lmm_fid by default"
5605         echo "$LFS getstripe --verbose passed"
5606
5607         #check for FID information
5608         local fid1=$($LFS getstripe --fid $dir/file1)
5609         local fid2=$($LFS getstripe --verbose $dir/file1 |
5610                      awk '/lmm_fid: / { print $2; exit; }')
5611         local fid3=$($LFS path2fid $dir/file1)
5612
5613         [ "$fid1" != "$fid2" ] &&
5614                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5615         [ "$fid1" != "$fid3" ] &&
5616                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5617         echo "$LFS getstripe --fid passed"
5618
5619         #test lfs getstripe with --obd
5620         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5621                 error "$LFS getstripe --obd wrong_uuid: should return error"
5622
5623         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5624
5625         local ostidx=1
5626         local obduuid=$(ostuuid_from_index $ostidx)
5627         local found=$($LFS getstripe -r --obd $obduuid $dir |
5628                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5629
5630         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5631         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5632                 ((filenum--))
5633         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5634                 ((filenum--))
5635
5636         [[ $found -eq $filenum ]] ||
5637                 error "$LFS getstripe --obd: found $found expect $filenum"
5638         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5639                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5640                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5641                 error "$LFS getstripe --obd: should not show file on other obd"
5642         echo "$LFS getstripe --obd passed"
5643 }
5644 run_test 56a "check $LFS getstripe"
5645
5646 test_56b() {
5647         local dir=$DIR/$tdir
5648         local numdirs=3
5649
5650         test_mkdir $dir
5651         for i in $(seq $numdirs); do
5652                 test_mkdir $dir/dir$i
5653         done
5654
5655         # test lfs getdirstripe default mode is non-recursion, which is
5656         # different from lfs getstripe
5657         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5658
5659         [[ $dircnt -eq 1 ]] ||
5660                 error "$LFS getdirstripe: found $dircnt, not 1"
5661         dircnt=$($LFS getdirstripe --recursive $dir |
5662                 grep -c lmv_stripe_count)
5663         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5664                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5665 }
5666 run_test 56b "check $LFS getdirstripe"
5667
5668 test_56c() {
5669         remote_ost_nodsh && skip "remote OST with nodsh"
5670
5671         local ost_idx=0
5672         local ost_name=$(ostname_from_index $ost_idx)
5673         local old_status=$(ost_dev_status $ost_idx)
5674         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5675
5676         [[ -z "$old_status" ]] ||
5677                 skip_env "OST $ost_name is in $old_status status"
5678
5679         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5680         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5681                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5682         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5683                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5684                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5685         fi
5686
5687         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5688                 error "$LFS df -v showing inactive devices"
5689         sleep_maxage
5690
5691         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5692
5693         [[ "$new_status" =~ "D" ]] ||
5694                 error "$ost_name status is '$new_status', missing 'D'"
5695         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5696                 [[ "$new_status" =~ "N" ]] ||
5697                         error "$ost_name status is '$new_status', missing 'N'"
5698         fi
5699         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5700                 [[ "$new_status" =~ "f" ]] ||
5701                         error "$ost_name status is '$new_status', missing 'f'"
5702         fi
5703
5704         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5705         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5706                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5707         [[ -z "$p" ]] && restore_lustre_params < $p || true
5708         sleep_maxage
5709
5710         new_status=$(ost_dev_status $ost_idx)
5711         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5712                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5713         # can't check 'f' as devices may actually be on flash
5714 }
5715 run_test 56c "check 'lfs df' showing device status"
5716
5717 test_56d() {
5718         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5719         local osts=$($LFS df -v $MOUNT | grep -c OST)
5720
5721         $LFS df $MOUNT
5722
5723         (( mdts == MDSCOUNT )) ||
5724                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5725         (( osts == OSTCOUNT )) ||
5726                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5727 }
5728 run_test 56d "'lfs df -v' prints only configured devices"
5729
5730 NUMFILES=3
5731 NUMDIRS=3
5732 setup_56() {
5733         local local_tdir="$1"
5734         local local_numfiles="$2"
5735         local local_numdirs="$3"
5736         local dir_params="$4"
5737         local dir_stripe_params="$5"
5738
5739         if [ ! -d "$local_tdir" ] ; then
5740                 test_mkdir -p $dir_stripe_params $local_tdir
5741                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5742                 for i in $(seq $local_numfiles) ; do
5743                         touch $local_tdir/file$i
5744                 done
5745                 for i in $(seq $local_numdirs) ; do
5746                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5747                         for j in $(seq $local_numfiles) ; do
5748                                 touch $local_tdir/dir$i/file$j
5749                         done
5750                 done
5751         fi
5752 }
5753
5754 setup_56_special() {
5755         local local_tdir=$1
5756         local local_numfiles=$2
5757         local local_numdirs=$3
5758
5759         setup_56 $local_tdir $local_numfiles $local_numdirs
5760
5761         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5762                 for i in $(seq $local_numfiles) ; do
5763                         mknod $local_tdir/loop${i}b b 7 $i
5764                         mknod $local_tdir/null${i}c c 1 3
5765                         ln -s $local_tdir/file1 $local_tdir/link${i}
5766                 done
5767                 for i in $(seq $local_numdirs) ; do
5768                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5769                         mknod $local_tdir/dir$i/null${i}c c 1 3
5770                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5771                 done
5772         fi
5773 }
5774
5775 test_56g() {
5776         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5777         local expected=$(($NUMDIRS + 2))
5778
5779         setup_56 $dir $NUMFILES $NUMDIRS
5780
5781         # test lfs find with -name
5782         for i in $(seq $NUMFILES) ; do
5783                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5784
5785                 [ $nums -eq $expected ] ||
5786                         error "lfs find -name '*$i' $dir wrong: "\
5787                               "found $nums, expected $expected"
5788         done
5789 }
5790 run_test 56g "check lfs find -name"
5791
5792 test_56h() {
5793         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5794         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5795
5796         setup_56 $dir $NUMFILES $NUMDIRS
5797
5798         # test lfs find with ! -name
5799         for i in $(seq $NUMFILES) ; do
5800                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5801
5802                 [ $nums -eq $expected ] ||
5803                         error "lfs find ! -name '*$i' $dir wrong: "\
5804                               "found $nums, expected $expected"
5805         done
5806 }
5807 run_test 56h "check lfs find ! -name"
5808
5809 test_56i() {
5810         local dir=$DIR/$tdir
5811
5812         test_mkdir $dir
5813
5814         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5815         local out=$($cmd)
5816
5817         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5818 }
5819 run_test 56i "check 'lfs find -ost UUID' skips directories"
5820
5821 test_56j() {
5822         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5823
5824         setup_56_special $dir $NUMFILES $NUMDIRS
5825
5826         local expected=$((NUMDIRS + 1))
5827         local cmd="$LFS find -type d $dir"
5828         local nums=$($cmd | wc -l)
5829
5830         [ $nums -eq $expected ] ||
5831                 error "'$cmd' wrong: found $nums, expected $expected"
5832 }
5833 run_test 56j "check lfs find -type d"
5834
5835 test_56k() {
5836         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5837
5838         setup_56_special $dir $NUMFILES $NUMDIRS
5839
5840         local expected=$(((NUMDIRS + 1) * NUMFILES))
5841         local cmd="$LFS find -type f $dir"
5842         local nums=$($cmd | wc -l)
5843
5844         [ $nums -eq $expected ] ||
5845                 error "'$cmd' wrong: found $nums, expected $expected"
5846 }
5847 run_test 56k "check lfs find -type f"
5848
5849 test_56l() {
5850         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5851
5852         setup_56_special $dir $NUMFILES $NUMDIRS
5853
5854         local expected=$((NUMDIRS + NUMFILES))
5855         local cmd="$LFS find -type b $dir"
5856         local nums=$($cmd | wc -l)
5857
5858         [ $nums -eq $expected ] ||
5859                 error "'$cmd' wrong: found $nums, expected $expected"
5860 }
5861 run_test 56l "check lfs find -type b"
5862
5863 test_56m() {
5864         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5865
5866         setup_56_special $dir $NUMFILES $NUMDIRS
5867
5868         local expected=$((NUMDIRS + NUMFILES))
5869         local cmd="$LFS find -type c $dir"
5870         local nums=$($cmd | wc -l)
5871         [ $nums -eq $expected ] ||
5872                 error "'$cmd' wrong: found $nums, expected $expected"
5873 }
5874 run_test 56m "check lfs find -type c"
5875
5876 test_56n() {
5877         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5878         setup_56_special $dir $NUMFILES $NUMDIRS
5879
5880         local expected=$((NUMDIRS + NUMFILES))
5881         local cmd="$LFS find -type l $dir"
5882         local nums=$($cmd | wc -l)
5883
5884         [ $nums -eq $expected ] ||
5885                 error "'$cmd' wrong: found $nums, expected $expected"
5886 }
5887 run_test 56n "check lfs find -type l"
5888
5889 test_56o() {
5890         local dir=$DIR/$tdir
5891
5892         setup_56 $dir $NUMFILES $NUMDIRS
5893         utime $dir/file1 > /dev/null || error "utime (1)"
5894         utime $dir/file2 > /dev/null || error "utime (2)"
5895         utime $dir/dir1 > /dev/null || error "utime (3)"
5896         utime $dir/dir2 > /dev/null || error "utime (4)"
5897         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5898         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5899
5900         local expected=4
5901         local nums=$($LFS find -mtime +0 $dir | wc -l)
5902
5903         [ $nums -eq $expected ] ||
5904                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5905
5906         expected=12
5907         cmd="$LFS find -mtime 0 $dir"
5908         nums=$($cmd | wc -l)
5909         [ $nums -eq $expected ] ||
5910                 error "'$cmd' wrong: found $nums, expected $expected"
5911 }
5912 run_test 56o "check lfs find -mtime for old files"
5913
5914 test_56ob() {
5915         local dir=$DIR/$tdir
5916         local expected=1
5917         local count=0
5918
5919         # just to make sure there is something that won't be found
5920         test_mkdir $dir
5921         touch $dir/$tfile.now
5922
5923         for age in year week day hour min; do
5924                 count=$((count + 1))
5925
5926                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5927                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5928                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5929
5930                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5931                 local nums=$($cmd | wc -l)
5932                 [ $nums -eq $expected ] ||
5933                         error "'$cmd' wrong: found $nums, expected $expected"
5934
5935                 cmd="$LFS find $dir -atime $count${age:0:1}"
5936                 nums=$($cmd | wc -l)
5937                 [ $nums -eq $expected ] ||
5938                         error "'$cmd' wrong: found $nums, expected $expected"
5939         done
5940
5941         sleep 2
5942         cmd="$LFS find $dir -ctime +1s -type f"
5943         nums=$($cmd | wc -l)
5944         (( $nums == $count * 2 + 1)) ||
5945                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
5946 }
5947 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5948
5949 test_newerXY_base() {
5950         local x=$1
5951         local y=$2
5952         local dir=$DIR/$tdir
5953         local ref
5954         local negref
5955
5956         if [ $y == "t" ]; then
5957                 if [ $x == "b" ]; then
5958                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5959                 else
5960                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5961                 fi
5962         else
5963                 ref=$DIR/$tfile.newer.$x$y
5964                 touch $ref || error "touch $ref failed"
5965         fi
5966         sleep 2
5967         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5968         sleep 2
5969         if [ $y == "t" ]; then
5970                 if [ $x == "b" ]; then
5971                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5972                 else
5973                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5974                 fi
5975         else
5976                 negref=$DIR/$tfile.negnewer.$x$y
5977                 touch $negref || error "touch $negref failed"
5978         fi
5979
5980         local cmd="$LFS find $dir -newer$x$y $ref"
5981         local nums=$(eval $cmd | wc -l)
5982         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5983
5984         [ $nums -eq $expected ] ||
5985                 error "'$cmd' wrong: found $nums, expected $expected"
5986
5987         cmd="$LFS find $dir ! -newer$x$y $negref"
5988         nums=$(eval $cmd | wc -l)
5989         [ $nums -eq $expected ] ||
5990                 error "'$cmd' wrong: found $nums, expected $expected"
5991
5992         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
5993         nums=$(eval $cmd | wc -l)
5994         [ $nums -eq $expected ] ||
5995                 error "'$cmd' wrong: found $nums, expected $expected"
5996
5997         rm -rf $DIR/*
5998 }
5999
6000 test_56oc() {
6001         test_newerXY_base "b" "t"
6002         test_newerXY_base "a" "a"
6003         test_newerXY_base "a" "m"
6004         test_newerXY_base "a" "c"
6005         test_newerXY_base "m" "a"
6006         test_newerXY_base "m" "m"
6007         test_newerXY_base "m" "c"
6008         test_newerXY_base "c" "a"
6009         test_newerXY_base "c" "m"
6010         test_newerXY_base "c" "c"
6011         test_newerXY_base "b" "b"
6012         test_newerXY_base "a" "t"
6013         test_newerXY_base "m" "t"
6014         test_newerXY_base "c" "t"
6015         test_newerXY_base "b" "t"
6016 }
6017 run_test 56oc "check lfs find -newerXY work"
6018
6019 btime_supported() {
6020         local dir=$DIR/$tdir
6021         local rc
6022
6023         mkdir -p $dir
6024         touch $dir/$tfile
6025         $LFS find $dir -btime -1d -type f
6026         rc=$?
6027         rm -rf $dir
6028         return $rc
6029 }
6030
6031 test_56od() {
6032         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6033                 ! btime_supported && skip "btime unsupported on MDS"
6034
6035         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6036                 ! btime_supported && skip "btime unsupported on clients"
6037
6038         local dir=$DIR/$tdir
6039         local ref=$DIR/$tfile.ref
6040         local negref=$DIR/$tfile.negref
6041
6042         mkdir $dir || error "mkdir $dir failed"
6043         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6044         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6045         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6046         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6047         touch $ref || error "touch $ref failed"
6048         # sleep 3 seconds at least
6049         sleep 3
6050
6051         local before=$(do_facet mds1 date +%s)
6052         local skew=$(($(date +%s) - before + 1))
6053
6054         if (( skew < 0 && skew > -5 )); then
6055                 sleep $((0 - skew + 1))
6056                 skew=0
6057         fi
6058
6059         # Set the dir stripe params to limit files all on MDT0,
6060         # otherwise we need to calc the max clock skew between
6061         # the client and MDTs.
6062         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6063         sleep 2
6064         touch $negref || error "touch $negref failed"
6065
6066         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6067         local nums=$($cmd | wc -l)
6068         local expected=$(((NUMFILES + 1) * NUMDIRS))
6069
6070         [ $nums -eq $expected ] ||
6071                 error "'$cmd' wrong: found $nums, expected $expected"
6072
6073         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6074         nums=$($cmd | wc -l)
6075         expected=$((NUMFILES + 1))
6076         [ $nums -eq $expected ] ||
6077                 error "'$cmd' wrong: found $nums, expected $expected"
6078
6079         [ $skew -lt 0 ] && return
6080
6081         local after=$(do_facet mds1 date +%s)
6082         local age=$((after - before + 1 + skew))
6083
6084         cmd="$LFS find $dir -btime -${age}s -type f"
6085         nums=$($cmd | wc -l)
6086         expected=$(((NUMFILES + 1) * NUMDIRS))
6087
6088         echo "Clock skew between client and server: $skew, age:$age"
6089         [ $nums -eq $expected ] ||
6090                 error "'$cmd' wrong: found $nums, expected $expected"
6091
6092         expected=$(($NUMDIRS + 1))
6093         cmd="$LFS find $dir -btime -${age}s -type d"
6094         nums=$($cmd | wc -l)
6095         [ $nums -eq $expected ] ||
6096                 error "'$cmd' wrong: found $nums, expected $expected"
6097         rm -f $ref $negref || error "Failed to remove $ref $negref"
6098 }
6099 run_test 56od "check lfs find -btime with units"
6100
6101 test_56p() {
6102         [ $RUNAS_ID -eq $UID ] &&
6103                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6104
6105         local dir=$DIR/$tdir
6106
6107         setup_56 $dir $NUMFILES $NUMDIRS
6108         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6109
6110         local expected=$NUMFILES
6111         local cmd="$LFS find -uid $RUNAS_ID $dir"
6112         local nums=$($cmd | wc -l)
6113
6114         [ $nums -eq $expected ] ||
6115                 error "'$cmd' wrong: found $nums, expected $expected"
6116
6117         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6118         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6119         nums=$($cmd | wc -l)
6120         [ $nums -eq $expected ] ||
6121                 error "'$cmd' wrong: found $nums, expected $expected"
6122 }
6123 run_test 56p "check lfs find -uid and ! -uid"
6124
6125 test_56q() {
6126         [ $RUNAS_ID -eq $UID ] &&
6127                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6128
6129         local dir=$DIR/$tdir
6130
6131         setup_56 $dir $NUMFILES $NUMDIRS
6132         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6133
6134         local expected=$NUMFILES
6135         local cmd="$LFS find -gid $RUNAS_GID $dir"
6136         local nums=$($cmd | wc -l)
6137
6138         [ $nums -eq $expected ] ||
6139                 error "'$cmd' wrong: found $nums, expected $expected"
6140
6141         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6142         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6143         nums=$($cmd | wc -l)
6144         [ $nums -eq $expected ] ||
6145                 error "'$cmd' wrong: found $nums, expected $expected"
6146 }
6147 run_test 56q "check lfs find -gid and ! -gid"
6148
6149 test_56r() {
6150         local dir=$DIR/$tdir
6151
6152         setup_56 $dir $NUMFILES $NUMDIRS
6153
6154         local expected=12
6155         local cmd="$LFS find -size 0 -type f -lazy $dir"
6156         local nums=$($cmd | wc -l)
6157
6158         [ $nums -eq $expected ] ||
6159                 error "'$cmd' wrong: found $nums, expected $expected"
6160         cmd="$LFS find -size 0 -type f $dir"
6161         nums=$($cmd | wc -l)
6162         [ $nums -eq $expected ] ||
6163                 error "'$cmd' wrong: found $nums, expected $expected"
6164
6165         expected=0
6166         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6167         nums=$($cmd | wc -l)
6168         [ $nums -eq $expected ] ||
6169                 error "'$cmd' wrong: found $nums, expected $expected"
6170         cmd="$LFS find ! -size 0 -type f $dir"
6171         nums=$($cmd | wc -l)
6172         [ $nums -eq $expected ] ||
6173                 error "'$cmd' wrong: found $nums, expected $expected"
6174
6175         echo "test" > $dir/$tfile
6176         echo "test2" > $dir/$tfile.2 && sync
6177         expected=1
6178         cmd="$LFS find -size 5 -type f -lazy $dir"
6179         nums=$($cmd | wc -l)
6180         [ $nums -eq $expected ] ||
6181                 error "'$cmd' wrong: found $nums, expected $expected"
6182         cmd="$LFS find -size 5 -type f $dir"
6183         nums=$($cmd | wc -l)
6184         [ $nums -eq $expected ] ||
6185                 error "'$cmd' wrong: found $nums, expected $expected"
6186
6187         expected=1
6188         cmd="$LFS find -size +5 -type f -lazy $dir"
6189         nums=$($cmd | wc -l)
6190         [ $nums -eq $expected ] ||
6191                 error "'$cmd' wrong: found $nums, expected $expected"
6192         cmd="$LFS find -size +5 -type f $dir"
6193         nums=$($cmd | wc -l)
6194         [ $nums -eq $expected ] ||
6195                 error "'$cmd' wrong: found $nums, expected $expected"
6196
6197         expected=2
6198         cmd="$LFS find -size +0 -type f -lazy $dir"
6199         nums=$($cmd | wc -l)
6200         [ $nums -eq $expected ] ||
6201                 error "'$cmd' wrong: found $nums, expected $expected"
6202         cmd="$LFS find -size +0 -type f $dir"
6203         nums=$($cmd | wc -l)
6204         [ $nums -eq $expected ] ||
6205                 error "'$cmd' wrong: found $nums, expected $expected"
6206
6207         expected=2
6208         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6209         nums=$($cmd | wc -l)
6210         [ $nums -eq $expected ] ||
6211                 error "'$cmd' wrong: found $nums, expected $expected"
6212         cmd="$LFS find ! -size -5 -type f $dir"
6213         nums=$($cmd | wc -l)
6214         [ $nums -eq $expected ] ||
6215                 error "'$cmd' wrong: found $nums, expected $expected"
6216
6217         expected=12
6218         cmd="$LFS find -size -5 -type f -lazy $dir"
6219         nums=$($cmd | wc -l)
6220         [ $nums -eq $expected ] ||
6221                 error "'$cmd' wrong: found $nums, expected $expected"
6222         cmd="$LFS find -size -5 -type f $dir"
6223         nums=$($cmd | wc -l)
6224         [ $nums -eq $expected ] ||
6225                 error "'$cmd' wrong: found $nums, expected $expected"
6226 }
6227 run_test 56r "check lfs find -size works"
6228
6229 test_56ra_sub() {
6230         local expected=$1
6231         local glimpses=$2
6232         local cmd="$3"
6233
6234         cancel_lru_locks $OSC
6235
6236         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6237         local nums=$($cmd | wc -l)
6238
6239         [ $nums -eq $expected ] ||
6240                 error "'$cmd' wrong: found $nums, expected $expected"
6241
6242         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6243
6244         if (( rpcs_before + glimpses != rpcs_after )); then
6245                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6246                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6247
6248                 if [[ $glimpses == 0 ]]; then
6249                         error "'$cmd' should not send glimpse RPCs to OST"
6250                 else
6251                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6252                 fi
6253         fi
6254 }
6255
6256 test_56ra() {
6257         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6258                 skip "MDS < 2.12.58 doesn't return LSOM data"
6259         local dir=$DIR/$tdir
6260
6261         [[ $OSC == "mdc" ]] && skip "DoM files" && return
6262
6263         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6264         # open and close all files to ensure LSOM is updated
6265         cancel_lru_locks $OSC
6266         find $dir -type f | xargs cat > /dev/null
6267
6268         #   expect_found  glimpse_rpcs  command_to_run
6269         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6270         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6271         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6272         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6273
6274         echo "test" > $dir/$tfile
6275         echo "test2" > $dir/$tfile.2 && sync
6276         cancel_lru_locks $OSC
6277         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6278
6279         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6280         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6281         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6282         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6283
6284         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6285         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6286         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6287         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6288         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6289         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6290 }
6291 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6292
6293 test_56rb() {
6294         local dir=$DIR/$tdir
6295         local tmp=$TMP/$tfile.log
6296         local mdt_idx;
6297
6298         test_mkdir -p $dir || error "failed to mkdir $dir"
6299         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6300                 error "failed to setstripe $dir/$tfile"
6301         mdt_idx=$($LFS getdirstripe -i $dir)
6302         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6303
6304         stack_trap "rm -f $tmp" EXIT
6305         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6306         ! grep -q obd_uuid $tmp ||
6307                 error "failed to find --size +100K --ost 0 $dir"
6308         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6309         ! grep -q obd_uuid $tmp ||
6310                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6311 }
6312 run_test 56rb "check lfs find --size --ost/--mdt works"
6313
6314 test_56s() { # LU-611 #LU-9369
6315         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6316
6317         local dir=$DIR/$tdir
6318         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6319
6320         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6321         for i in $(seq $NUMDIRS); do
6322                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6323         done
6324
6325         local expected=$NUMDIRS
6326         local cmd="$LFS find -c $OSTCOUNT $dir"
6327         local nums=$($cmd | wc -l)
6328
6329         [ $nums -eq $expected ] || {
6330                 $LFS getstripe -R $dir
6331                 error "'$cmd' wrong: found $nums, expected $expected"
6332         }
6333
6334         expected=$((NUMDIRS + onestripe))
6335         cmd="$LFS find -stripe-count +0 -type f $dir"
6336         nums=$($cmd | wc -l)
6337         [ $nums -eq $expected ] || {
6338                 $LFS getstripe -R $dir
6339                 error "'$cmd' wrong: found $nums, expected $expected"
6340         }
6341
6342         expected=$onestripe
6343         cmd="$LFS find -stripe-count 1 -type f $dir"
6344         nums=$($cmd | wc -l)
6345         [ $nums -eq $expected ] || {
6346                 $LFS getstripe -R $dir
6347                 error "'$cmd' wrong: found $nums, expected $expected"
6348         }
6349
6350         cmd="$LFS find -stripe-count -2 -type f $dir"
6351         nums=$($cmd | wc -l)
6352         [ $nums -eq $expected ] || {
6353                 $LFS getstripe -R $dir
6354                 error "'$cmd' wrong: found $nums, expected $expected"
6355         }
6356
6357         expected=0
6358         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6359         nums=$($cmd | wc -l)
6360         [ $nums -eq $expected ] || {
6361                 $LFS getstripe -R $dir
6362                 error "'$cmd' wrong: found $nums, expected $expected"
6363         }
6364 }
6365 run_test 56s "check lfs find -stripe-count works"
6366
6367 test_56t() { # LU-611 #LU-9369
6368         local dir=$DIR/$tdir
6369
6370         setup_56 $dir 0 $NUMDIRS
6371         for i in $(seq $NUMDIRS); do
6372                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6373         done
6374
6375         local expected=$NUMDIRS
6376         local cmd="$LFS find -S 8M $dir"
6377         local nums=$($cmd | wc -l)
6378
6379         [ $nums -eq $expected ] || {
6380                 $LFS getstripe -R $dir
6381                 error "'$cmd' wrong: found $nums, expected $expected"
6382         }
6383         rm -rf $dir
6384
6385         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6386
6387         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6388
6389         expected=$(((NUMDIRS + 1) * NUMFILES))
6390         cmd="$LFS find -stripe-size 512k -type f $dir"
6391         nums=$($cmd | wc -l)
6392         [ $nums -eq $expected ] ||
6393                 error "'$cmd' wrong: found $nums, expected $expected"
6394
6395         cmd="$LFS find -stripe-size +320k -type f $dir"
6396         nums=$($cmd | wc -l)
6397         [ $nums -eq $expected ] ||
6398                 error "'$cmd' wrong: found $nums, expected $expected"
6399
6400         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6401         cmd="$LFS find -stripe-size +200k -type f $dir"
6402         nums=$($cmd | wc -l)
6403         [ $nums -eq $expected ] ||
6404                 error "'$cmd' wrong: found $nums, expected $expected"
6405
6406         cmd="$LFS find -stripe-size -640k -type f $dir"
6407         nums=$($cmd | wc -l)
6408         [ $nums -eq $expected ] ||
6409                 error "'$cmd' wrong: found $nums, expected $expected"
6410
6411         expected=4
6412         cmd="$LFS find -stripe-size 256k -type f $dir"
6413         nums=$($cmd | wc -l)
6414         [ $nums -eq $expected ] ||
6415                 error "'$cmd' wrong: found $nums, expected $expected"
6416
6417         cmd="$LFS find -stripe-size -320k -type f $dir"
6418         nums=$($cmd | wc -l)
6419         [ $nums -eq $expected ] ||
6420                 error "'$cmd' wrong: found $nums, expected $expected"
6421
6422         expected=0
6423         cmd="$LFS find -stripe-size 1024k -type f $dir"
6424         nums=$($cmd | wc -l)
6425         [ $nums -eq $expected ] ||
6426                 error "'$cmd' wrong: found $nums, expected $expected"
6427 }
6428 run_test 56t "check lfs find -stripe-size works"
6429
6430 test_56u() { # LU-611
6431         local dir=$DIR/$tdir
6432
6433         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6434
6435         if [[ $OSTCOUNT -gt 1 ]]; then
6436                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6437                 onestripe=4
6438         else
6439                 onestripe=0
6440         fi
6441
6442         local expected=$(((NUMDIRS + 1) * NUMFILES))
6443         local cmd="$LFS find -stripe-index 0 -type f $dir"
6444         local nums=$($cmd | wc -l)
6445
6446         [ $nums -eq $expected ] ||
6447                 error "'$cmd' wrong: found $nums, expected $expected"
6448
6449         expected=$onestripe
6450         cmd="$LFS find -stripe-index 1 -type f $dir"
6451         nums=$($cmd | wc -l)
6452         [ $nums -eq $expected ] ||
6453                 error "'$cmd' wrong: found $nums, expected $expected"
6454
6455         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6456         nums=$($cmd | wc -l)
6457         [ $nums -eq $expected ] ||
6458                 error "'$cmd' wrong: found $nums, expected $expected"
6459
6460         expected=0
6461         # This should produce an error and not return any files
6462         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6463         nums=$($cmd 2>/dev/null | wc -l)
6464         [ $nums -eq $expected ] ||
6465                 error "'$cmd' wrong: found $nums, expected $expected"
6466
6467         if [[ $OSTCOUNT -gt 1 ]]; then
6468                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6469                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6470                 nums=$($cmd | wc -l)
6471                 [ $nums -eq $expected ] ||
6472                         error "'$cmd' wrong: found $nums, expected $expected"
6473         fi
6474 }
6475 run_test 56u "check lfs find -stripe-index works"
6476
6477 test_56v() {
6478         local mdt_idx=0
6479         local dir=$DIR/$tdir
6480
6481         setup_56 $dir $NUMFILES $NUMDIRS
6482
6483         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6484         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6485
6486         for file in $($LFS find -m $UUID $dir); do
6487                 file_midx=$($LFS getstripe -m $file)
6488                 [ $file_midx -eq $mdt_idx ] ||
6489                         error "lfs find -m $UUID != getstripe -m $file_midx"
6490         done
6491 }
6492 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6493
6494 test_56w() {
6495         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6497
6498         local dir=$DIR/$tdir
6499
6500         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6501
6502         local stripe_size=$($LFS getstripe -S -d $dir) ||
6503                 error "$LFS getstripe -S -d $dir failed"
6504         stripe_size=${stripe_size%% *}
6505
6506         local file_size=$((stripe_size * OSTCOUNT))
6507         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6508         local required_space=$((file_num * file_size))
6509         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6510                            head -n1)
6511         [[ $free_space -le $((required_space / 1024)) ]] &&
6512                 skip_env "need $required_space, have $free_space kbytes"
6513
6514         local dd_bs=65536
6515         local dd_count=$((file_size / dd_bs))
6516
6517         # write data into the files
6518         local i
6519         local j
6520         local file
6521
6522         for i in $(seq $NUMFILES); do
6523                 file=$dir/file$i
6524                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6525                         error "write data into $file failed"
6526         done
6527         for i in $(seq $NUMDIRS); do
6528                 for j in $(seq $NUMFILES); do
6529                         file=$dir/dir$i/file$j
6530                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6531                                 error "write data into $file failed"
6532                 done
6533         done
6534
6535         # $LFS_MIGRATE will fail if hard link migration is unsupported
6536         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6537                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6538                         error "creating links to $dir/dir1/file1 failed"
6539         fi
6540
6541         local expected=-1
6542
6543         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6544
6545         # lfs_migrate file
6546         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6547
6548         echo "$cmd"
6549         eval $cmd || error "$cmd failed"
6550
6551         check_stripe_count $dir/file1 $expected
6552
6553         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6554         then
6555                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6556                 # OST 1 if it is on OST 0. This file is small enough to
6557                 # be on only one stripe.
6558                 file=$dir/migr_1_ost
6559                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6560                         error "write data into $file failed"
6561                 local obdidx=$($LFS getstripe -i $file)
6562                 local oldmd5=$(md5sum $file)
6563                 local newobdidx=0
6564
6565                 [[ $obdidx -eq 0 ]] && newobdidx=1
6566                 cmd="$LFS migrate -i $newobdidx $file"
6567                 echo $cmd
6568                 eval $cmd || error "$cmd failed"
6569
6570                 local realobdix=$($LFS getstripe -i $file)
6571                 local newmd5=$(md5sum $file)
6572
6573                 [[ $newobdidx -ne $realobdix ]] &&
6574                         error "new OST is different (was=$obdidx, "\
6575                               "wanted=$newobdidx, got=$realobdix)"
6576                 [[ "$oldmd5" != "$newmd5" ]] &&
6577                         error "md5sum differ: $oldmd5, $newmd5"
6578         fi
6579
6580         # lfs_migrate dir
6581         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6582         echo "$cmd"
6583         eval $cmd || error "$cmd failed"
6584
6585         for j in $(seq $NUMFILES); do
6586                 check_stripe_count $dir/dir1/file$j $expected
6587         done
6588
6589         # lfs_migrate works with lfs find
6590         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6591              $LFS_MIGRATE -y -c $expected"
6592         echo "$cmd"
6593         eval $cmd || error "$cmd failed"
6594
6595         for i in $(seq 2 $NUMFILES); do
6596                 check_stripe_count $dir/file$i $expected
6597         done
6598         for i in $(seq 2 $NUMDIRS); do
6599                 for j in $(seq $NUMFILES); do
6600                 check_stripe_count $dir/dir$i/file$j $expected
6601                 done
6602         done
6603 }
6604 run_test 56w "check lfs_migrate -c stripe_count works"
6605
6606 test_56wb() {
6607         local file1=$DIR/$tdir/file1
6608         local create_pool=false
6609         local initial_pool=$($LFS getstripe -p $DIR)
6610         local pool_list=()
6611         local pool=""
6612
6613         echo -n "Creating test dir..."
6614         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6615         echo "done."
6616
6617         echo -n "Creating test file..."
6618         touch $file1 || error "cannot create file"
6619         echo "done."
6620
6621         echo -n "Detecting existing pools..."
6622         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6623
6624         if [ ${#pool_list[@]} -gt 0 ]; then
6625                 echo "${pool_list[@]}"
6626                 for thispool in "${pool_list[@]}"; do
6627                         if [[ -z "$initial_pool" ||
6628                               "$initial_pool" != "$thispool" ]]; then
6629                                 pool="$thispool"
6630                                 echo "Using existing pool '$pool'"
6631                                 break
6632                         fi
6633                 done
6634         else
6635                 echo "none detected."
6636         fi
6637         if [ -z "$pool" ]; then
6638                 pool=${POOL:-testpool}
6639                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6640                 echo -n "Creating pool '$pool'..."
6641                 create_pool=true
6642                 pool_add $pool &> /dev/null ||
6643                         error "pool_add failed"
6644                 echo "done."
6645
6646                 echo -n "Adding target to pool..."
6647                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6648                         error "pool_add_targets failed"
6649                 echo "done."
6650         fi
6651
6652         echo -n "Setting pool using -p option..."
6653         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6654                 error "migrate failed rc = $?"
6655         echo "done."
6656
6657         echo -n "Verifying test file is in pool after migrating..."
6658         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6659                 error "file was not migrated to pool $pool"
6660         echo "done."
6661
6662         echo -n "Removing test file from pool '$pool'..."
6663         # "lfs migrate $file" won't remove the file from the pool
6664         # until some striping information is changed.
6665         $LFS migrate -c 1 $file1 &> /dev/null ||
6666                 error "cannot remove from pool"
6667         [ "$($LFS getstripe -p $file1)" ] &&
6668                 error "pool still set"
6669         echo "done."
6670
6671         echo -n "Setting pool using --pool option..."
6672         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6673                 error "migrate failed rc = $?"
6674         echo "done."
6675
6676         # Clean up
6677         rm -f $file1
6678         if $create_pool; then
6679                 destroy_test_pools 2> /dev/null ||
6680                         error "destroy test pools failed"
6681         fi
6682 }
6683 run_test 56wb "check lfs_migrate pool support"
6684
6685 test_56wc() {
6686         local file1="$DIR/$tdir/file1"
6687         local parent_ssize
6688         local parent_scount
6689         local cur_ssize
6690         local cur_scount
6691         local orig_ssize
6692
6693         echo -n "Creating test dir..."
6694         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6695         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6696                 error "cannot set stripe by '-S 1M -c 1'"
6697         echo "done"
6698
6699         echo -n "Setting initial stripe for test file..."
6700         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6701                 error "cannot set stripe"
6702         cur_ssize=$($LFS getstripe -S "$file1")
6703         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6704         echo "done."
6705
6706         # File currently set to -S 512K -c 1
6707
6708         # Ensure -c and -S options are rejected when -R is set
6709         echo -n "Verifying incompatible options are detected..."
6710         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6711                 error "incompatible -c and -R options not detected"
6712         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6713                 error "incompatible -S and -R options not detected"
6714         echo "done."
6715
6716         # Ensure unrecognized options are passed through to 'lfs migrate'
6717         echo -n "Verifying -S option is passed through to lfs migrate..."
6718         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6719                 error "migration failed"
6720         cur_ssize=$($LFS getstripe -S "$file1")
6721         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6722         echo "done."
6723
6724         # File currently set to -S 1M -c 1
6725
6726         # Ensure long options are supported
6727         echo -n "Verifying long options supported..."
6728         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6729                 error "long option without argument not supported"
6730         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6731                 error "long option with argument not supported"
6732         cur_ssize=$($LFS getstripe -S "$file1")
6733         [ $cur_ssize -eq 524288 ] ||
6734                 error "migrate --stripe-size $cur_ssize != 524288"
6735         echo "done."
6736
6737         # File currently set to -S 512K -c 1
6738
6739         if [ "$OSTCOUNT" -gt 1 ]; then
6740                 echo -n "Verifying explicit stripe count can be set..."
6741                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6742                         error "migrate failed"
6743                 cur_scount=$($LFS getstripe -c "$file1")
6744                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6745                 echo "done."
6746         fi
6747
6748         # File currently set to -S 512K -c 1 or -S 512K -c 2
6749
6750         # Ensure parent striping is used if -R is set, and no stripe
6751         # count or size is specified
6752         echo -n "Setting stripe for parent directory..."
6753         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6754                 error "cannot set stripe '-S 2M -c 1'"
6755         echo "done."
6756
6757         echo -n "Verifying restripe option uses parent stripe settings..."
6758         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6759         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6760         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6761                 error "migrate failed"
6762         cur_ssize=$($LFS getstripe -S "$file1")
6763         [ $cur_ssize -eq $parent_ssize ] ||
6764                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6765         cur_scount=$($LFS getstripe -c "$file1")
6766         [ $cur_scount -eq $parent_scount ] ||
6767                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6768         echo "done."
6769
6770         # File currently set to -S 1M -c 1
6771
6772         # Ensure striping is preserved if -R is not set, and no stripe
6773         # count or size is specified
6774         echo -n "Verifying striping size preserved when not specified..."
6775         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6776         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6777                 error "cannot set stripe on parent directory"
6778         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6779                 error "migrate failed"
6780         cur_ssize=$($LFS getstripe -S "$file1")
6781         [ $cur_ssize -eq $orig_ssize ] ||
6782                 error "migrate by default $cur_ssize != $orig_ssize"
6783         echo "done."
6784
6785         # Ensure file name properly detected when final option has no argument
6786         echo -n "Verifying file name properly detected..."
6787         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6788                 error "file name interpreted as option argument"
6789         echo "done."
6790
6791         # Clean up
6792         rm -f "$file1"
6793 }
6794 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6795
6796 test_56wd() {
6797         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6798
6799         local file1=$DIR/$tdir/file1
6800
6801         echo -n "Creating test dir..."
6802         test_mkdir $DIR/$tdir || error "cannot create dir"
6803         echo "done."
6804
6805         echo -n "Creating test file..."
6806         touch $file1
6807         echo "done."
6808
6809         # Ensure 'lfs migrate' will fail by using a non-existent option,
6810         # and make sure rsync is not called to recover
6811         echo -n "Make sure --no-rsync option works..."
6812         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6813                 grep -q 'refusing to fall back to rsync' ||
6814                 error "rsync was called with --no-rsync set"
6815         echo "done."
6816
6817         # Ensure rsync is called without trying 'lfs migrate' first
6818         echo -n "Make sure --rsync option works..."
6819         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6820                 grep -q 'falling back to rsync' &&
6821                 error "lfs migrate was called with --rsync set"
6822         echo "done."
6823
6824         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6825         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6826                 grep -q 'at the same time' ||
6827                 error "--rsync and --no-rsync accepted concurrently"
6828         echo "done."
6829
6830         # Clean up
6831         rm -f $file1
6832 }
6833 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6834
6835 test_56we() {
6836         local td=$DIR/$tdir
6837         local tf=$td/$tfile
6838
6839         test_mkdir $td || error "cannot create $td"
6840         touch $tf || error "cannot touch $tf"
6841
6842         echo -n "Make sure --non-direct|-D works..."
6843         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6844                 grep -q "lfs migrate --non-direct" ||
6845                 error "--non-direct option cannot work correctly"
6846         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6847                 grep -q "lfs migrate -D" ||
6848                 error "-D option cannot work correctly"
6849         echo "done."
6850 }
6851 run_test 56we "check lfs_migrate --non-direct|-D support"
6852
6853 test_56x() {
6854         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6855         check_swap_layouts_support
6856
6857         local dir=$DIR/$tdir
6858         local ref1=/etc/passwd
6859         local file1=$dir/file1
6860
6861         test_mkdir $dir || error "creating dir $dir"
6862         $LFS setstripe -c 2 $file1
6863         cp $ref1 $file1
6864         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6865         stripe=$($LFS getstripe -c $file1)
6866         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6867         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6868
6869         # clean up
6870         rm -f $file1
6871 }
6872 run_test 56x "lfs migration support"
6873
6874 test_56xa() {
6875         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6876         check_swap_layouts_support
6877
6878         local dir=$DIR/$tdir/$testnum
6879
6880         test_mkdir -p $dir
6881
6882         local ref1=/etc/passwd
6883         local file1=$dir/file1
6884
6885         $LFS setstripe -c 2 $file1
6886         cp $ref1 $file1
6887         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6888
6889         local stripe=$($LFS getstripe -c $file1)
6890
6891         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6892         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6893
6894         # clean up
6895         rm -f $file1
6896 }
6897 run_test 56xa "lfs migration --block support"
6898
6899 check_migrate_links() {
6900         local dir="$1"
6901         local file1="$dir/file1"
6902         local begin="$2"
6903         local count="$3"
6904         local runas="$4"
6905         local total_count=$(($begin + $count - 1))
6906         local symlink_count=10
6907         local uniq_count=10
6908
6909         if [ ! -f "$file1" ]; then
6910                 echo -n "creating initial file..."
6911                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6912                         error "cannot setstripe initial file"
6913                 echo "done"
6914
6915                 echo -n "creating symlinks..."
6916                 for s in $(seq 1 $symlink_count); do
6917                         ln -s "$file1" "$dir/slink$s" ||
6918                                 error "cannot create symlinks"
6919                 done
6920                 echo "done"
6921
6922                 echo -n "creating nonlinked files..."
6923                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6924                         error "cannot create nonlinked files"
6925                 echo "done"
6926         fi
6927
6928         # create hard links
6929         if [ ! -f "$dir/file$total_count" ]; then
6930                 echo -n "creating hard links $begin:$total_count..."
6931                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6932                         /dev/null || error "cannot create hard links"
6933                 echo "done"
6934         fi
6935
6936         echo -n "checking number of hard links listed in xattrs..."
6937         local fid=$($LFS getstripe -F "$file1")
6938         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6939
6940         echo "${#paths[*]}"
6941         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6942                         skip "hard link list has unexpected size, skipping test"
6943         fi
6944         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6945                         error "link names should exceed xattrs size"
6946         fi
6947
6948         echo -n "migrating files..."
6949         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6950         local rc=$?
6951         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6952         echo "done"
6953
6954         # make sure all links have been properly migrated
6955         echo -n "verifying files..."
6956         fid=$($LFS getstripe -F "$file1") ||
6957                 error "cannot get fid for file $file1"
6958         for i in $(seq 2 $total_count); do
6959                 local fid2=$($LFS getstripe -F $dir/file$i)
6960
6961                 [ "$fid2" == "$fid" ] ||
6962                         error "migrated hard link has mismatched FID"
6963         done
6964
6965         # make sure hard links were properly detected, and migration was
6966         # performed only once for the entire link set; nonlinked files should
6967         # also be migrated
6968         local actual=$(grep -c 'done' <<< "$migrate_out")
6969         local expected=$(($uniq_count + 1))
6970
6971         [ "$actual" -eq  "$expected" ] ||
6972                 error "hard links individually migrated ($actual != $expected)"
6973
6974         # make sure the correct number of hard links are present
6975         local hardlinks=$(stat -c '%h' "$file1")
6976
6977         [ $hardlinks -eq $total_count ] ||
6978                 error "num hard links $hardlinks != $total_count"
6979         echo "done"
6980
6981         return 0
6982 }
6983
6984 test_56xb() {
6985         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6986                 skip "Need MDS version at least 2.10.55"
6987
6988         local dir="$DIR/$tdir"
6989
6990         test_mkdir "$dir" || error "cannot create dir $dir"
6991
6992         echo "testing lfs migrate mode when all links fit within xattrs"
6993         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6994
6995         echo "testing rsync mode when all links fit within xattrs"
6996         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6997
6998         echo "testing lfs migrate mode when all links do not fit within xattrs"
6999         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7000
7001         echo "testing rsync mode when all links do not fit within xattrs"
7002         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7003
7004         chown -R $RUNAS_ID $dir
7005         echo "testing non-root lfs migrate mode when not all links are in xattr"
7006         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7007
7008         # clean up
7009         rm -rf $dir
7010 }
7011 run_test 56xb "lfs migration hard link support"
7012
7013 test_56xc() {
7014         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7015
7016         local dir="$DIR/$tdir"
7017
7018         test_mkdir "$dir" || error "cannot create dir $dir"
7019
7020         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7021         echo -n "Setting initial stripe for 20MB test file..."
7022         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7023                 error "cannot setstripe 20MB file"
7024         echo "done"
7025         echo -n "Sizing 20MB test file..."
7026         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7027         echo "done"
7028         echo -n "Verifying small file autostripe count is 1..."
7029         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7030                 error "cannot migrate 20MB file"
7031         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7032                 error "cannot get stripe for $dir/20mb"
7033         [ $stripe_count -eq 1 ] ||
7034                 error "unexpected stripe count $stripe_count for 20MB file"
7035         rm -f "$dir/20mb"
7036         echo "done"
7037
7038         # Test 2: File is small enough to fit within the available space on
7039         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7040         # have at least an additional 1KB for each desired stripe for test 3
7041         echo -n "Setting stripe for 1GB test file..."
7042         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7043         echo "done"
7044         echo -n "Sizing 1GB test file..."
7045         # File size is 1GB + 3KB
7046         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7047         echo "done"
7048
7049         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7050         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7051         if (( avail > 524288 * OSTCOUNT )); then
7052                 echo -n "Migrating 1GB file..."
7053                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7054                         error "cannot migrate 1GB file"
7055                 echo "done"
7056                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7057                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7058                         error "cannot getstripe for 1GB file"
7059                 [ $stripe_count -eq 2 ] ||
7060                         error "unexpected stripe count $stripe_count != 2"
7061                 echo "done"
7062         fi
7063
7064         # Test 3: File is too large to fit within the available space on
7065         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7066         if [ $OSTCOUNT -ge 3 ]; then
7067                 # The required available space is calculated as
7068                 # file size (1GB + 3KB) / OST count (3).
7069                 local kb_per_ost=349526
7070
7071                 echo -n "Migrating 1GB file with limit..."
7072                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7073                         error "cannot migrate 1GB file with limit"
7074                 echo "done"
7075
7076                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7077                 echo -n "Verifying 1GB autostripe count with limited space..."
7078                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7079                         error "unexpected stripe count $stripe_count (min 3)"
7080                 echo "done"
7081         fi
7082
7083         # clean up
7084         rm -rf $dir
7085 }
7086 run_test 56xc "lfs migration autostripe"
7087
7088 test_56xd() {
7089         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7090
7091         local dir=$DIR/$tdir
7092         local f_mgrt=$dir/$tfile.mgrt
7093         local f_yaml=$dir/$tfile.yaml
7094         local f_copy=$dir/$tfile.copy
7095         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7096         local layout_copy="-c 2 -S 2M -i 1"
7097         local yamlfile=$dir/yamlfile
7098         local layout_before;
7099         local layout_after;
7100
7101         test_mkdir "$dir" || error "cannot create dir $dir"
7102         $LFS setstripe $layout_yaml $f_yaml ||
7103                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7104         $LFS getstripe --yaml $f_yaml > $yamlfile
7105         $LFS setstripe $layout_copy $f_copy ||
7106                 error "cannot setstripe $f_copy with layout $layout_copy"
7107         touch $f_mgrt
7108         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7109
7110         # 1. test option --yaml
7111         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7112                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7113         layout_before=$(get_layout_param $f_yaml)
7114         layout_after=$(get_layout_param $f_mgrt)
7115         [ "$layout_after" == "$layout_before" ] ||
7116                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7117
7118         # 2. test option --copy
7119         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7120                 error "cannot migrate $f_mgrt with --copy $f_copy"
7121         layout_before=$(get_layout_param $f_copy)
7122         layout_after=$(get_layout_param $f_mgrt)
7123         [ "$layout_after" == "$layout_before" ] ||
7124                 error "lfs_migrate --copy: $layout_after != $layout_before"
7125 }
7126 run_test 56xd "check lfs_migrate --yaml and --copy support"
7127
7128 test_56xe() {
7129         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7130
7131         local dir=$DIR/$tdir
7132         local f_comp=$dir/$tfile
7133         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7134         local layout_before=""
7135         local layout_after=""
7136
7137         test_mkdir "$dir" || error "cannot create dir $dir"
7138         $LFS setstripe $layout $f_comp ||
7139                 error "cannot setstripe $f_comp with layout $layout"
7140         layout_before=$(get_layout_param $f_comp)
7141         dd if=/dev/zero of=$f_comp bs=1M count=4
7142
7143         # 1. migrate a comp layout file by lfs_migrate
7144         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7145         layout_after=$(get_layout_param $f_comp)
7146         [ "$layout_before" == "$layout_after" ] ||
7147                 error "lfs_migrate: $layout_before != $layout_after"
7148
7149         # 2. migrate a comp layout file by lfs migrate
7150         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7151         layout_after=$(get_layout_param $f_comp)
7152         [ "$layout_before" == "$layout_after" ] ||
7153                 error "lfs migrate: $layout_before != $layout_after"
7154 }
7155 run_test 56xe "migrate a composite layout file"
7156
7157 test_56xf() {
7158         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7159
7160         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7161                 skip "Need server version at least 2.13.53"
7162
7163         local dir=$DIR/$tdir
7164         local f_comp=$dir/$tfile
7165         local layout="-E 1M -c1 -E -1 -c2"
7166         local fid_before=""
7167         local fid_after=""
7168
7169         test_mkdir "$dir" || error "cannot create dir $dir"
7170         $LFS setstripe $layout $f_comp ||
7171                 error "cannot setstripe $f_comp with layout $layout"
7172         fid_before=$($LFS getstripe --fid $f_comp)
7173         dd if=/dev/zero of=$f_comp bs=1M count=4
7174
7175         # 1. migrate a comp layout file to a comp layout
7176         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7177         fid_after=$($LFS getstripe --fid $f_comp)
7178         [ "$fid_before" == "$fid_after" ] ||
7179                 error "comp-to-comp migrate: $fid_before != $fid_after"
7180
7181         # 2. migrate a comp layout file to a plain layout
7182         $LFS migrate -c2 $f_comp ||
7183                 error "cannot migrate $f_comp by lfs migrate"
7184         fid_after=$($LFS getstripe --fid $f_comp)
7185         [ "$fid_before" == "$fid_after" ] ||
7186                 error "comp-to-plain migrate: $fid_before != $fid_after"
7187
7188         # 3. migrate a plain layout file to a comp layout
7189         $LFS migrate $layout $f_comp ||
7190                 error "cannot migrate $f_comp by lfs migrate"
7191         fid_after=$($LFS getstripe --fid $f_comp)
7192         [ "$fid_before" == "$fid_after" ] ||
7193                 error "plain-to-comp migrate: $fid_before != $fid_after"
7194 }
7195 run_test 56xf "FID is not lost during migration of a composite layout file"
7196
7197 test_56y() {
7198         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7199                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7200
7201         local res=""
7202         local dir=$DIR/$tdir
7203         local f1=$dir/file1
7204         local f2=$dir/file2
7205
7206         test_mkdir -p $dir || error "creating dir $dir"
7207         touch $f1 || error "creating std file $f1"
7208         $MULTIOP $f2 H2c || error "creating released file $f2"
7209
7210         # a directory can be raid0, so ask only for files
7211         res=$($LFS find $dir -L raid0 -type f | wc -l)
7212         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7213
7214         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7215         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7216
7217         # only files can be released, so no need to force file search
7218         res=$($LFS find $dir -L released)
7219         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7220
7221         res=$($LFS find $dir -type f \! -L released)
7222         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7223 }
7224 run_test 56y "lfs find -L raid0|released"
7225
7226 test_56z() { # LU-4824
7227         # This checks to make sure 'lfs find' continues after errors
7228         # There are two classes of errors that should be caught:
7229         # - If multiple paths are provided, all should be searched even if one
7230         #   errors out
7231         # - If errors are encountered during the search, it should not terminate
7232         #   early
7233         local dir=$DIR/$tdir
7234         local i
7235
7236         test_mkdir $dir
7237         for i in d{0..9}; do
7238                 test_mkdir $dir/$i
7239                 touch $dir/$i/$tfile
7240         done
7241         $LFS find $DIR/non_existent_dir $dir &&
7242                 error "$LFS find did not return an error"
7243         # Make a directory unsearchable. This should NOT be the last entry in
7244         # directory order.  Arbitrarily pick the 6th entry
7245         chmod 700 $($LFS find $dir -type d | sed '6!d')
7246
7247         $RUNAS $LFS find $DIR/non_existent $dir
7248         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7249
7250         # The user should be able to see 10 directories and 9 files
7251         (( count == 19 )) ||
7252                 error "$LFS find found $count != 19 entries after error"
7253 }
7254 run_test 56z "lfs find should continue after an error"
7255
7256 test_56aa() { # LU-5937
7257         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7258
7259         local dir=$DIR/$tdir
7260
7261         mkdir $dir
7262         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7263
7264         createmany -o $dir/striped_dir/${tfile}- 1024
7265         local dirs=$($LFS find --size +8k $dir/)
7266
7267         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7268 }
7269 run_test 56aa "lfs find --size under striped dir"
7270
7271 test_56ab() { # LU-10705
7272         test_mkdir $DIR/$tdir
7273         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7274         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7275         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7276         # Flush writes to ensure valid blocks.  Need to be more thorough for
7277         # ZFS, since blocks are not allocated/returned to client immediately.
7278         sync_all_data
7279         wait_zfs_commit ost1 2
7280         cancel_lru_locks osc
7281         ls -ls $DIR/$tdir
7282
7283         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7284
7285         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7286
7287         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7288         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7289
7290         rm -f $DIR/$tdir/$tfile.[123]
7291 }
7292 run_test 56ab "lfs find --blocks"
7293
7294 test_56ba() {
7295         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7296                 skip "Need MDS version at least 2.10.50"
7297
7298         # Create composite files with one component
7299         local dir=$DIR/$tdir
7300
7301         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7302         # Create composite files with three components
7303         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7304         # Create non-composite files
7305         createmany -o $dir/${tfile}- 10
7306
7307         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7308
7309         [[ $nfiles == 10 ]] ||
7310                 error "lfs find -E 1M found $nfiles != 10 files"
7311
7312         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7313         [[ $nfiles == 25 ]] ||
7314                 error "lfs find ! -E 1M found $nfiles != 25 files"
7315
7316         # All files have a component that starts at 0
7317         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7318         [[ $nfiles == 35 ]] ||
7319                 error "lfs find --component-start 0 - $nfiles != 35 files"
7320
7321         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7322         [[ $nfiles == 15 ]] ||
7323                 error "lfs find --component-start 2M - $nfiles != 15 files"
7324
7325         # All files created here have a componenet that does not starts at 2M
7326         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7327         [[ $nfiles == 35 ]] ||
7328                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7329
7330         # Find files with a specified number of components
7331         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7332         [[ $nfiles == 15 ]] ||
7333                 error "lfs find --component-count 3 - $nfiles != 15 files"
7334
7335         # Remember non-composite files have a component count of zero
7336         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7337         [[ $nfiles == 10 ]] ||
7338                 error "lfs find --component-count 0 - $nfiles != 10 files"
7339
7340         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7341         [[ $nfiles == 20 ]] ||
7342                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7343
7344         # All files have a flag called "init"
7345         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7346         [[ $nfiles == 35 ]] ||
7347                 error "lfs find --component-flags init - $nfiles != 35 files"
7348
7349         # Multi-component files will have a component not initialized
7350         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7351         [[ $nfiles == 15 ]] ||
7352                 error "lfs find !--component-flags init - $nfiles != 15 files"
7353
7354         rm -rf $dir
7355
7356 }
7357 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7358
7359 test_56ca() {
7360         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7361                 skip "Need MDS version at least 2.10.57"
7362
7363         local td=$DIR/$tdir
7364         local tf=$td/$tfile
7365         local dir
7366         local nfiles
7367         local cmd
7368         local i
7369         local j
7370
7371         # create mirrored directories and mirrored files
7372         mkdir $td || error "mkdir $td failed"
7373         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7374         createmany -o $tf- 10 || error "create $tf- failed"
7375
7376         for i in $(seq 2); do
7377                 dir=$td/dir$i
7378                 mkdir $dir || error "mkdir $dir failed"
7379                 $LFS mirror create -N$((3 + i)) $dir ||
7380                         error "create mirrored dir $dir failed"
7381                 createmany -o $dir/$tfile- 10 ||
7382                         error "create $dir/$tfile- failed"
7383         done
7384
7385         # change the states of some mirrored files
7386         echo foo > $tf-6
7387         for i in $(seq 2); do
7388                 dir=$td/dir$i
7389                 for j in $(seq 4 9); do
7390                         echo foo > $dir/$tfile-$j
7391                 done
7392         done
7393
7394         # find mirrored files with specific mirror count
7395         cmd="$LFS find --mirror-count 3 --type f $td"
7396         nfiles=$($cmd | wc -l)
7397         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7398
7399         cmd="$LFS find ! --mirror-count 3 --type f $td"
7400         nfiles=$($cmd | wc -l)
7401         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7402
7403         cmd="$LFS find --mirror-count +2 --type f $td"
7404         nfiles=$($cmd | wc -l)
7405         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7406
7407         cmd="$LFS find --mirror-count -6 --type f $td"
7408         nfiles=$($cmd | wc -l)
7409         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7410
7411         # find mirrored files with specific file state
7412         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7413         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7414
7415         cmd="$LFS find --mirror-state=ro --type f $td"
7416         nfiles=$($cmd | wc -l)
7417         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7418
7419         cmd="$LFS find ! --mirror-state=ro --type f $td"
7420         nfiles=$($cmd | wc -l)
7421         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7422
7423         cmd="$LFS find --mirror-state=wp --type f $td"
7424         nfiles=$($cmd | wc -l)
7425         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7426
7427         cmd="$LFS find ! --mirror-state=sp --type f $td"
7428         nfiles=$($cmd | wc -l)
7429         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7430 }
7431 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7432
7433 test_57a() {
7434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7435         # note test will not do anything if MDS is not local
7436         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7437                 skip_env "ldiskfs only test"
7438         fi
7439         remote_mds_nodsh && skip "remote MDS with nodsh"
7440
7441         local MNTDEV="osd*.*MDT*.mntdev"
7442         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7443         [ -z "$DEV" ] && error "can't access $MNTDEV"
7444         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7445                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7446                         error "can't access $DEV"
7447                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7448                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7449                 rm $TMP/t57a.dump
7450         done
7451 }
7452 run_test 57a "verify MDS filesystem created with large inodes =="
7453
7454 test_57b() {
7455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7456         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7457                 skip_env "ldiskfs only test"
7458         fi
7459         remote_mds_nodsh && skip "remote MDS with nodsh"
7460
7461         local dir=$DIR/$tdir
7462         local filecount=100
7463         local file1=$dir/f1
7464         local fileN=$dir/f$filecount
7465
7466         rm -rf $dir || error "removing $dir"
7467         test_mkdir -c1 $dir
7468         local mdtidx=$($LFS getstripe -m $dir)
7469         local mdtname=MDT$(printf %04x $mdtidx)
7470         local facet=mds$((mdtidx + 1))
7471
7472         echo "mcreating $filecount files"
7473         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7474
7475         # verify that files do not have EAs yet
7476         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7477                 error "$file1 has an EA"
7478         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7479                 error "$fileN has an EA"
7480
7481         sync
7482         sleep 1
7483         df $dir  #make sure we get new statfs data
7484         local mdsfree=$(do_facet $facet \
7485                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7486         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7487         local file
7488
7489         echo "opening files to create objects/EAs"
7490         for file in $(seq -f $dir/f%g 1 $filecount); do
7491                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7492                         error "opening $file"
7493         done
7494
7495         # verify that files have EAs now
7496         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7497         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7498
7499         sleep 1  #make sure we get new statfs data
7500         df $dir
7501         local mdsfree2=$(do_facet $facet \
7502                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7503         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7504
7505         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7506                 if [ "$mdsfree" != "$mdsfree2" ]; then
7507                         error "MDC before $mdcfree != after $mdcfree2"
7508                 else
7509                         echo "MDC before $mdcfree != after $mdcfree2"
7510                         echo "unable to confirm if MDS has large inodes"
7511                 fi
7512         fi
7513         rm -rf $dir
7514 }
7515 run_test 57b "default LOV EAs are stored inside large inodes ==="
7516
7517 test_58() {
7518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7519         [ -z "$(which wiretest 2>/dev/null)" ] &&
7520                         skip_env "could not find wiretest"
7521
7522         wiretest
7523 }
7524 run_test 58 "verify cross-platform wire constants =============="
7525
7526 test_59() {
7527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7528
7529         echo "touch 130 files"
7530         createmany -o $DIR/f59- 130
7531         echo "rm 130 files"
7532         unlinkmany $DIR/f59- 130
7533         sync
7534         # wait for commitment of removal
7535         wait_delete_completed
7536 }
7537 run_test 59 "verify cancellation of llog records async ========="
7538
7539 TEST60_HEAD="test_60 run $RANDOM"
7540 test_60a() {
7541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7542         remote_mgs_nodsh && skip "remote MGS with nodsh"
7543         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7544                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7545                         skip_env "missing subtest run-llog.sh"
7546
7547         log "$TEST60_HEAD - from kernel mode"
7548         do_facet mgs "$LCTL dk > /dev/null"
7549         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7550         do_facet mgs $LCTL dk > $TMP/$tfile
7551
7552         # LU-6388: test llog_reader
7553         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7554         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7555         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7556                         skip_env "missing llog_reader"
7557         local fstype=$(facet_fstype mgs)
7558         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7559                 skip_env "Only for ldiskfs or zfs type mgs"
7560
7561         local mntpt=$(facet_mntpt mgs)
7562         local mgsdev=$(mgsdevname 1)
7563         local fid_list
7564         local fid
7565         local rec_list
7566         local rec
7567         local rec_type
7568         local obj_file
7569         local path
7570         local seq
7571         local oid
7572         local pass=true
7573
7574         #get fid and record list
7575         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7576                 tail -n 4))
7577         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7578                 tail -n 4))
7579         #remount mgs as ldiskfs or zfs type
7580         stop mgs || error "stop mgs failed"
7581         mount_fstype mgs || error "remount mgs failed"
7582         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7583                 fid=${fid_list[i]}
7584                 rec=${rec_list[i]}
7585                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7586                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7587                 oid=$((16#$oid))
7588
7589                 case $fstype in
7590                         ldiskfs )
7591                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7592                         zfs )
7593                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7594                 esac
7595                 echo "obj_file is $obj_file"
7596                 do_facet mgs $llog_reader $obj_file
7597
7598                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7599                         awk '{ print $3 }' | sed -e "s/^type=//g")
7600                 if [ $rec_type != $rec ]; then
7601                         echo "FAILED test_60a wrong record type $rec_type," \
7602                               "should be $rec"
7603                         pass=false
7604                         break
7605                 fi
7606
7607                 #check obj path if record type is LLOG_LOGID_MAGIC
7608                 if [ "$rec" == "1064553b" ]; then
7609                         path=$(do_facet mgs $llog_reader $obj_file |
7610                                 grep "path=" | awk '{ print $NF }' |
7611                                 sed -e "s/^path=//g")
7612                         if [ $obj_file != $mntpt/$path ]; then
7613                                 echo "FAILED test_60a wrong obj path" \
7614                                       "$montpt/$path, should be $obj_file"
7615                                 pass=false
7616                                 break
7617                         fi
7618                 fi
7619         done
7620         rm -f $TMP/$tfile
7621         #restart mgs before "error", otherwise it will block the next test
7622         stop mgs || error "stop mgs failed"
7623         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7624         $pass || error "test failed, see FAILED test_60a messages for specifics"
7625 }
7626 run_test 60a "llog_test run from kernel module and test llog_reader"
7627
7628 test_60b() { # bug 6411
7629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7630
7631         dmesg > $DIR/$tfile
7632         LLOG_COUNT=$(do_facet mgs dmesg |
7633                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7634                           /llog_[a-z]*.c:[0-9]/ {
7635                                 if (marker)
7636                                         from_marker++
7637                                 from_begin++
7638                           }
7639                           END {
7640                                 if (marker)
7641                                         print from_marker
7642                                 else
7643                                         print from_begin
7644                           }")
7645
7646         [[ $LLOG_COUNT -gt 120 ]] &&
7647                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7648 }
7649 run_test 60b "limit repeated messages from CERROR/CWARN"
7650
7651 test_60c() {
7652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7653
7654         echo "create 5000 files"
7655         createmany -o $DIR/f60c- 5000
7656 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7657         lctl set_param fail_loc=0x80000137
7658         unlinkmany $DIR/f60c- 5000
7659         lctl set_param fail_loc=0
7660 }
7661 run_test 60c "unlink file when mds full"
7662
7663 test_60d() {
7664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7665
7666         SAVEPRINTK=$(lctl get_param -n printk)
7667         # verify "lctl mark" is even working"
7668         MESSAGE="test message ID $RANDOM $$"
7669         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7670         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7671
7672         lctl set_param printk=0 || error "set lnet.printk failed"
7673         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7674         MESSAGE="new test message ID $RANDOM $$"
7675         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7676         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7677         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7678
7679         lctl set_param -n printk="$SAVEPRINTK"
7680 }
7681 run_test 60d "test printk console message masking"
7682
7683 test_60e() {
7684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7685         remote_mds_nodsh && skip "remote MDS with nodsh"
7686
7687         touch $DIR/$tfile
7688 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7689         do_facet mds1 lctl set_param fail_loc=0x15b
7690         rm $DIR/$tfile
7691 }
7692 run_test 60e "no space while new llog is being created"
7693
7694 test_60g() {
7695         local pid
7696         local i
7697
7698         test_mkdir -c $MDSCOUNT $DIR/$tdir
7699
7700         (
7701                 local index=0
7702                 while true; do
7703                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7704                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7705                                 2>/dev/null
7706                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7707                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7708                         index=$((index + 1))
7709                 done
7710         ) &
7711
7712         pid=$!
7713
7714         for i in {0..100}; do
7715                 # define OBD_FAIL_OSD_TXN_START    0x19a
7716                 local index=$((i % MDSCOUNT + 1))
7717
7718                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7719                         > /dev/null
7720                 sleep 0.01
7721         done
7722
7723         kill -9 $pid
7724
7725         for i in $(seq $MDSCOUNT); do
7726                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7727         done
7728
7729         mkdir $DIR/$tdir/new || error "mkdir failed"
7730         rmdir $DIR/$tdir/new || error "rmdir failed"
7731
7732         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7733                 -t namespace
7734         for i in $(seq $MDSCOUNT); do
7735                 wait_update_facet mds$i "$LCTL get_param -n \
7736                         mdd.$(facet_svc mds$i).lfsck_namespace |
7737                         awk '/^status/ { print \\\$2 }'" "completed"
7738         done
7739
7740         ls -R $DIR/$tdir || error "ls failed"
7741         rm -rf $DIR/$tdir || error "rmdir failed"
7742 }
7743 run_test 60g "transaction abort won't cause MDT hung"
7744
7745 test_60h() {
7746         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7747                 skip "Need MDS version at least 2.12.52"
7748         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7749
7750         local f
7751
7752         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7753         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7754         for fail_loc in 0x80000188 0x80000189; do
7755                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7756                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7757                         error "mkdir $dir-$fail_loc failed"
7758                 for i in {0..10}; do
7759                         # create may fail on missing stripe
7760                         echo $i > $DIR/$tdir-$fail_loc/$i
7761                 done
7762                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7763                         error "getdirstripe $tdir-$fail_loc failed"
7764                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7765                         error "migrate $tdir-$fail_loc failed"
7766                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7767                         error "getdirstripe $tdir-$fail_loc failed"
7768                 pushd $DIR/$tdir-$fail_loc
7769                 for f in *; do
7770                         echo $f | cmp $f - || error "$f data mismatch"
7771                 done
7772                 popd
7773                 rm -rf $DIR/$tdir-$fail_loc
7774         done
7775 }
7776 run_test 60h "striped directory with missing stripes can be accessed"
7777
7778 test_61a() {
7779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7780
7781         f="$DIR/f61"
7782         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7783         cancel_lru_locks osc
7784         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7785         sync
7786 }
7787 run_test 61a "mmap() writes don't make sync hang ================"
7788
7789 test_61b() {
7790         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7791 }
7792 run_test 61b "mmap() of unstriped file is successful"
7793
7794 # bug 2330 - insufficient obd_match error checking causes LBUG
7795 test_62() {
7796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7797
7798         f="$DIR/f62"
7799         echo foo > $f
7800         cancel_lru_locks osc
7801         lctl set_param fail_loc=0x405
7802         cat $f && error "cat succeeded, expect -EIO"
7803         lctl set_param fail_loc=0
7804 }
7805 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7806 # match every page all of the time.
7807 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7808
7809 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7810 # Though this test is irrelevant anymore, it helped to reveal some
7811 # other grant bugs (LU-4482), let's keep it.
7812 test_63a() {   # was test_63
7813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7814
7815         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7816
7817         for i in `seq 10` ; do
7818                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7819                 sleep 5
7820                 kill $!
7821                 sleep 1
7822         done
7823
7824         rm -f $DIR/f63 || true
7825 }
7826 run_test 63a "Verify oig_wait interruption does not crash ======="
7827
7828 # bug 2248 - async write errors didn't return to application on sync
7829 # bug 3677 - async write errors left page locked
7830 test_63b() {
7831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7832
7833         debugsave
7834         lctl set_param debug=-1
7835
7836         # ensure we have a grant to do async writes
7837         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7838         rm $DIR/$tfile
7839
7840         sync    # sync lest earlier test intercept the fail_loc
7841
7842         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7843         lctl set_param fail_loc=0x80000406
7844         $MULTIOP $DIR/$tfile Owy && \
7845                 error "sync didn't return ENOMEM"
7846         sync; sleep 2; sync     # do a real sync this time to flush page
7847         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7848                 error "locked page left in cache after async error" || true
7849         debugrestore
7850 }
7851 run_test 63b "async write errors should be returned to fsync ==="
7852
7853 test_64a () {
7854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7855
7856         lfs df $DIR
7857         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7858 }
7859 run_test 64a "verify filter grant calculations (in kernel) ====="
7860
7861 test_64b () {
7862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7863
7864         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7865 }
7866 run_test 64b "check out-of-space detection on client"
7867
7868 test_64c() {
7869         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7870 }
7871 run_test 64c "verify grant shrink"
7872
7873 import_param() {
7874         local tgt=$1
7875         local param=$2
7876
7877         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7878 }
7879
7880 # this does exactly what osc_request.c:osc_announce_cached() does in
7881 # order to calculate max amount of grants to ask from server
7882 want_grant() {
7883         local tgt=$1
7884
7885         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7886         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7887
7888         ((rpc_in_flight++));
7889         nrpages=$((nrpages * rpc_in_flight))
7890
7891         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7892
7893         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7894
7895         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7896         local undirty=$((nrpages * PAGE_SIZE))
7897
7898         local max_extent_pages
7899         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7900         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7901         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7902         local grant_extent_tax
7903         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7904
7905         undirty=$((undirty + nrextents * grant_extent_tax))
7906
7907         echo $undirty
7908 }
7909
7910 # this is size of unit for grant allocation. It should be equal to
7911 # what tgt_grant.c:tgt_grant_chunk() calculates
7912 grant_chunk() {
7913         local tgt=$1
7914         local max_brw_size
7915         local grant_extent_tax
7916
7917         max_brw_size=$(import_param $tgt max_brw_size)
7918
7919         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7920
7921         echo $(((max_brw_size + grant_extent_tax) * 2))
7922 }
7923
7924 test_64d() {
7925         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7926                 skip "OST < 2.10.55 doesn't limit grants enough"
7927
7928         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7929
7930         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7931                 skip "no grant_param connect flag"
7932
7933         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7934
7935         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7936         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7937
7938
7939         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7940         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7941
7942         $LFS setstripe $DIR/$tfile -i 0 -c 1
7943         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7944         ddpid=$!
7945
7946         while kill -0 $ddpid; do
7947                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7948
7949                 if [[ $cur_grant -gt $max_cur_granted ]]; then
7950                         kill $ddpid
7951                         error "cur_grant $cur_grant > $max_cur_granted"
7952                 fi
7953
7954                 sleep 1
7955         done
7956 }
7957 run_test 64d "check grant limit exceed"
7958
7959 check_grants() {
7960         local tgt=$1
7961         local expected=$2
7962         local msg=$3
7963         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7964
7965         ((cur_grants == expected)) ||
7966                 error "$msg: grants mismatch: $cur_grants, expected $expected"
7967 }
7968
7969 round_up_p2() {
7970         echo $((($1 + $2 - 1) & ~($2 - 1)))
7971 }
7972
7973 test_64e() {
7974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7975         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
7976                 skip "Need OSS version at least 2.11.56"
7977
7978         # Remount client to reset grant
7979         remount_client $MOUNT || error "failed to remount client"
7980         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
7981
7982         local init_grants=$(import_param $osc_tgt initial_grant)
7983
7984         check_grants $osc_tgt $init_grants "init grants"
7985
7986         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
7987         local max_brw_size=$(import_param $osc_tgt max_brw_size)
7988         local gbs=$(import_param $osc_tgt grant_block_size)
7989
7990         # write random number of bytes from max_brw_size / 4 to max_brw_size
7991         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
7992         # align for direct io
7993         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
7994         # round to grant consumption unit
7995         local wb_round_up=$(round_up_p2 $write_bytes gbs)
7996
7997         local grants=$((wb_round_up + extent_tax))
7998
7999         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8000
8001         # define OBD_FAIL_TGT_NO_GRANT 0x725
8002         # make the server not grant more back
8003         do_facet ost1 $LCTL set_param fail_loc=0x725
8004         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8005
8006         do_facet ost1 $LCTL set_param fail_loc=0
8007
8008         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8009
8010         rm -f $DIR/$tfile || error "rm failed"
8011
8012         # Remount client to reset grant
8013         remount_client $MOUNT || error "failed to remount client"
8014         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8015
8016         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8017
8018         # define OBD_FAIL_TGT_NO_GRANT 0x725
8019         # make the server not grant more back
8020         do_facet ost1 $LCTL set_param fail_loc=0x725
8021         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8022         do_facet ost1 $LCTL set_param fail_loc=0
8023
8024         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8025 }
8026 run_test 64e "check grant consumption (no grant allocation)"
8027
8028 test_64f() {
8029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8030
8031         # Remount client to reset grant
8032         remount_client $MOUNT || error "failed to remount client"
8033         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8034
8035         local init_grants=$(import_param $osc_tgt initial_grant)
8036         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8037         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8038         local gbs=$(import_param $osc_tgt grant_block_size)
8039         local chunk=$(grant_chunk $osc_tgt)
8040
8041         # write random number of bytes from max_brw_size / 4 to max_brw_size
8042         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8043         # align for direct io
8044         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8045         # round to grant consumption unit
8046         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8047
8048         local grants=$((wb_round_up + extent_tax))
8049
8050         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8051         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8052                 error "error writing to $DIR/$tfile"
8053
8054         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8055                 "direct io with grant allocation"
8056
8057         rm -f $DIR/$tfile || error "rm failed"
8058
8059         # Remount client to reset grant
8060         remount_client $MOUNT || error "failed to remount client"
8061         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8062
8063         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8064
8065         local cmd="oO_WRONLY:w${write_bytes}_yc"
8066
8067         $MULTIOP $DIR/$tfile $cmd &
8068         MULTIPID=$!
8069         sleep 1
8070
8071         check_grants $osc_tgt $((init_grants - grants)) \
8072                 "buffered io, not write rpc"
8073
8074         kill -USR1 $MULTIPID
8075         wait
8076
8077         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8078                 "buffered io, one RPC"
8079 }
8080 run_test 64f "check grant consumption (with grant allocation)"
8081
8082 # bug 1414 - set/get directories' stripe info
8083 test_65a() {
8084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8085
8086         test_mkdir $DIR/$tdir
8087         touch $DIR/$tdir/f1
8088         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8089 }
8090 run_test 65a "directory with no stripe info"
8091
8092 test_65b() {
8093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8094
8095         test_mkdir $DIR/$tdir
8096         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8097
8098         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8099                                                 error "setstripe"
8100         touch $DIR/$tdir/f2
8101         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8102 }
8103 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8104
8105 test_65c() {
8106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8107         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8108
8109         test_mkdir $DIR/$tdir
8110         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8111
8112         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8113                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8114         touch $DIR/$tdir/f3
8115         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8116 }
8117 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8118
8119 test_65d() {
8120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8121
8122         test_mkdir $DIR/$tdir
8123         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8124         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8125
8126         if [[ $STRIPECOUNT -le 0 ]]; then
8127                 sc=1
8128         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8129                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8130                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8131         else
8132                 sc=$(($STRIPECOUNT - 1))
8133         fi
8134         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8135         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8136         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8137                 error "lverify failed"
8138 }
8139 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8140
8141 test_65e() {
8142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8143
8144         test_mkdir $DIR/$tdir
8145
8146         $LFS setstripe $DIR/$tdir || error "setstripe"
8147         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8148                                         error "no stripe info failed"
8149         touch $DIR/$tdir/f6
8150         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8151 }
8152 run_test 65e "directory setstripe defaults"
8153
8154 test_65f() {
8155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8156
8157         test_mkdir $DIR/${tdir}f
8158         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8159                 error "setstripe succeeded" || true
8160 }
8161 run_test 65f "dir setstripe permission (should return error) ==="
8162
8163 test_65g() {
8164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8165
8166         test_mkdir $DIR/$tdir
8167         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8168
8169         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8170                 error "setstripe -S failed"
8171         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8172         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8173                 error "delete default stripe failed"
8174 }
8175 run_test 65g "directory setstripe -d"
8176
8177 test_65h() {
8178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8179
8180         test_mkdir $DIR/$tdir
8181         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8182
8183         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8184                 error "setstripe -S failed"
8185         test_mkdir $DIR/$tdir/dd1
8186         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8187                 error "stripe info inherit failed"
8188 }
8189 run_test 65h "directory stripe info inherit ===================="
8190
8191 test_65i() {
8192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8193
8194         save_layout_restore_at_exit $MOUNT
8195
8196         # bug6367: set non-default striping on root directory
8197         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8198
8199         # bug12836: getstripe on -1 default directory striping
8200         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8201
8202         # bug12836: getstripe -v on -1 default directory striping
8203         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8204
8205         # bug12836: new find on -1 default directory striping
8206         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8207 }
8208 run_test 65i "various tests to set root directory striping"
8209
8210 test_65j() { # bug6367
8211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8212
8213         sync; sleep 1
8214
8215         # if we aren't already remounting for each test, do so for this test
8216         if [ "$I_MOUNTED" = "yes" ]; then
8217                 cleanup || error "failed to unmount"
8218                 setup
8219         fi
8220
8221         save_layout_restore_at_exit $MOUNT
8222
8223         $LFS setstripe -d $MOUNT || error "setstripe failed"
8224 }
8225 run_test 65j "set default striping on root directory (bug 6367)="
8226
8227 cleanup_65k() {
8228         rm -rf $DIR/$tdir
8229         wait_delete_completed
8230         do_facet $SINGLEMDS "lctl set_param -n \
8231                 osp.$ost*MDT0000.max_create_count=$max_count"
8232         do_facet $SINGLEMDS "lctl set_param -n \
8233                 osp.$ost*MDT0000.create_count=$count"
8234         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8235         echo $INACTIVE_OSC "is Activate"
8236
8237         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8238 }
8239
8240 test_65k() { # bug11679
8241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8242         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8243         remote_mds_nodsh && skip "remote MDS with nodsh"
8244
8245         local disable_precreate=true
8246         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8247                 disable_precreate=false
8248
8249         echo "Check OST status: "
8250         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8251                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8252
8253         for OSC in $MDS_OSCS; do
8254                 echo $OSC "is active"
8255                 do_facet $SINGLEMDS lctl --device %$OSC activate
8256         done
8257
8258         for INACTIVE_OSC in $MDS_OSCS; do
8259                 local ost=$(osc_to_ost $INACTIVE_OSC)
8260                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8261                                lov.*md*.target_obd |
8262                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8263
8264                 mkdir -p $DIR/$tdir
8265                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8266                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8267
8268                 echo "Deactivate: " $INACTIVE_OSC
8269                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8270
8271                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8272                               osp.$ost*MDT0000.create_count")
8273                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8274                                   osp.$ost*MDT0000.max_create_count")
8275                 $disable_precreate &&
8276                         do_facet $SINGLEMDS "lctl set_param -n \
8277                                 osp.$ost*MDT0000.max_create_count=0"
8278
8279                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8280                         [ -f $DIR/$tdir/$idx ] && continue
8281                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8282                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8283                                 { cleanup_65k;
8284                                   error "setstripe $idx should succeed"; }
8285                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8286                 done
8287                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8288                 rmdir $DIR/$tdir
8289
8290                 do_facet $SINGLEMDS "lctl set_param -n \
8291                         osp.$ost*MDT0000.max_create_count=$max_count"
8292                 do_facet $SINGLEMDS "lctl set_param -n \
8293                         osp.$ost*MDT0000.create_count=$count"
8294                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8295                 echo $INACTIVE_OSC "is Activate"
8296
8297                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8298         done
8299 }
8300 run_test 65k "validate manual striping works properly with deactivated OSCs"
8301
8302 test_65l() { # bug 12836
8303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8304
8305         test_mkdir -p $DIR/$tdir/test_dir
8306         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8307         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8308 }
8309 run_test 65l "lfs find on -1 stripe dir ========================"
8310
8311 test_65m() {
8312         local layout=$(save_layout $MOUNT)
8313         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8314                 restore_layout $MOUNT $layout
8315                 error "setstripe should fail by non-root users"
8316         }
8317         true
8318 }
8319 run_test 65m "normal user can't set filesystem default stripe"
8320
8321 test_65n() {
8322         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8323         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8324                 skip "Need MDS version at least 2.12.50"
8325         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8326
8327         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8328         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8329         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8330
8331         local root_layout=$(save_layout $MOUNT)
8332         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8333
8334         # new subdirectory under root directory should not inherit
8335         # the default layout from root
8336         local dir1=$MOUNT/$tdir-1
8337         mkdir $dir1 || error "mkdir $dir1 failed"
8338         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8339                 error "$dir1 shouldn't have LOV EA"
8340
8341         # delete the default layout on root directory
8342         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8343
8344         local dir2=$MOUNT/$tdir-2
8345         mkdir $dir2 || error "mkdir $dir2 failed"
8346         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8347                 error "$dir2 shouldn't have LOV EA"
8348
8349         # set a new striping pattern on root directory
8350         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8351         local new_def_stripe_size=$((def_stripe_size * 2))
8352         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8353                 error "set stripe size on $MOUNT failed"
8354
8355         # new file created in $dir2 should inherit the new stripe size from
8356         # the filesystem default
8357         local file2=$dir2/$tfile-2
8358         touch $file2 || error "touch $file2 failed"
8359
8360         local file2_stripe_size=$($LFS getstripe -S $file2)
8361         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8362                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8363
8364         local dir3=$MOUNT/$tdir-3
8365         mkdir $dir3 || error "mkdir $dir3 failed"
8366         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8367         # the root layout, which is the actual default layout that will be used
8368         # when new files are created in $dir3.
8369         local dir3_layout=$(get_layout_param $dir3)
8370         local root_dir_layout=$(get_layout_param $MOUNT)
8371         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8372                 error "$dir3 should show the default layout from $MOUNT"
8373
8374         # set OST pool on root directory
8375         local pool=$TESTNAME
8376         pool_add $pool || error "add $pool failed"
8377         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8378                 error "add targets to $pool failed"
8379
8380         $LFS setstripe -p $pool $MOUNT ||
8381                 error "set OST pool on $MOUNT failed"
8382
8383         # new file created in $dir3 should inherit the pool from
8384         # the filesystem default
8385         local file3=$dir3/$tfile-3
8386         touch $file3 || error "touch $file3 failed"
8387
8388         local file3_pool=$($LFS getstripe -p $file3)
8389         [[ "$file3_pool" = "$pool" ]] ||
8390                 error "$file3 didn't inherit OST pool $pool"
8391
8392         local dir4=$MOUNT/$tdir-4
8393         mkdir $dir4 || error "mkdir $dir4 failed"
8394         local dir4_layout=$(get_layout_param $dir4)
8395         root_dir_layout=$(get_layout_param $MOUNT)
8396         echo "$LFS getstripe -d $dir4"
8397         $LFS getstripe -d $dir4
8398         echo "$LFS getstripe -d $MOUNT"
8399         $LFS getstripe -d $MOUNT
8400         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8401                 error "$dir4 should show the default layout from $MOUNT"
8402
8403         # new file created in $dir4 should inherit the pool from
8404         # the filesystem default
8405         local file4=$dir4/$tfile-4
8406         touch $file4 || error "touch $file4 failed"
8407
8408         local file4_pool=$($LFS getstripe -p $file4)
8409         [[ "$file4_pool" = "$pool" ]] ||
8410                 error "$file4 didn't inherit OST pool $pool"
8411
8412         # new subdirectory under non-root directory should inherit
8413         # the default layout from its parent directory
8414         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8415                 error "set directory layout on $dir4 failed"
8416
8417         local dir5=$dir4/$tdir-5
8418         mkdir $dir5 || error "mkdir $dir5 failed"
8419
8420         dir4_layout=$(get_layout_param $dir4)
8421         local dir5_layout=$(get_layout_param $dir5)
8422         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8423                 error "$dir5 should inherit the default layout from $dir4"
8424
8425         # though subdir under ROOT doesn't inherit default layout, but
8426         # its sub dir/file should be created with default layout.
8427         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8428         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8429                 skip "Need MDS version at least 2.12.59"
8430
8431         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8432         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8433         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8434
8435         if [ $default_lmv_hash == "none" ]; then
8436                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8437         else
8438                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8439                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8440         fi
8441
8442         $LFS setdirstripe -D -c 2 $MOUNT ||
8443                 error "setdirstripe -D -c 2 failed"
8444         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8445         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8446         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8447 }
8448 run_test 65n "don't inherit default layout from root for new subdirectories"
8449
8450 # bug 2543 - update blocks count on client
8451 test_66() {
8452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8453
8454         COUNT=${COUNT:-8}
8455         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8456         sync; sync_all_data; sync; sync_all_data
8457         cancel_lru_locks osc
8458         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8459         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8460 }
8461 run_test 66 "update inode blocks count on client ==============="
8462
8463 meminfo() {
8464         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8465 }
8466
8467 swap_used() {
8468         swapon -s | awk '($1 == "'$1'") { print $4 }'
8469 }
8470
8471 # bug5265, obdfilter oa2dentry return -ENOENT
8472 # #define OBD_FAIL_SRV_ENOENT 0x217
8473 test_69() {
8474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8475         remote_ost_nodsh && skip "remote OST with nodsh"
8476
8477         f="$DIR/$tfile"
8478         $LFS setstripe -c 1 -i 0 $f
8479
8480         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8481
8482         do_facet ost1 lctl set_param fail_loc=0x217
8483         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8484         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8485
8486         do_facet ost1 lctl set_param fail_loc=0
8487         $DIRECTIO write $f 0 2 || error "write error"
8488
8489         cancel_lru_locks osc
8490         $DIRECTIO read $f 0 1 || error "read error"
8491
8492         do_facet ost1 lctl set_param fail_loc=0x217
8493         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8494
8495         do_facet ost1 lctl set_param fail_loc=0
8496         rm -f $f
8497 }
8498 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8499
8500 test_71() {
8501         test_mkdir $DIR/$tdir
8502         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8503         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8504 }
8505 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8506
8507 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8509         [ "$RUNAS_ID" = "$UID" ] &&
8510                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8511         # Check that testing environment is properly set up. Skip if not
8512         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8513                 skip_env "User $RUNAS_ID does not exist - skipping"
8514
8515         touch $DIR/$tfile
8516         chmod 777 $DIR/$tfile
8517         chmod ug+s $DIR/$tfile
8518         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8519                 error "$RUNAS dd $DIR/$tfile failed"
8520         # See if we are still setuid/sgid
8521         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8522                 error "S/gid is not dropped on write"
8523         # Now test that MDS is updated too
8524         cancel_lru_locks mdc
8525         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8526                 error "S/gid is not dropped on MDS"
8527         rm -f $DIR/$tfile
8528 }
8529 run_test 72a "Test that remove suid works properly (bug5695) ===="
8530
8531 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8532         local perm
8533
8534         [ "$RUNAS_ID" = "$UID" ] &&
8535                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8536         [ "$RUNAS_ID" -eq 0 ] &&
8537                 skip_env "RUNAS_ID = 0 -- skipping"
8538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8539         # Check that testing environment is properly set up. Skip if not
8540         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8541                 skip_env "User $RUNAS_ID does not exist - skipping"
8542
8543         touch $DIR/${tfile}-f{g,u}
8544         test_mkdir $DIR/${tfile}-dg
8545         test_mkdir $DIR/${tfile}-du
8546         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8547         chmod g+s $DIR/${tfile}-{f,d}g
8548         chmod u+s $DIR/${tfile}-{f,d}u
8549         for perm in 777 2777 4777; do
8550                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8551                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8552                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8553                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8554         done
8555         true
8556 }
8557 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8558
8559 # bug 3462 - multiple simultaneous MDC requests
8560 test_73() {
8561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8562
8563         test_mkdir $DIR/d73-1
8564         test_mkdir $DIR/d73-2
8565         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8566         pid1=$!
8567
8568         lctl set_param fail_loc=0x80000129
8569         $MULTIOP $DIR/d73-1/f73-2 Oc &
8570         sleep 1
8571         lctl set_param fail_loc=0
8572
8573         $MULTIOP $DIR/d73-2/f73-3 Oc &
8574         pid3=$!
8575
8576         kill -USR1 $pid1
8577         wait $pid1 || return 1
8578
8579         sleep 25
8580
8581         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8582         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8583         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8584
8585         rm -rf $DIR/d73-*
8586 }
8587 run_test 73 "multiple MDC requests (should not deadlock)"
8588
8589 test_74a() { # bug 6149, 6184
8590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8591
8592         touch $DIR/f74a
8593         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8594         #
8595         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8596         # will spin in a tight reconnection loop
8597         $LCTL set_param fail_loc=0x8000030e
8598         # get any lock that won't be difficult - lookup works.
8599         ls $DIR/f74a
8600         $LCTL set_param fail_loc=0
8601         rm -f $DIR/f74a
8602         true
8603 }
8604 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8605
8606 test_74b() { # bug 13310
8607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8608
8609         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8610         #
8611         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8612         # will spin in a tight reconnection loop
8613         $LCTL set_param fail_loc=0x8000030e
8614         # get a "difficult" lock
8615         touch $DIR/f74b
8616         $LCTL set_param fail_loc=0
8617         rm -f $DIR/f74b
8618         true
8619 }
8620 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8621
8622 test_74c() {
8623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8624
8625         #define OBD_FAIL_LDLM_NEW_LOCK
8626         $LCTL set_param fail_loc=0x319
8627         touch $DIR/$tfile && error "touch successful"
8628         $LCTL set_param fail_loc=0
8629         true
8630 }
8631 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8632
8633 slab_lic=/sys/kernel/slab/lustre_inode_cache
8634 num_objects() {
8635         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8636         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8637                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8638 }
8639
8640 test_76() { # Now for b=20433, added originally in b=1443
8641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8642
8643         cancel_lru_locks osc
8644         # there may be some slab objects cached per core
8645         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8646         local before=$(num_objects)
8647         local count=$((512 * cpus))
8648         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8649         local margin=$((count / 10))
8650         if [[ -f $slab_lic/aliases ]]; then
8651                 local aliases=$(cat $slab_lic/aliases)
8652                 (( aliases > 0 )) && margin=$((margin * aliases))
8653         fi
8654
8655         echo "before slab objects: $before"
8656         for i in $(seq $count); do
8657                 touch $DIR/$tfile
8658                 rm -f $DIR/$tfile
8659         done
8660         cancel_lru_locks osc
8661         local after=$(num_objects)
8662         echo "created: $count, after slab objects: $after"
8663         # shared slab counts are not very accurate, allow significant margin
8664         # the main goal is that the cache growth is not permanently > $count
8665         while (( after > before + margin )); do
8666                 sleep 1
8667                 after=$(num_objects)
8668                 wait=$((wait + 1))
8669                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8670                 if (( wait > 60 )); then
8671                         error "inode slab grew from $before+$margin to $after"
8672                 fi
8673         done
8674 }
8675 run_test 76 "confirm clients recycle inodes properly ===="
8676
8677
8678 export ORIG_CSUM=""
8679 set_checksums()
8680 {
8681         # Note: in sptlrpc modes which enable its own bulk checksum, the
8682         # original crc32_le bulk checksum will be automatically disabled,
8683         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8684         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8685         # In this case set_checksums() will not be no-op, because sptlrpc
8686         # bulk checksum will be enabled all through the test.
8687
8688         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8689         lctl set_param -n osc.*.checksums $1
8690         return 0
8691 }
8692
8693 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8694                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8695 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8696                              tr -d [] | head -n1)}
8697 set_checksum_type()
8698 {
8699         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8700         rc=$?
8701         log "set checksum type to $1, rc = $rc"
8702         return $rc
8703 }
8704
8705 get_osc_checksum_type()
8706 {
8707         # arugment 1: OST name, like OST0000
8708         ost=$1
8709         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8710                         sed 's/.*\[\(.*\)\].*/\1/g')
8711         rc=$?
8712         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8713         echo $checksum_type
8714 }
8715
8716 F77_TMP=$TMP/f77-temp
8717 F77SZ=8
8718 setup_f77() {
8719         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8720                 error "error writing to $F77_TMP"
8721 }
8722
8723 test_77a() { # bug 10889
8724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8725         $GSS && skip_env "could not run with gss"
8726
8727         [ ! -f $F77_TMP ] && setup_f77
8728         set_checksums 1
8729         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8730         set_checksums 0
8731         rm -f $DIR/$tfile
8732 }
8733 run_test 77a "normal checksum read/write operation"
8734
8735 test_77b() { # bug 10889
8736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8737         $GSS && skip_env "could not run with gss"
8738
8739         [ ! -f $F77_TMP ] && setup_f77
8740         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8741         $LCTL set_param fail_loc=0x80000409
8742         set_checksums 1
8743
8744         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8745                 error "dd error: $?"
8746         $LCTL set_param fail_loc=0
8747
8748         for algo in $CKSUM_TYPES; do
8749                 cancel_lru_locks osc
8750                 set_checksum_type $algo
8751                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8752                 $LCTL set_param fail_loc=0x80000408
8753                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8754                 $LCTL set_param fail_loc=0
8755         done
8756         set_checksums 0
8757         set_checksum_type $ORIG_CSUM_TYPE
8758         rm -f $DIR/$tfile
8759 }
8760 run_test 77b "checksum error on client write, read"
8761
8762 cleanup_77c() {
8763         trap 0
8764         set_checksums 0
8765         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8766         $check_ost &&
8767                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8768         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8769         $check_ost && [ -n "$ost_file_prefix" ] &&
8770                 do_facet ost1 rm -f ${ost_file_prefix}\*
8771 }
8772
8773 test_77c() {
8774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8775         $GSS && skip_env "could not run with gss"
8776         remote_ost_nodsh && skip "remote OST with nodsh"
8777
8778         local bad1
8779         local osc_file_prefix
8780         local osc_file
8781         local check_ost=false
8782         local ost_file_prefix
8783         local ost_file
8784         local orig_cksum
8785         local dump_cksum
8786         local fid
8787
8788         # ensure corruption will occur on first OSS/OST
8789         $LFS setstripe -i 0 $DIR/$tfile
8790
8791         [ ! -f $F77_TMP ] && setup_f77
8792         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8793                 error "dd write error: $?"
8794         fid=$($LFS path2fid $DIR/$tfile)
8795
8796         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8797         then
8798                 check_ost=true
8799                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8800                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8801         else
8802                 echo "OSS do not support bulk pages dump upon error"
8803         fi
8804
8805         osc_file_prefix=$($LCTL get_param -n debug_path)
8806         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8807
8808         trap cleanup_77c EXIT
8809
8810         set_checksums 1
8811         # enable bulk pages dump upon error on Client
8812         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8813         # enable bulk pages dump upon error on OSS
8814         $check_ost &&
8815                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8816
8817         # flush Client cache to allow next read to reach OSS
8818         cancel_lru_locks osc
8819
8820         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8821         $LCTL set_param fail_loc=0x80000408
8822         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8823         $LCTL set_param fail_loc=0
8824
8825         rm -f $DIR/$tfile
8826
8827         # check cksum dump on Client
8828         osc_file=$(ls ${osc_file_prefix}*)
8829         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8830         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8831         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8832         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8833         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8834                      cksum)
8835         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8836         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8837                 error "dump content does not match on Client"
8838
8839         $check_ost || skip "No need to check cksum dump on OSS"
8840
8841         # check cksum dump on OSS
8842         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8843         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8844         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8845         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8846         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8847                 error "dump content does not match on OSS"
8848
8849         cleanup_77c
8850 }
8851 run_test 77c "checksum error on client read with debug"
8852
8853 test_77d() { # bug 10889
8854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8855         $GSS && skip_env "could not run with gss"
8856
8857         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8858         $LCTL set_param fail_loc=0x80000409
8859         set_checksums 1
8860         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8861                 error "direct write: rc=$?"
8862         $LCTL set_param fail_loc=0
8863         set_checksums 0
8864
8865         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8866         $LCTL set_param fail_loc=0x80000408
8867         set_checksums 1
8868         cancel_lru_locks osc
8869         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8870                 error "direct read: rc=$?"
8871         $LCTL set_param fail_loc=0
8872         set_checksums 0
8873 }
8874 run_test 77d "checksum error on OST direct write, read"
8875
8876 test_77f() { # bug 10889
8877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8878         $GSS && skip_env "could not run with gss"
8879
8880         set_checksums 1
8881         for algo in $CKSUM_TYPES; do
8882                 cancel_lru_locks osc
8883                 set_checksum_type $algo
8884                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8885                 $LCTL set_param fail_loc=0x409
8886                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8887                         error "direct write succeeded"
8888                 $LCTL set_param fail_loc=0
8889         done
8890         set_checksum_type $ORIG_CSUM_TYPE
8891         set_checksums 0
8892 }
8893 run_test 77f "repeat checksum error on write (expect error)"
8894
8895 test_77g() { # bug 10889
8896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8897         $GSS && skip_env "could not run with gss"
8898         remote_ost_nodsh && skip "remote OST with nodsh"
8899
8900         [ ! -f $F77_TMP ] && setup_f77
8901
8902         local file=$DIR/$tfile
8903         stack_trap "rm -f $file" EXIT
8904
8905         $LFS setstripe -c 1 -i 0 $file
8906         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8907         do_facet ost1 lctl set_param fail_loc=0x8000021a
8908         set_checksums 1
8909         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8910                 error "write error: rc=$?"
8911         do_facet ost1 lctl set_param fail_loc=0
8912         set_checksums 0
8913
8914         cancel_lru_locks osc
8915         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8916         do_facet ost1 lctl set_param fail_loc=0x8000021b
8917         set_checksums 1
8918         cmp $F77_TMP $file || error "file compare failed"
8919         do_facet ost1 lctl set_param fail_loc=0
8920         set_checksums 0
8921 }
8922 run_test 77g "checksum error on OST write, read"
8923
8924 test_77k() { # LU-10906
8925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8926         $GSS && skip_env "could not run with gss"
8927
8928         local cksum_param="osc.$FSNAME*.checksums"
8929         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8930         local checksum
8931         local i
8932
8933         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8934         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
8935         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
8936
8937         for i in 0 1; do
8938                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8939                         error "failed to set checksum=$i on MGS"
8940                 wait_update $HOSTNAME "$get_checksum" $i
8941                 #remount
8942                 echo "remount client, checksum should be $i"
8943                 remount_client $MOUNT || error "failed to remount client"
8944                 checksum=$(eval $get_checksum)
8945                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8946         done
8947         # remove persistent param to avoid races with checksum mountopt below
8948         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8949                 error "failed to delete checksum on MGS"
8950
8951         for opt in "checksum" "nochecksum"; do
8952                 #remount with mount option
8953                 echo "remount client with option $opt, checksum should be $i"
8954                 umount_client $MOUNT || error "failed to umount client"
8955                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8956                         error "failed to mount client with option '$opt'"
8957                 checksum=$(eval $get_checksum)
8958                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8959                 i=$((i - 1))
8960         done
8961
8962         remount_client $MOUNT || error "failed to remount client"
8963 }
8964 run_test 77k "enable/disable checksum correctly"
8965
8966 test_77l() {
8967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8968         $GSS && skip_env "could not run with gss"
8969
8970         set_checksums 1
8971         stack_trap "set_checksums $ORIG_CSUM" EXIT
8972         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8973
8974         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8975
8976         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8977         for algo in $CKSUM_TYPES; do
8978                 set_checksum_type $algo || error "fail to set checksum type $algo"
8979                 osc_algo=$(get_osc_checksum_type OST0000)
8980                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8981
8982                 # no locks, no reqs to let the connection idle
8983                 cancel_lru_locks osc
8984                 lru_resize_disable osc
8985                 wait_osc_import_state client ost1 IDLE
8986
8987                 # ensure ost1 is connected
8988                 stat $DIR/$tfile >/dev/null || error "can't stat"
8989                 wait_osc_import_state client ost1 FULL
8990
8991                 osc_algo=$(get_osc_checksum_type OST0000)
8992                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8993         done
8994         return 0
8995 }
8996 run_test 77l "preferred checksum type is remembered after reconnected"
8997
8998 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8999 rm -f $F77_TMP
9000 unset F77_TMP
9001
9002 cleanup_test_78() {
9003         trap 0
9004         rm -f $DIR/$tfile
9005 }
9006
9007 test_78() { # bug 10901
9008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9009         remote_ost || skip_env "local OST"
9010
9011         NSEQ=5
9012         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9013         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9014         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9015         echo "MemTotal: $MEMTOTAL"
9016
9017         # reserve 256MB of memory for the kernel and other running processes,
9018         # and then take 1/2 of the remaining memory for the read/write buffers.
9019         if [ $MEMTOTAL -gt 512 ] ;then
9020                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9021         else
9022                 # for those poor memory-starved high-end clusters...
9023                 MEMTOTAL=$((MEMTOTAL / 2))
9024         fi
9025         echo "Mem to use for directio: $MEMTOTAL"
9026
9027         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9028         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9029         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9030         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9031                 head -n1)
9032         echo "Smallest OST: $SMALLESTOST"
9033         [[ $SMALLESTOST -lt 10240 ]] &&
9034                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9035
9036         trap cleanup_test_78 EXIT
9037
9038         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9039                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9040
9041         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9042         echo "File size: $F78SIZE"
9043         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9044         for i in $(seq 1 $NSEQ); do
9045                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9046                 echo directIO rdwr round $i of $NSEQ
9047                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9048         done
9049
9050         cleanup_test_78
9051 }
9052 run_test 78 "handle large O_DIRECT writes correctly ============"
9053
9054 test_79() { # bug 12743
9055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9056
9057         wait_delete_completed
9058
9059         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9060         BKFREE=$(calc_osc_kbytes kbytesfree)
9061         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9062
9063         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9064         DFTOTAL=`echo $STRING | cut -d, -f1`
9065         DFUSED=`echo $STRING  | cut -d, -f2`
9066         DFAVAIL=`echo $STRING | cut -d, -f3`
9067         DFFREE=$(($DFTOTAL - $DFUSED))
9068
9069         ALLOWANCE=$((64 * $OSTCOUNT))
9070
9071         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9072            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9073                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9074         fi
9075         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9076            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9077                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9078         fi
9079         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9080            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9081                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9082         fi
9083 }
9084 run_test 79 "df report consistency check ======================="
9085
9086 test_80() { # bug 10718
9087         remote_ost_nodsh && skip "remote OST with nodsh"
9088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9089
9090         # relax strong synchronous semantics for slow backends like ZFS
9091         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9092                 local soc="obdfilter.*.sync_lock_cancel"
9093                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9094
9095                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9096                 if [ -z "$save" ]; then
9097                         soc="obdfilter.*.sync_on_lock_cancel"
9098                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9099                 fi
9100
9101                 if [ "$save" != "never" ]; then
9102                         local hosts=$(comma_list $(osts_nodes))
9103
9104                         do_nodes $hosts $LCTL set_param $soc=never
9105                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9106                 fi
9107         fi
9108
9109         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9110         sync; sleep 1; sync
9111         local before=$(date +%s)
9112         cancel_lru_locks osc
9113         local after=$(date +%s)
9114         local diff=$((after - before))
9115         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9116
9117         rm -f $DIR/$tfile
9118 }
9119 run_test 80 "Page eviction is equally fast at high offsets too"
9120
9121 test_81a() { # LU-456
9122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9123         remote_ost_nodsh && skip "remote OST with nodsh"
9124
9125         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9126         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9127         do_facet ost1 lctl set_param fail_loc=0x80000228
9128
9129         # write should trigger a retry and success
9130         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9131         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9132         RC=$?
9133         if [ $RC -ne 0 ] ; then
9134                 error "write should success, but failed for $RC"
9135         fi
9136 }
9137 run_test 81a "OST should retry write when get -ENOSPC ==============="
9138
9139 test_81b() { # LU-456
9140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9141         remote_ost_nodsh && skip "remote OST with nodsh"
9142
9143         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9144         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9145         do_facet ost1 lctl set_param fail_loc=0x228
9146
9147         # write should retry several times and return -ENOSPC finally
9148         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9149         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9150         RC=$?
9151         ENOSPC=28
9152         if [ $RC -ne $ENOSPC ] ; then
9153                 error "dd should fail for -ENOSPC, but succeed."
9154         fi
9155 }
9156 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9157
9158 test_99() {
9159         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9160
9161         test_mkdir $DIR/$tdir.cvsroot
9162         chown $RUNAS_ID $DIR/$tdir.cvsroot
9163
9164         cd $TMP
9165         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9166
9167         cd /etc/init.d
9168         # some versions of cvs import exit(1) when asked to import links or
9169         # files they can't read.  ignore those files.
9170         local toignore=$(find . -type l -printf '-I %f\n' -o \
9171                          ! -perm /4 -printf '-I %f\n')
9172         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9173                 $tdir.reposname vtag rtag
9174
9175         cd $DIR
9176         test_mkdir $DIR/$tdir.reposname
9177         chown $RUNAS_ID $DIR/$tdir.reposname
9178         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9179
9180         cd $DIR/$tdir.reposname
9181         $RUNAS touch foo99
9182         $RUNAS cvs add -m 'addmsg' foo99
9183         $RUNAS cvs update
9184         $RUNAS cvs commit -m 'nomsg' foo99
9185         rm -fr $DIR/$tdir.cvsroot
9186 }
9187 run_test 99 "cvs strange file/directory operations"
9188
9189 test_100() {
9190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9191         [[ "$NETTYPE" =~ tcp ]] ||
9192                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9193         remote_ost_nodsh && skip "remote OST with nodsh"
9194         remote_mds_nodsh && skip "remote MDS with nodsh"
9195         remote_servers ||
9196                 skip "useless for local single node setup"
9197
9198         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9199                 [ "$PROT" != "tcp" ] && continue
9200                 RPORT=$(echo $REMOTE | cut -d: -f2)
9201                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9202
9203                 rc=0
9204                 LPORT=`echo $LOCAL | cut -d: -f2`
9205                 if [ $LPORT -ge 1024 ]; then
9206                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9207                         netstat -tna
9208                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9209                 fi
9210         done
9211         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9212 }
9213 run_test 100 "check local port using privileged port ==========="
9214
9215 function get_named_value()
9216 {
9217     local tag
9218
9219     tag=$1
9220     while read ;do
9221         line=$REPLY
9222         case $line in
9223         $tag*)
9224             echo $line | sed "s/^$tag[ ]*//"
9225             break
9226             ;;
9227         esac
9228     done
9229 }
9230
9231 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9232                    awk '/^max_cached_mb/ { print $2 }')
9233
9234 cleanup_101a() {
9235         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9236         trap 0
9237 }
9238
9239 test_101a() {
9240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9241
9242         local s
9243         local discard
9244         local nreads=10000
9245         local cache_limit=32
9246
9247         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9248         trap cleanup_101a EXIT
9249         $LCTL set_param -n llite.*.read_ahead_stats 0
9250         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9251
9252         #
9253         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9254         #
9255         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9256         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9257
9258         discard=0
9259         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9260                 get_named_value 'read but discarded' | cut -d" " -f1); do
9261                         discard=$(($discard + $s))
9262         done
9263         cleanup_101a
9264
9265         $LCTL get_param osc.*-osc*.rpc_stats
9266         $LCTL get_param llite.*.read_ahead_stats
9267
9268         # Discard is generally zero, but sometimes a few random reads line up
9269         # and trigger larger readahead, which is wasted & leads to discards.
9270         if [[ $(($discard)) -gt $nreads ]]; then
9271                 error "too many ($discard) discarded pages"
9272         fi
9273         rm -f $DIR/$tfile || true
9274 }
9275 run_test 101a "check read-ahead for random reads"
9276
9277 setup_test101bc() {
9278         test_mkdir $DIR/$tdir
9279         local ssize=$1
9280         local FILE_LENGTH=$2
9281         STRIPE_OFFSET=0
9282
9283         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9284
9285         local list=$(comma_list $(osts_nodes))
9286         set_osd_param $list '' read_cache_enable 0
9287         set_osd_param $list '' writethrough_cache_enable 0
9288
9289         trap cleanup_test101bc EXIT
9290         # prepare the read-ahead file
9291         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9292
9293         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9294                                 count=$FILE_SIZE_MB 2> /dev/null
9295
9296 }
9297
9298 cleanup_test101bc() {
9299         trap 0
9300         rm -rf $DIR/$tdir
9301         rm -f $DIR/$tfile
9302
9303         local list=$(comma_list $(osts_nodes))
9304         set_osd_param $list '' read_cache_enable 1
9305         set_osd_param $list '' writethrough_cache_enable 1
9306 }
9307
9308 calc_total() {
9309         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9310 }
9311
9312 ra_check_101() {
9313         local READ_SIZE=$1
9314         local STRIPE_SIZE=$2
9315         local FILE_LENGTH=$3
9316         local RA_INC=1048576
9317         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9318         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9319                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9320         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9321                         get_named_value 'read but discarded' |
9322                         cut -d" " -f1 | calc_total)
9323         if [[ $DISCARD -gt $discard_limit ]]; then
9324                 $LCTL get_param llite.*.read_ahead_stats
9325                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9326         else
9327                 echo "Read-ahead success for size ${READ_SIZE}"
9328         fi
9329 }
9330
9331 test_101b() {
9332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9333         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9334
9335         local STRIPE_SIZE=1048576
9336         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9337
9338         if [ $SLOW == "yes" ]; then
9339                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9340         else
9341                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9342         fi
9343
9344         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9345
9346         # prepare the read-ahead file
9347         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9348         cancel_lru_locks osc
9349         for BIDX in 2 4 8 16 32 64 128 256
9350         do
9351                 local BSIZE=$((BIDX*4096))
9352                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9353                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9354                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9355                 $LCTL set_param -n llite.*.read_ahead_stats 0
9356                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9357                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9358                 cancel_lru_locks osc
9359                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9360         done
9361         cleanup_test101bc
9362         true
9363 }
9364 run_test 101b "check stride-io mode read-ahead ================="
9365
9366 test_101c() {
9367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9368
9369         local STRIPE_SIZE=1048576
9370         local FILE_LENGTH=$((STRIPE_SIZE*100))
9371         local nreads=10000
9372         local rsize=65536
9373         local osc_rpc_stats
9374
9375         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9376
9377         cancel_lru_locks osc
9378         $LCTL set_param osc.*.rpc_stats 0
9379         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9380         $LCTL get_param osc.*.rpc_stats
9381         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9382                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9383                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9384                 local size
9385
9386                 if [ $lines -le 20 ]; then
9387                         echo "continue debug"
9388                         continue
9389                 fi
9390                 for size in 1 2 4 8; do
9391                         local rpc=$(echo "$stats" |
9392                                     awk '($1 == "'$size':") {print $2; exit; }')
9393                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9394                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9395                 done
9396                 echo "$osc_rpc_stats check passed!"
9397         done
9398         cleanup_test101bc
9399         true
9400 }
9401 run_test 101c "check stripe_size aligned read-ahead ================="
9402
9403 test_101d() {
9404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9405
9406         local file=$DIR/$tfile
9407         local sz_MB=${FILESIZE_101d:-80}
9408         local ra_MB=${READAHEAD_MB:-40}
9409
9410         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9411         [ $free_MB -lt $sz_MB ] &&
9412                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9413
9414         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9415         $LFS setstripe -c -1 $file || error "setstripe failed"
9416
9417         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9418         echo Cancel LRU locks on lustre client to flush the client cache
9419         cancel_lru_locks osc
9420
9421         echo Disable read-ahead
9422         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9423         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9424         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9425         $LCTL get_param -n llite.*.max_read_ahead_mb
9426
9427         echo "Reading the test file $file with read-ahead disabled"
9428         local sz_KB=$((sz_MB * 1024 / 4))
9429         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9430         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9431         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9432                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9433
9434         echo "Cancel LRU locks on lustre client to flush the client cache"
9435         cancel_lru_locks osc
9436         echo Enable read-ahead with ${ra_MB}MB
9437         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9438
9439         echo "Reading the test file $file with read-ahead enabled"
9440         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9441                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9442
9443         echo "read-ahead disabled time read $raOFF"
9444         echo "read-ahead enabled time read $raON"
9445
9446         rm -f $file
9447         wait_delete_completed
9448
9449         # use awk for this check instead of bash because it handles decimals
9450         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9451                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9452 }
9453 run_test 101d "file read with and without read-ahead enabled"
9454
9455 test_101e() {
9456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9457
9458         local file=$DIR/$tfile
9459         local size_KB=500  #KB
9460         local count=100
9461         local bsize=1024
9462
9463         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9464         local need_KB=$((count * size_KB))
9465         [[ $free_KB -le $need_KB ]] &&
9466                 skip_env "Need free space $need_KB, have $free_KB"
9467
9468         echo "Creating $count ${size_KB}K test files"
9469         for ((i = 0; i < $count; i++)); do
9470                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9471         done
9472
9473         echo "Cancel LRU locks on lustre client to flush the client cache"
9474         cancel_lru_locks $OSC
9475
9476         echo "Reset readahead stats"
9477         $LCTL set_param -n llite.*.read_ahead_stats 0
9478
9479         for ((i = 0; i < $count; i++)); do
9480                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9481         done
9482
9483         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9484                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9485
9486         for ((i = 0; i < $count; i++)); do
9487                 rm -rf $file.$i 2>/dev/null
9488         done
9489
9490         #10000 means 20% reads are missing in readahead
9491         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9492 }
9493 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9494
9495 test_101f() {
9496         which iozone || skip_env "no iozone installed"
9497
9498         local old_debug=$($LCTL get_param debug)
9499         old_debug=${old_debug#*=}
9500         $LCTL set_param debug="reada mmap"
9501
9502         # create a test file
9503         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9504
9505         echo Cancel LRU locks on lustre client to flush the client cache
9506         cancel_lru_locks osc
9507
9508         echo Reset readahead stats
9509         $LCTL set_param -n llite.*.read_ahead_stats 0
9510
9511         echo mmap read the file with small block size
9512         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9513                 > /dev/null 2>&1
9514
9515         echo checking missing pages
9516         $LCTL get_param llite.*.read_ahead_stats
9517         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9518                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9519
9520         $LCTL set_param debug="$old_debug"
9521         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9522         rm -f $DIR/$tfile
9523 }
9524 run_test 101f "check mmap read performance"
9525
9526 test_101g_brw_size_test() {
9527         local mb=$1
9528         local pages=$((mb * 1048576 / PAGE_SIZE))
9529         local file=$DIR/$tfile
9530
9531         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9532                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9533         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9534                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9535                         return 2
9536         done
9537
9538         stack_trap "rm -f $file" EXIT
9539         $LCTL set_param -n osc.*.rpc_stats=0
9540
9541         # 10 RPCs should be enough for the test
9542         local count=10
9543         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9544                 { error "dd write ${mb} MB blocks failed"; return 3; }
9545         cancel_lru_locks osc
9546         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9547                 { error "dd write ${mb} MB blocks failed"; return 4; }
9548
9549         # calculate number of full-sized read and write RPCs
9550         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9551                 sed -n '/pages per rpc/,/^$/p' |
9552                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9553                 END { print reads,writes }'))
9554         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
9555                 return 5
9556         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
9557                 return 6
9558
9559         return 0
9560 }
9561
9562 test_101g() {
9563         remote_ost_nodsh && skip "remote OST with nodsh"
9564
9565         local rpcs
9566         local osts=$(get_facets OST)
9567         local list=$(comma_list $(osts_nodes))
9568         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9569         local brw_size="obdfilter.*.brw_size"
9570
9571         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9572
9573         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9574
9575         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9576                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9577                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9578            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9579                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9580                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9581
9582                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9583                         suffix="M"
9584
9585                 if [[ $orig_mb -lt 16 ]]; then
9586                         save_lustre_params $osts "$brw_size" > $p
9587                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9588                                 error "set 16MB RPC size failed"
9589
9590                         echo "remount client to enable new RPC size"
9591                         remount_client $MOUNT || error "remount_client failed"
9592                 fi
9593
9594                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9595                 # should be able to set brw_size=12, but no rpc_stats for that
9596                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9597         fi
9598
9599         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9600
9601         if [[ $orig_mb -lt 16 ]]; then
9602                 restore_lustre_params < $p
9603                 remount_client $MOUNT || error "remount_client restore failed"
9604         fi
9605
9606         rm -f $p $DIR/$tfile
9607 }
9608 run_test 101g "Big bulk(4/16 MiB) readahead"
9609
9610 test_101h() {
9611         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9612
9613         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9614                 error "dd 70M file failed"
9615         echo Cancel LRU locks on lustre client to flush the client cache
9616         cancel_lru_locks osc
9617
9618         echo "Reset readahead stats"
9619         $LCTL set_param -n llite.*.read_ahead_stats 0
9620
9621         echo "Read 10M of data but cross 64M bundary"
9622         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9623         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9624                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9625         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9626         rm -f $p $DIR/$tfile
9627 }
9628 run_test 101h "Readahead should cover current read window"
9629
9630 test_101i() {
9631         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9632                 error "dd 10M file failed"
9633
9634         local max_per_file_mb=$($LCTL get_param -n \
9635                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9636         cancel_lru_locks osc
9637         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9638         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9639                 error "set max_read_ahead_per_file_mb to 1 failed"
9640
9641         echo "Reset readahead stats"
9642         $LCTL set_param llite.*.read_ahead_stats=0
9643
9644         dd if=$DIR/$tfile of=/dev/null bs=2M
9645
9646         $LCTL get_param llite.*.read_ahead_stats
9647         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9648                      awk '/misses/ { print $2 }')
9649         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9650         rm -f $DIR/$tfile
9651 }
9652 run_test 101i "allow current readahead to exceed reservation"
9653
9654 test_101j() {
9655         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9656                 error "setstripe $DIR/$tfile failed"
9657         local file_size=$((1048576 * 16))
9658         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9659         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9660
9661         echo Disable read-ahead
9662         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9663
9664         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9665         for blk in $PAGE_SIZE 1048576 $file_size; do
9666                 cancel_lru_locks osc
9667                 echo "Reset readahead stats"
9668                 $LCTL set_param -n llite.*.read_ahead_stats=0
9669                 local count=$(($file_size / $blk))
9670                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9671                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9672                              get_named_value 'failed to fast read' |
9673                              cut -d" " -f1 | calc_total)
9674                 $LCTL get_param -n llite.*.read_ahead_stats
9675                 [ $miss -eq $count ] || error "expected $count got $miss"
9676         done
9677
9678         rm -f $p $DIR/$tfile
9679 }
9680 run_test 101j "A complete read block should be submitted when no RA"
9681
9682 setup_test102() {
9683         test_mkdir $DIR/$tdir
9684         chown $RUNAS_ID $DIR/$tdir
9685         STRIPE_SIZE=65536
9686         STRIPE_OFFSET=1
9687         STRIPE_COUNT=$OSTCOUNT
9688         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9689
9690         trap cleanup_test102 EXIT
9691         cd $DIR
9692         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9693         cd $DIR/$tdir
9694         for num in 1 2 3 4; do
9695                 for count in $(seq 1 $STRIPE_COUNT); do
9696                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9697                                 local size=`expr $STRIPE_SIZE \* $num`
9698                                 local file=file"$num-$idx-$count"
9699                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9700                         done
9701                 done
9702         done
9703
9704         cd $DIR
9705         $1 tar cf $TMP/f102.tar $tdir --xattrs
9706 }
9707
9708 cleanup_test102() {
9709         trap 0
9710         rm -f $TMP/f102.tar
9711         rm -rf $DIR/d0.sanity/d102
9712 }
9713
9714 test_102a() {
9715         [ "$UID" != 0 ] && skip "must run as root"
9716         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9717                 skip_env "must have user_xattr"
9718
9719         [ -z "$(which setfattr 2>/dev/null)" ] &&
9720                 skip_env "could not find setfattr"
9721
9722         local testfile=$DIR/$tfile
9723
9724         touch $testfile
9725         echo "set/get xattr..."
9726         setfattr -n trusted.name1 -v value1 $testfile ||
9727                 error "setfattr -n trusted.name1=value1 $testfile failed"
9728         getfattr -n trusted.name1 $testfile 2> /dev/null |
9729           grep "trusted.name1=.value1" ||
9730                 error "$testfile missing trusted.name1=value1"
9731
9732         setfattr -n user.author1 -v author1 $testfile ||
9733                 error "setfattr -n user.author1=author1 $testfile failed"
9734         getfattr -n user.author1 $testfile 2> /dev/null |
9735           grep "user.author1=.author1" ||
9736                 error "$testfile missing trusted.author1=author1"
9737
9738         echo "listxattr..."
9739         setfattr -n trusted.name2 -v value2 $testfile ||
9740                 error "$testfile unable to set trusted.name2"
9741         setfattr -n trusted.name3 -v value3 $testfile ||
9742                 error "$testfile unable to set trusted.name3"
9743         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9744             grep "trusted.name" | wc -l) -eq 3 ] ||
9745                 error "$testfile missing 3 trusted.name xattrs"
9746
9747         setfattr -n user.author2 -v author2 $testfile ||
9748                 error "$testfile unable to set user.author2"
9749         setfattr -n user.author3 -v author3 $testfile ||
9750                 error "$testfile unable to set user.author3"
9751         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9752             grep "user.author" | wc -l) -eq 3 ] ||
9753                 error "$testfile missing 3 user.author xattrs"
9754
9755         echo "remove xattr..."
9756         setfattr -x trusted.name1 $testfile ||
9757                 error "$testfile error deleting trusted.name1"
9758         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9759                 error "$testfile did not delete trusted.name1 xattr"
9760
9761         setfattr -x user.author1 $testfile ||
9762                 error "$testfile error deleting user.author1"
9763         echo "set lustre special xattr ..."
9764         $LFS setstripe -c1 $testfile
9765         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9766                 awk -F "=" '/trusted.lov/ { print $2 }' )
9767         setfattr -n "trusted.lov" -v $lovea $testfile ||
9768                 error "$testfile doesn't ignore setting trusted.lov again"
9769         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9770                 error "$testfile allow setting invalid trusted.lov"
9771         rm -f $testfile
9772 }
9773 run_test 102a "user xattr test =================================="
9774
9775 check_102b_layout() {
9776         local layout="$*"
9777         local testfile=$DIR/$tfile
9778
9779         echo "test layout '$layout'"
9780         $LFS setstripe $layout $testfile || error "setstripe failed"
9781         $LFS getstripe -y $testfile
9782
9783         echo "get/set/list trusted.lov xattr ..." # b=10930
9784         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9785         [[ "$value" =~ "trusted.lov" ]] ||
9786                 error "can't get trusted.lov from $testfile"
9787         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9788                 error "getstripe failed"
9789
9790         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9791
9792         value=$(cut -d= -f2 <<<$value)
9793         # LU-13168: truncated xattr should fail if short lov_user_md header
9794         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9795                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9796         for len in $lens; do
9797                 echo "setfattr $len $testfile.2"
9798                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9799                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9800         done
9801         local stripe_size=$($LFS getstripe -S $testfile.2)
9802         local stripe_count=$($LFS getstripe -c $testfile.2)
9803         [[ $stripe_size -eq 65536 ]] ||
9804                 error "stripe size $stripe_size != 65536"
9805         [[ $stripe_count -eq $stripe_count_orig ]] ||
9806                 error "stripe count $stripe_count != $stripe_count_orig"
9807         rm $testfile $testfile.2
9808 }
9809
9810 test_102b() {
9811         [ -z "$(which setfattr 2>/dev/null)" ] &&
9812                 skip_env "could not find setfattr"
9813         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9814
9815         # check plain layout
9816         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9817
9818         # and also check composite layout
9819         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9820
9821 }
9822 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9823
9824 test_102c() {
9825         [ -z "$(which setfattr 2>/dev/null)" ] &&
9826                 skip_env "could not find setfattr"
9827         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9828
9829         # b10930: get/set/list lustre.lov xattr
9830         echo "get/set/list lustre.lov xattr ..."
9831         test_mkdir $DIR/$tdir
9832         chown $RUNAS_ID $DIR/$tdir
9833         local testfile=$DIR/$tdir/$tfile
9834         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9835                 error "setstripe failed"
9836         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9837                 error "getstripe failed"
9838         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9839         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9840
9841         local testfile2=${testfile}2
9842         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9843                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9844
9845         $RUNAS $MCREATE $testfile2
9846         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9847         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9848         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9849         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9850         [ $stripe_count -eq $STRIPECOUNT ] ||
9851                 error "stripe count $stripe_count != $STRIPECOUNT"
9852 }
9853 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9854
9855 compare_stripe_info1() {
9856         local stripe_index_all_zero=true
9857
9858         for num in 1 2 3 4; do
9859                 for count in $(seq 1 $STRIPE_COUNT); do
9860                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9861                                 local size=$((STRIPE_SIZE * num))
9862                                 local file=file"$num-$offset-$count"
9863                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9864                                 [[ $stripe_size -ne $size ]] &&
9865                                     error "$file: size $stripe_size != $size"
9866                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9867                                 # allow fewer stripes to be created, ORI-601
9868                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9869                                     error "$file: count $stripe_count != $count"
9870                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9871                                 [[ $stripe_index -ne 0 ]] &&
9872                                         stripe_index_all_zero=false
9873                         done
9874                 done
9875         done
9876         $stripe_index_all_zero &&
9877                 error "all files are being extracted starting from OST index 0"
9878         return 0
9879 }
9880
9881 have_xattrs_include() {
9882         tar --help | grep -q xattrs-include &&
9883                 echo --xattrs-include="lustre.*"
9884 }
9885
9886 test_102d() {
9887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9888         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9889
9890         XINC=$(have_xattrs_include)
9891         setup_test102
9892         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9893         cd $DIR/$tdir/$tdir
9894         compare_stripe_info1
9895 }
9896 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9897
9898 test_102f() {
9899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9900         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9901
9902         XINC=$(have_xattrs_include)
9903         setup_test102
9904         test_mkdir $DIR/$tdir.restore
9905         cd $DIR
9906         tar cf - --xattrs $tdir | tar xf - \
9907                 -C $DIR/$tdir.restore --xattrs $XINC
9908         cd $DIR/$tdir.restore/$tdir
9909         compare_stripe_info1
9910 }
9911 run_test 102f "tar copy files, not keep osts"
9912
9913 grow_xattr() {
9914         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9915                 skip "must have user_xattr"
9916         [ -z "$(which setfattr 2>/dev/null)" ] &&
9917                 skip_env "could not find setfattr"
9918         [ -z "$(which getfattr 2>/dev/null)" ] &&
9919                 skip_env "could not find getfattr"
9920
9921         local xsize=${1:-1024}  # in bytes
9922         local file=$DIR/$tfile
9923         local value="$(generate_string $xsize)"
9924         local xbig=trusted.big
9925         local toobig=$2
9926
9927         touch $file
9928         log "save $xbig on $file"
9929         if [ -z "$toobig" ]
9930         then
9931                 setfattr -n $xbig -v $value $file ||
9932                         error "saving $xbig on $file failed"
9933         else
9934                 setfattr -n $xbig -v $value $file &&
9935                         error "saving $xbig on $file succeeded"
9936                 return 0
9937         fi
9938
9939         local orig=$(get_xattr_value $xbig $file)
9940         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9941
9942         local xsml=trusted.sml
9943         log "save $xsml on $file"
9944         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9945
9946         local new=$(get_xattr_value $xbig $file)
9947         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9948
9949         log "grow $xsml on $file"
9950         setfattr -n $xsml -v "$value" $file ||
9951                 error "growing $xsml on $file failed"
9952
9953         new=$(get_xattr_value $xbig $file)
9954         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9955         log "$xbig still valid after growing $xsml"
9956
9957         rm -f $file
9958 }
9959
9960 test_102h() { # bug 15777
9961         grow_xattr 1024
9962 }
9963 run_test 102h "grow xattr from inside inode to external block"
9964
9965 test_102ha() {
9966         large_xattr_enabled || skip_env "ea_inode feature disabled"
9967
9968         echo "setting xattr of max xattr size: $(max_xattr_size)"
9969         grow_xattr $(max_xattr_size)
9970
9971         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9972         echo "This should fail:"
9973         grow_xattr $(($(max_xattr_size) + 10)) 1
9974 }
9975 run_test 102ha "grow xattr from inside inode to external inode"
9976
9977 test_102i() { # bug 17038
9978         [ -z "$(which getfattr 2>/dev/null)" ] &&
9979                 skip "could not find getfattr"
9980
9981         touch $DIR/$tfile
9982         ln -s $DIR/$tfile $DIR/${tfile}link
9983         getfattr -n trusted.lov $DIR/$tfile ||
9984                 error "lgetxattr on $DIR/$tfile failed"
9985         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9986                 grep -i "no such attr" ||
9987                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9988         rm -f $DIR/$tfile $DIR/${tfile}link
9989 }
9990 run_test 102i "lgetxattr test on symbolic link ============"
9991
9992 test_102j() {
9993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9994         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9995
9996         XINC=$(have_xattrs_include)
9997         setup_test102 "$RUNAS"
9998         chown $RUNAS_ID $DIR/$tdir
9999         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10000         cd $DIR/$tdir/$tdir
10001         compare_stripe_info1 "$RUNAS"
10002 }
10003 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10004
10005 test_102k() {
10006         [ -z "$(which setfattr 2>/dev/null)" ] &&
10007                 skip "could not find setfattr"
10008
10009         touch $DIR/$tfile
10010         # b22187 just check that does not crash for regular file.
10011         setfattr -n trusted.lov $DIR/$tfile
10012         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10013         local test_kdir=$DIR/$tdir
10014         test_mkdir $test_kdir
10015         local default_size=$($LFS getstripe -S $test_kdir)
10016         local default_count=$($LFS getstripe -c $test_kdir)
10017         local default_offset=$($LFS getstripe -i $test_kdir)
10018         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10019                 error 'dir setstripe failed'
10020         setfattr -n trusted.lov $test_kdir
10021         local stripe_size=$($LFS getstripe -S $test_kdir)
10022         local stripe_count=$($LFS getstripe -c $test_kdir)
10023         local stripe_offset=$($LFS getstripe -i $test_kdir)
10024         [ $stripe_size -eq $default_size ] ||
10025                 error "stripe size $stripe_size != $default_size"
10026         [ $stripe_count -eq $default_count ] ||
10027                 error "stripe count $stripe_count != $default_count"
10028         [ $stripe_offset -eq $default_offset ] ||
10029                 error "stripe offset $stripe_offset != $default_offset"
10030         rm -rf $DIR/$tfile $test_kdir
10031 }
10032 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10033
10034 test_102l() {
10035         [ -z "$(which getfattr 2>/dev/null)" ] &&
10036                 skip "could not find getfattr"
10037
10038         # LU-532 trusted. xattr is invisible to non-root
10039         local testfile=$DIR/$tfile
10040
10041         touch $testfile
10042
10043         echo "listxattr as user..."
10044         chown $RUNAS_ID $testfile
10045         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10046             grep -q "trusted" &&
10047                 error "$testfile trusted xattrs are user visible"
10048
10049         return 0;
10050 }
10051 run_test 102l "listxattr size test =================================="
10052
10053 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10054         local path=$DIR/$tfile
10055         touch $path
10056
10057         listxattr_size_check $path || error "listattr_size_check $path failed"
10058 }
10059 run_test 102m "Ensure listxattr fails on small bufffer ========"
10060
10061 cleanup_test102
10062
10063 getxattr() { # getxattr path name
10064         # Return the base64 encoding of the value of xattr name on path.
10065         local path=$1
10066         local name=$2
10067
10068         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10069         # file: $path
10070         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10071         #
10072         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10073
10074         getfattr --absolute-names --encoding=base64 --name=$name $path |
10075                 awk -F= -v name=$name '$1 == name {
10076                         print substr($0, index($0, "=") + 1);
10077         }'
10078 }
10079
10080 test_102n() { # LU-4101 mdt: protect internal xattrs
10081         [ -z "$(which setfattr 2>/dev/null)" ] &&
10082                 skip "could not find setfattr"
10083         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10084         then
10085                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10086         fi
10087
10088         local file0=$DIR/$tfile.0
10089         local file1=$DIR/$tfile.1
10090         local xattr0=$TMP/$tfile.0
10091         local xattr1=$TMP/$tfile.1
10092         local namelist="lov lma lmv link fid version som hsm"
10093         local name
10094         local value
10095
10096         rm -rf $file0 $file1 $xattr0 $xattr1
10097         touch $file0 $file1
10098
10099         # Get 'before' xattrs of $file1.
10100         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10101
10102         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10103                 namelist+=" lfsck_namespace"
10104         for name in $namelist; do
10105                 # Try to copy xattr from $file0 to $file1.
10106                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10107
10108                 setfattr --name=trusted.$name --value="$value" $file1 ||
10109                         error "setxattr 'trusted.$name' failed"
10110
10111                 # Try to set a garbage xattr.
10112                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10113
10114                 if [[ x$name == "xlov" ]]; then
10115                         setfattr --name=trusted.lov --value="$value" $file1 &&
10116                         error "setxattr invalid 'trusted.lov' success"
10117                 else
10118                         setfattr --name=trusted.$name --value="$value" $file1 ||
10119                                 error "setxattr invalid 'trusted.$name' failed"
10120                 fi
10121
10122                 # Try to remove the xattr from $file1. We don't care if this
10123                 # appears to succeed or fail, we just don't want there to be
10124                 # any changes or crashes.
10125                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10126         done
10127
10128         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10129         then
10130                 name="lfsck_ns"
10131                 # Try to copy xattr from $file0 to $file1.
10132                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10133
10134                 setfattr --name=trusted.$name --value="$value" $file1 ||
10135                         error "setxattr 'trusted.$name' failed"
10136
10137                 # Try to set a garbage xattr.
10138                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10139
10140                 setfattr --name=trusted.$name --value="$value" $file1 ||
10141                         error "setxattr 'trusted.$name' failed"
10142
10143                 # Try to remove the xattr from $file1. We don't care if this
10144                 # appears to succeed or fail, we just don't want there to be
10145                 # any changes or crashes.
10146                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10147         fi
10148
10149         # Get 'after' xattrs of file1.
10150         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10151
10152         if ! diff $xattr0 $xattr1; then
10153                 error "before and after xattrs of '$file1' differ"
10154         fi
10155
10156         rm -rf $file0 $file1 $xattr0 $xattr1
10157
10158         return 0
10159 }
10160 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10161
10162 test_102p() { # LU-4703 setxattr did not check ownership
10163         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10164                 skip "MDS needs to be at least 2.5.56"
10165
10166         local testfile=$DIR/$tfile
10167
10168         touch $testfile
10169
10170         echo "setfacl as user..."
10171         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10172         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10173
10174         echo "setfattr as user..."
10175         setfacl -m "u:$RUNAS_ID:---" $testfile
10176         $RUNAS setfattr -x system.posix_acl_access $testfile
10177         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10178 }
10179 run_test 102p "check setxattr(2) correctly fails without permission"
10180
10181 test_102q() {
10182         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10183                 skip "MDS needs to be at least 2.6.92"
10184
10185         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10186 }
10187 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10188
10189 test_102r() {
10190         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10191                 skip "MDS needs to be at least 2.6.93"
10192
10193         touch $DIR/$tfile || error "touch"
10194         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10195         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10196         rm $DIR/$tfile || error "rm"
10197
10198         #normal directory
10199         mkdir -p $DIR/$tdir || error "mkdir"
10200         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10201         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10202         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10203                 error "$testfile error deleting user.author1"
10204         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10205                 grep "user.$(basename $tdir)" &&
10206                 error "$tdir did not delete user.$(basename $tdir)"
10207         rmdir $DIR/$tdir || error "rmdir"
10208
10209         #striped directory
10210         test_mkdir $DIR/$tdir
10211         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10212         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10213         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10214                 error "$testfile error deleting user.author1"
10215         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10216                 grep "user.$(basename $tdir)" &&
10217                 error "$tdir did not delete user.$(basename $tdir)"
10218         rmdir $DIR/$tdir || error "rm striped dir"
10219 }
10220 run_test 102r "set EAs with empty values"
10221
10222 test_102s() {
10223         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10224                 skip "MDS needs to be at least 2.11.52"
10225
10226         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10227
10228         save_lustre_params client "llite.*.xattr_cache" > $save
10229
10230         for cache in 0 1; do
10231                 lctl set_param llite.*.xattr_cache=$cache
10232
10233                 rm -f $DIR/$tfile
10234                 touch $DIR/$tfile || error "touch"
10235                 for prefix in lustre security system trusted user; do
10236                         # Note getxattr() may fail with 'Operation not
10237                         # supported' or 'No such attribute' depending
10238                         # on prefix and cache.
10239                         getfattr -n $prefix.n102s $DIR/$tfile &&
10240                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10241                 done
10242         done
10243
10244         restore_lustre_params < $save
10245 }
10246 run_test 102s "getting nonexistent xattrs should fail"
10247
10248 test_102t() {
10249         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10250                 skip "MDS needs to be at least 2.11.52"
10251
10252         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10253
10254         save_lustre_params client "llite.*.xattr_cache" > $save
10255
10256         for cache in 0 1; do
10257                 lctl set_param llite.*.xattr_cache=$cache
10258
10259                 for buf_size in 0 256; do
10260                         rm -f $DIR/$tfile
10261                         touch $DIR/$tfile || error "touch"
10262                         setfattr -n user.multiop $DIR/$tfile
10263                         $MULTIOP $DIR/$tfile oa$buf_size ||
10264                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10265                 done
10266         done
10267
10268         restore_lustre_params < $save
10269 }
10270 run_test 102t "zero length xattr values handled correctly"
10271
10272 run_acl_subtest()
10273 {
10274     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10275     return $?
10276 }
10277
10278 test_103a() {
10279         [ "$UID" != 0 ] && skip "must run as root"
10280         $GSS && skip_env "could not run under gss"
10281         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10282                 skip_env "must have acl enabled"
10283         [ -z "$(which setfacl 2>/dev/null)" ] &&
10284                 skip_env "could not find setfacl"
10285         remote_mds_nodsh && skip "remote MDS with nodsh"
10286
10287         gpasswd -a daemon bin                           # LU-5641
10288         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10289
10290         declare -a identity_old
10291
10292         for num in $(seq $MDSCOUNT); do
10293                 switch_identity $num true || identity_old[$num]=$?
10294         done
10295
10296         SAVE_UMASK=$(umask)
10297         umask 0022
10298         mkdir -p $DIR/$tdir
10299         cd $DIR/$tdir
10300
10301         echo "performing cp ..."
10302         run_acl_subtest cp || error "run_acl_subtest cp failed"
10303         echo "performing getfacl-noacl..."
10304         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10305         echo "performing misc..."
10306         run_acl_subtest misc || error  "misc test failed"
10307         echo "performing permissions..."
10308         run_acl_subtest permissions || error "permissions failed"
10309         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10310         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10311                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10312                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10313         then
10314                 echo "performing permissions xattr..."
10315                 run_acl_subtest permissions_xattr ||
10316                         error "permissions_xattr failed"
10317         fi
10318         echo "performing setfacl..."
10319         run_acl_subtest setfacl || error  "setfacl test failed"
10320
10321         # inheritance test got from HP
10322         echo "performing inheritance..."
10323         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10324         chmod +x make-tree || error "chmod +x failed"
10325         run_acl_subtest inheritance || error "inheritance test failed"
10326         rm -f make-tree
10327
10328         echo "LU-974 ignore umask when acl is enabled..."
10329         run_acl_subtest 974 || error "LU-974 umask test failed"
10330         if [ $MDSCOUNT -ge 2 ]; then
10331                 run_acl_subtest 974_remote ||
10332                         error "LU-974 umask test failed under remote dir"
10333         fi
10334
10335         echo "LU-2561 newly created file is same size as directory..."
10336         if [ "$mds1_FSTYPE" != "zfs" ]; then
10337                 run_acl_subtest 2561 || error "LU-2561 test failed"
10338         else
10339                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10340         fi
10341
10342         run_acl_subtest 4924 || error "LU-4924 test failed"
10343
10344         cd $SAVE_PWD
10345         umask $SAVE_UMASK
10346
10347         for num in $(seq $MDSCOUNT); do
10348                 if [ "${identity_old[$num]}" = 1 ]; then
10349                         switch_identity $num false || identity_old[$num]=$?
10350                 fi
10351         done
10352 }
10353 run_test 103a "acl test"
10354
10355 test_103b() {
10356         declare -a pids
10357         local U
10358
10359         for U in {0..511}; do
10360                 {
10361                 local O=$(printf "%04o" $U)
10362
10363                 umask $(printf "%04o" $((511 ^ $O)))
10364                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10365                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10366
10367                 (( $S == ($O & 0666) )) ||
10368                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10369
10370                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10371                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10372                 (( $S == ($O & 0666) )) ||
10373                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10374
10375                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10376                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10377                 (( $S == ($O & 0666) )) ||
10378                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10379                 rm -f $DIR/$tfile.[smp]$0
10380                 } &
10381                 local pid=$!
10382
10383                 # limit the concurrently running threads to 64. LU-11878
10384                 local idx=$((U % 64))
10385                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10386                 pids[idx]=$pid
10387         done
10388         wait
10389 }
10390 run_test 103b "umask lfs setstripe"
10391
10392 test_103c() {
10393         mkdir -p $DIR/$tdir
10394         cp -rp $DIR/$tdir $DIR/$tdir.bak
10395
10396         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10397                 error "$DIR/$tdir shouldn't contain default ACL"
10398         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10399                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10400         true
10401 }
10402 run_test 103c "'cp -rp' won't set empty acl"
10403
10404 test_104a() {
10405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10406
10407         touch $DIR/$tfile
10408         lfs df || error "lfs df failed"
10409         lfs df -ih || error "lfs df -ih failed"
10410         lfs df -h $DIR || error "lfs df -h $DIR failed"
10411         lfs df -i $DIR || error "lfs df -i $DIR failed"
10412         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10413         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10414
10415         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10416         lctl --device %$OSC deactivate
10417         lfs df || error "lfs df with deactivated OSC failed"
10418         lctl --device %$OSC activate
10419         # wait the osc back to normal
10420         wait_osc_import_ready client ost
10421
10422         lfs df || error "lfs df with reactivated OSC failed"
10423         rm -f $DIR/$tfile
10424 }
10425 run_test 104a "lfs df [-ih] [path] test ========================="
10426
10427 test_104b() {
10428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10429         [ $RUNAS_ID -eq $UID ] &&
10430                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10431
10432         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10433                         grep "Permission denied" | wc -l)))
10434         if [ $denied_cnt -ne 0 ]; then
10435                 error "lfs check servers test failed"
10436         fi
10437 }
10438 run_test 104b "$RUNAS lfs check servers test ===================="
10439
10440 test_105a() {
10441         # doesn't work on 2.4 kernels
10442         touch $DIR/$tfile
10443         if $(flock_is_enabled); then
10444                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10445         else
10446                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10447         fi
10448         rm -f $DIR/$tfile
10449 }
10450 run_test 105a "flock when mounted without -o flock test ========"
10451
10452 test_105b() {
10453         touch $DIR/$tfile
10454         if $(flock_is_enabled); then
10455                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10456         else
10457                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10458         fi
10459         rm -f $DIR/$tfile
10460 }
10461 run_test 105b "fcntl when mounted without -o flock test ========"
10462
10463 test_105c() {
10464         touch $DIR/$tfile
10465         if $(flock_is_enabled); then
10466                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10467         else
10468                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10469         fi
10470         rm -f $DIR/$tfile
10471 }
10472 run_test 105c "lockf when mounted without -o flock test"
10473
10474 test_105d() { # bug 15924
10475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10476
10477         test_mkdir $DIR/$tdir
10478         flock_is_enabled || skip_env "mount w/o flock enabled"
10479         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10480         $LCTL set_param fail_loc=0x80000315
10481         flocks_test 2 $DIR/$tdir
10482 }
10483 run_test 105d "flock race (should not freeze) ========"
10484
10485 test_105e() { # bug 22660 && 22040
10486         flock_is_enabled || skip_env "mount w/o flock enabled"
10487
10488         touch $DIR/$tfile
10489         flocks_test 3 $DIR/$tfile
10490 }
10491 run_test 105e "Two conflicting flocks from same process"
10492
10493 test_106() { #bug 10921
10494         test_mkdir $DIR/$tdir
10495         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10496         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10497 }
10498 run_test 106 "attempt exec of dir followed by chown of that dir"
10499
10500 test_107() {
10501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10502
10503         CDIR=`pwd`
10504         local file=core
10505
10506         cd $DIR
10507         rm -f $file
10508
10509         local save_pattern=$(sysctl -n kernel.core_pattern)
10510         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10511         sysctl -w kernel.core_pattern=$file
10512         sysctl -w kernel.core_uses_pid=0
10513
10514         ulimit -c unlimited
10515         sleep 60 &
10516         SLEEPPID=$!
10517
10518         sleep 1
10519
10520         kill -s 11 $SLEEPPID
10521         wait $SLEEPPID
10522         if [ -e $file ]; then
10523                 size=`stat -c%s $file`
10524                 [ $size -eq 0 ] && error "Fail to create core file $file"
10525         else
10526                 error "Fail to create core file $file"
10527         fi
10528         rm -f $file
10529         sysctl -w kernel.core_pattern=$save_pattern
10530         sysctl -w kernel.core_uses_pid=$save_uses_pid
10531         cd $CDIR
10532 }
10533 run_test 107 "Coredump on SIG"
10534
10535 test_110() {
10536         test_mkdir $DIR/$tdir
10537         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10538         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10539                 error "mkdir with 256 char should fail, but did not"
10540         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10541                 error "create with 255 char failed"
10542         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10543                 error "create with 256 char should fail, but did not"
10544
10545         ls -l $DIR/$tdir
10546         rm -rf $DIR/$tdir
10547 }
10548 run_test 110 "filename length checking"
10549
10550 #
10551 # Purpose: To verify dynamic thread (OSS) creation.
10552 #
10553 test_115() {
10554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10555         remote_ost_nodsh && skip "remote OST with nodsh"
10556
10557         # Lustre does not stop service threads once they are started.
10558         # Reset number of running threads to default.
10559         stopall
10560         setupall
10561
10562         local OSTIO_pre
10563         local save_params="$TMP/sanity-$TESTNAME.parameters"
10564
10565         # Get ll_ost_io count before I/O
10566         OSTIO_pre=$(do_facet ost1 \
10567                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10568         # Exit if lustre is not running (ll_ost_io not running).
10569         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10570
10571         echo "Starting with $OSTIO_pre threads"
10572         local thread_max=$((OSTIO_pre * 2))
10573         local rpc_in_flight=$((thread_max * 2))
10574         # Number of I/O Process proposed to be started.
10575         local nfiles
10576         local facets=$(get_facets OST)
10577
10578         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10579         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10580
10581         # Set in_flight to $rpc_in_flight
10582         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10583                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10584         nfiles=${rpc_in_flight}
10585         # Set ost thread_max to $thread_max
10586         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10587
10588         # 5 Minutes should be sufficient for max number of OSS
10589         # threads(thread_max) to be created.
10590         local timeout=300
10591
10592         # Start I/O.
10593         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10594         test_mkdir $DIR/$tdir
10595         for i in $(seq $nfiles); do
10596                 local file=$DIR/$tdir/${tfile}-$i
10597                 $LFS setstripe -c -1 -i 0 $file
10598                 ($WTL $file $timeout)&
10599         done
10600
10601         # I/O Started - Wait for thread_started to reach thread_max or report
10602         # error if thread_started is more than thread_max.
10603         echo "Waiting for thread_started to reach thread_max"
10604         local thread_started=0
10605         local end_time=$((SECONDS + timeout))
10606
10607         while [ $SECONDS -le $end_time ] ; do
10608                 echo -n "."
10609                 # Get ost i/o thread_started count.
10610                 thread_started=$(do_facet ost1 \
10611                         "$LCTL get_param \
10612                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10613                 # Break out if thread_started is equal/greater than thread_max
10614                 if [[ $thread_started -ge $thread_max ]]; then
10615                         echo ll_ost_io thread_started $thread_started, \
10616                                 equal/greater than thread_max $thread_max
10617                         break
10618                 fi
10619                 sleep 1
10620         done
10621
10622         # Cleanup - We have the numbers, Kill i/o jobs if running.
10623         jobcount=($(jobs -p))
10624         for i in $(seq 0 $((${#jobcount[@]}-1)))
10625         do
10626                 kill -9 ${jobcount[$i]}
10627                 if [ $? -ne 0 ] ; then
10628                         echo Warning: \
10629                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10630                 fi
10631         done
10632
10633         # Cleanup files left by WTL binary.
10634         for i in $(seq $nfiles); do
10635                 local file=$DIR/$tdir/${tfile}-$i
10636                 rm -rf $file
10637                 if [ $? -ne 0 ] ; then
10638                         echo "Warning: Failed to delete file $file"
10639                 fi
10640         done
10641
10642         restore_lustre_params <$save_params
10643         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10644
10645         # Error out if no new thread has started or Thread started is greater
10646         # than thread max.
10647         if [[ $thread_started -le $OSTIO_pre ||
10648                         $thread_started -gt $thread_max ]]; then
10649                 error "ll_ost_io: thread_started $thread_started" \
10650                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10651                       "No new thread started or thread started greater " \
10652                       "than thread_max."
10653         fi
10654 }
10655 run_test 115 "verify dynamic thread creation===================="
10656
10657 free_min_max () {
10658         wait_delete_completed
10659         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10660         echo "OST kbytes available: ${AVAIL[@]}"
10661         MAXV=${AVAIL[0]}
10662         MAXI=0
10663         MINV=${AVAIL[0]}
10664         MINI=0
10665         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10666                 #echo OST $i: ${AVAIL[i]}kb
10667                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10668                         MAXV=${AVAIL[i]}
10669                         MAXI=$i
10670                 fi
10671                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10672                         MINV=${AVAIL[i]}
10673                         MINI=$i
10674                 fi
10675         done
10676         echo "Min free space: OST $MINI: $MINV"
10677         echo "Max free space: OST $MAXI: $MAXV"
10678 }
10679
10680 test_116a() { # was previously test_116()
10681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10682         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10683         remote_mds_nodsh && skip "remote MDS with nodsh"
10684
10685         echo -n "Free space priority "
10686         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10687                 head -n1
10688         declare -a AVAIL
10689         free_min_max
10690
10691         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10692         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10693         trap simple_cleanup_common EXIT
10694
10695         # Check if we need to generate uneven OSTs
10696         test_mkdir -p $DIR/$tdir/OST${MINI}
10697         local FILL=$((MINV / 4))
10698         local DIFF=$((MAXV - MINV))
10699         local DIFF2=$((DIFF * 100 / MINV))
10700
10701         local threshold=$(do_facet $SINGLEMDS \
10702                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10703         threshold=${threshold%%%}
10704         echo -n "Check for uneven OSTs: "
10705         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10706
10707         if [[ $DIFF2 -gt $threshold ]]; then
10708                 echo "ok"
10709                 echo "Don't need to fill OST$MINI"
10710         else
10711                 # generate uneven OSTs. Write 2% over the QOS threshold value
10712                 echo "no"
10713                 DIFF=$((threshold - DIFF2 + 2))
10714                 DIFF2=$((MINV * DIFF / 100))
10715                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10716                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10717                         error "setstripe failed"
10718                 DIFF=$((DIFF2 / 2048))
10719                 i=0
10720                 while [ $i -lt $DIFF ]; do
10721                         i=$((i + 1))
10722                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10723                                 bs=2M count=1 2>/dev/null
10724                         echo -n .
10725                 done
10726                 echo .
10727                 sync
10728                 sleep_maxage
10729                 free_min_max
10730         fi
10731
10732         DIFF=$((MAXV - MINV))
10733         DIFF2=$((DIFF * 100 / MINV))
10734         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10735         if [ $DIFF2 -gt $threshold ]; then
10736                 echo "ok"
10737         else
10738                 echo "failed - QOS mode won't be used"
10739                 simple_cleanup_common
10740                 skip "QOS imbalance criteria not met"
10741         fi
10742
10743         MINI1=$MINI
10744         MINV1=$MINV
10745         MAXI1=$MAXI
10746         MAXV1=$MAXV
10747
10748         # now fill using QOS
10749         $LFS setstripe -c 1 $DIR/$tdir
10750         FILL=$((FILL / 200))
10751         if [ $FILL -gt 600 ]; then
10752                 FILL=600
10753         fi
10754         echo "writing $FILL files to QOS-assigned OSTs"
10755         i=0
10756         while [ $i -lt $FILL ]; do
10757                 i=$((i + 1))
10758                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10759                         count=1 2>/dev/null
10760                 echo -n .
10761         done
10762         echo "wrote $i 200k files"
10763         sync
10764         sleep_maxage
10765
10766         echo "Note: free space may not be updated, so measurements might be off"
10767         free_min_max
10768         DIFF2=$((MAXV - MINV))
10769         echo "free space delta: orig $DIFF final $DIFF2"
10770         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10771         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10772         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10773         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10774         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10775         if [[ $DIFF -gt 0 ]]; then
10776                 FILL=$((DIFF2 * 100 / DIFF - 100))
10777                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10778         fi
10779
10780         # Figure out which files were written where
10781         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10782                awk '/'$MINI1': / {print $2; exit}')
10783         echo $UUID
10784         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10785         echo "$MINC files created on smaller OST $MINI1"
10786         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10787                awk '/'$MAXI1': / {print $2; exit}')
10788         echo $UUID
10789         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10790         echo "$MAXC files created on larger OST $MAXI1"
10791         if [[ $MINC -gt 0 ]]; then
10792                 FILL=$((MAXC * 100 / MINC - 100))
10793                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10794         fi
10795         [[ $MAXC -gt $MINC ]] ||
10796                 error_ignore LU-9 "stripe QOS didn't balance free space"
10797         simple_cleanup_common
10798 }
10799 run_test 116a "stripe QOS: free space balance ==================="
10800
10801 test_116b() { # LU-2093
10802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10803         remote_mds_nodsh && skip "remote MDS with nodsh"
10804
10805 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10806         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10807                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10808         [ -z "$old_rr" ] && skip "no QOS"
10809         do_facet $SINGLEMDS lctl set_param \
10810                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10811         mkdir -p $DIR/$tdir
10812         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10813         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10814         do_facet $SINGLEMDS lctl set_param fail_loc=0
10815         rm -rf $DIR/$tdir
10816         do_facet $SINGLEMDS lctl set_param \
10817                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10818 }
10819 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10820
10821 test_117() # bug 10891
10822 {
10823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10824
10825         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10826         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10827         lctl set_param fail_loc=0x21e
10828         > $DIR/$tfile || error "truncate failed"
10829         lctl set_param fail_loc=0
10830         echo "Truncate succeeded."
10831         rm -f $DIR/$tfile
10832 }
10833 run_test 117 "verify osd extend =========="
10834
10835 NO_SLOW_RESENDCOUNT=4
10836 export OLD_RESENDCOUNT=""
10837 set_resend_count () {
10838         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10839         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10840         lctl set_param -n $PROC_RESENDCOUNT $1
10841         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10842 }
10843
10844 # for reduce test_118* time (b=14842)
10845 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10846
10847 # Reset async IO behavior after error case
10848 reset_async() {
10849         FILE=$DIR/reset_async
10850
10851         # Ensure all OSCs are cleared
10852         $LFS setstripe -c -1 $FILE
10853         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10854         sync
10855         rm $FILE
10856 }
10857
10858 test_118a() #bug 11710
10859 {
10860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10861
10862         reset_async
10863
10864         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10865         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10866         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10867
10868         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10869                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10870                 return 1;
10871         fi
10872         rm -f $DIR/$tfile
10873 }
10874 run_test 118a "verify O_SYNC works =========="
10875
10876 test_118b()
10877 {
10878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10879         remote_ost_nodsh && skip "remote OST with nodsh"
10880
10881         reset_async
10882
10883         #define OBD_FAIL_SRV_ENOENT 0x217
10884         set_nodes_failloc "$(osts_nodes)" 0x217
10885         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10886         RC=$?
10887         set_nodes_failloc "$(osts_nodes)" 0
10888         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10889         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10890                     grep -c writeback)
10891
10892         if [[ $RC -eq 0 ]]; then
10893                 error "Must return error due to dropped pages, rc=$RC"
10894                 return 1;
10895         fi
10896
10897         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10898                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10899                 return 1;
10900         fi
10901
10902         echo "Dirty pages not leaked on ENOENT"
10903
10904         # Due to the above error the OSC will issue all RPCs syncronously
10905         # until a subsequent RPC completes successfully without error.
10906         $MULTIOP $DIR/$tfile Ow4096yc
10907         rm -f $DIR/$tfile
10908
10909         return 0
10910 }
10911 run_test 118b "Reclaim dirty pages on fatal error =========="
10912
10913 test_118c()
10914 {
10915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10916
10917         # for 118c, restore the original resend count, LU-1940
10918         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10919                                 set_resend_count $OLD_RESENDCOUNT
10920         remote_ost_nodsh && skip "remote OST with nodsh"
10921
10922         reset_async
10923
10924         #define OBD_FAIL_OST_EROFS               0x216
10925         set_nodes_failloc "$(osts_nodes)" 0x216
10926
10927         # multiop should block due to fsync until pages are written
10928         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10929         MULTIPID=$!
10930         sleep 1
10931
10932         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10933                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10934         fi
10935
10936         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10937                     grep -c writeback)
10938         if [[ $WRITEBACK -eq 0 ]]; then
10939                 error "No page in writeback, writeback=$WRITEBACK"
10940         fi
10941
10942         set_nodes_failloc "$(osts_nodes)" 0
10943         wait $MULTIPID
10944         RC=$?
10945         if [[ $RC -ne 0 ]]; then
10946                 error "Multiop fsync failed, rc=$RC"
10947         fi
10948
10949         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10950         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10951                     grep -c writeback)
10952         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10953                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10954         fi
10955
10956         rm -f $DIR/$tfile
10957         echo "Dirty pages flushed via fsync on EROFS"
10958         return 0
10959 }
10960 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10961
10962 # continue to use small resend count to reduce test_118* time (b=14842)
10963 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10964
10965 test_118d()
10966 {
10967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10968         remote_ost_nodsh && skip "remote OST with nodsh"
10969
10970         reset_async
10971
10972         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10973         set_nodes_failloc "$(osts_nodes)" 0x214
10974         # multiop should block due to fsync until pages are written
10975         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10976         MULTIPID=$!
10977         sleep 1
10978
10979         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10980                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10981         fi
10982
10983         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10984                     grep -c writeback)
10985         if [[ $WRITEBACK -eq 0 ]]; then
10986                 error "No page in writeback, writeback=$WRITEBACK"
10987         fi
10988
10989         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10990         set_nodes_failloc "$(osts_nodes)" 0
10991
10992         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10993         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10994                     grep -c writeback)
10995         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10996                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10997         fi
10998
10999         rm -f $DIR/$tfile
11000         echo "Dirty pages gaurenteed flushed via fsync"
11001         return 0
11002 }
11003 run_test 118d "Fsync validation inject a delay of the bulk =========="
11004
11005 test_118f() {
11006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11007
11008         reset_async
11009
11010         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11011         lctl set_param fail_loc=0x8000040a
11012
11013         # Should simulate EINVAL error which is fatal
11014         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11015         RC=$?
11016         if [[ $RC -eq 0 ]]; then
11017                 error "Must return error due to dropped pages, rc=$RC"
11018         fi
11019
11020         lctl set_param fail_loc=0x0
11021
11022         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11023         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11024         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11025                     grep -c writeback)
11026         if [[ $LOCKED -ne 0 ]]; then
11027                 error "Locked pages remain in cache, locked=$LOCKED"
11028         fi
11029
11030         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11031                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11032         fi
11033
11034         rm -f $DIR/$tfile
11035         echo "No pages locked after fsync"
11036
11037         reset_async
11038         return 0
11039 }
11040 run_test 118f "Simulate unrecoverable OSC side error =========="
11041
11042 test_118g() {
11043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11044
11045         reset_async
11046
11047         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11048         lctl set_param fail_loc=0x406
11049
11050         # simulate local -ENOMEM
11051         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11052         RC=$?
11053
11054         lctl set_param fail_loc=0
11055         if [[ $RC -eq 0 ]]; then
11056                 error "Must return error due to dropped pages, rc=$RC"
11057         fi
11058
11059         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11060         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11061         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11062                         grep -c writeback)
11063         if [[ $LOCKED -ne 0 ]]; then
11064                 error "Locked pages remain in cache, locked=$LOCKED"
11065         fi
11066
11067         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11068                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11069         fi
11070
11071         rm -f $DIR/$tfile
11072         echo "No pages locked after fsync"
11073
11074         reset_async
11075         return 0
11076 }
11077 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11078
11079 test_118h() {
11080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11081         remote_ost_nodsh && skip "remote OST with nodsh"
11082
11083         reset_async
11084
11085         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11086         set_nodes_failloc "$(osts_nodes)" 0x20e
11087         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11088         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11089         RC=$?
11090
11091         set_nodes_failloc "$(osts_nodes)" 0
11092         if [[ $RC -eq 0 ]]; then
11093                 error "Must return error due to dropped pages, rc=$RC"
11094         fi
11095
11096         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11097         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11098         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11099                     grep -c writeback)
11100         if [[ $LOCKED -ne 0 ]]; then
11101                 error "Locked pages remain in cache, locked=$LOCKED"
11102         fi
11103
11104         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11105                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11106         fi
11107
11108         rm -f $DIR/$tfile
11109         echo "No pages locked after fsync"
11110
11111         return 0
11112 }
11113 run_test 118h "Verify timeout in handling recoverables errors  =========="
11114
11115 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11116
11117 test_118i() {
11118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11119         remote_ost_nodsh && skip "remote OST with nodsh"
11120
11121         reset_async
11122
11123         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11124         set_nodes_failloc "$(osts_nodes)" 0x20e
11125
11126         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11127         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11128         PID=$!
11129         sleep 5
11130         set_nodes_failloc "$(osts_nodes)" 0
11131
11132         wait $PID
11133         RC=$?
11134         if [[ $RC -ne 0 ]]; then
11135                 error "got error, but should be not, rc=$RC"
11136         fi
11137
11138         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11139         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11140         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11141         if [[ $LOCKED -ne 0 ]]; then
11142                 error "Locked pages remain in cache, locked=$LOCKED"
11143         fi
11144
11145         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11146                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11147         fi
11148
11149         rm -f $DIR/$tfile
11150         echo "No pages locked after fsync"
11151
11152         return 0
11153 }
11154 run_test 118i "Fix error before timeout in recoverable error  =========="
11155
11156 [ "$SLOW" = "no" ] && set_resend_count 4
11157
11158 test_118j() {
11159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11160         remote_ost_nodsh && skip "remote OST with nodsh"
11161
11162         reset_async
11163
11164         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11165         set_nodes_failloc "$(osts_nodes)" 0x220
11166
11167         # return -EIO from OST
11168         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11169         RC=$?
11170         set_nodes_failloc "$(osts_nodes)" 0x0
11171         if [[ $RC -eq 0 ]]; then
11172                 error "Must return error due to dropped pages, rc=$RC"
11173         fi
11174
11175         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11176         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11177         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11178         if [[ $LOCKED -ne 0 ]]; then
11179                 error "Locked pages remain in cache, locked=$LOCKED"
11180         fi
11181
11182         # in recoverable error on OST we want resend and stay until it finished
11183         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11184                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11185         fi
11186
11187         rm -f $DIR/$tfile
11188         echo "No pages locked after fsync"
11189
11190         return 0
11191 }
11192 run_test 118j "Simulate unrecoverable OST side error =========="
11193
11194 test_118k()
11195 {
11196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11197         remote_ost_nodsh && skip "remote OSTs with nodsh"
11198
11199         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11200         set_nodes_failloc "$(osts_nodes)" 0x20e
11201         test_mkdir $DIR/$tdir
11202
11203         for ((i=0;i<10;i++)); do
11204                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11205                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11206                 SLEEPPID=$!
11207                 sleep 0.500s
11208                 kill $SLEEPPID
11209                 wait $SLEEPPID
11210         done
11211
11212         set_nodes_failloc "$(osts_nodes)" 0
11213         rm -rf $DIR/$tdir
11214 }
11215 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11216
11217 test_118l() # LU-646
11218 {
11219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11220
11221         test_mkdir $DIR/$tdir
11222         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11223         rm -rf $DIR/$tdir
11224 }
11225 run_test 118l "fsync dir"
11226
11227 test_118m() # LU-3066
11228 {
11229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11230
11231         test_mkdir $DIR/$tdir
11232         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11233         rm -rf $DIR/$tdir
11234 }
11235 run_test 118m "fdatasync dir ========="
11236
11237 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11238
11239 test_118n()
11240 {
11241         local begin
11242         local end
11243
11244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11245         remote_ost_nodsh && skip "remote OSTs with nodsh"
11246
11247         # Sleep to avoid a cached response.
11248         #define OBD_STATFS_CACHE_SECONDS 1
11249         sleep 2
11250
11251         # Inject a 10 second delay in the OST_STATFS handler.
11252         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11253         set_nodes_failloc "$(osts_nodes)" 0x242
11254
11255         begin=$SECONDS
11256         stat --file-system $MOUNT > /dev/null
11257         end=$SECONDS
11258
11259         set_nodes_failloc "$(osts_nodes)" 0
11260
11261         if ((end - begin > 20)); then
11262             error "statfs took $((end - begin)) seconds, expected 10"
11263         fi
11264 }
11265 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11266
11267 test_119a() # bug 11737
11268 {
11269         BSIZE=$((512 * 1024))
11270         directio write $DIR/$tfile 0 1 $BSIZE
11271         # We ask to read two blocks, which is more than a file size.
11272         # directio will indicate an error when requested and actual
11273         # sizes aren't equeal (a normal situation in this case) and
11274         # print actual read amount.
11275         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11276         if [ "$NOB" != "$BSIZE" ]; then
11277                 error "read $NOB bytes instead of $BSIZE"
11278         fi
11279         rm -f $DIR/$tfile
11280 }
11281 run_test 119a "Short directIO read must return actual read amount"
11282
11283 test_119b() # bug 11737
11284 {
11285         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11286
11287         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11288         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11289         sync
11290         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11291                 error "direct read failed"
11292         rm -f $DIR/$tfile
11293 }
11294 run_test 119b "Sparse directIO read must return actual read amount"
11295
11296 test_119c() # bug 13099
11297 {
11298         BSIZE=1048576
11299         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11300         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11301         rm -f $DIR/$tfile
11302 }
11303 run_test 119c "Testing for direct read hitting hole"
11304
11305 test_119d() # bug 15950
11306 {
11307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11308
11309         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11310         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11311         BSIZE=1048576
11312         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11313         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11314         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11315         lctl set_param fail_loc=0x40d
11316         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11317         pid_dio=$!
11318         sleep 1
11319         cat $DIR/$tfile > /dev/null &
11320         lctl set_param fail_loc=0
11321         pid_reads=$!
11322         wait $pid_dio
11323         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11324         sleep 2
11325         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11326         error "the read rpcs have not completed in 2s"
11327         rm -f $DIR/$tfile
11328         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11329 }
11330 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11331
11332 test_120a() {
11333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11334         remote_mds_nodsh && skip "remote MDS with nodsh"
11335         test_mkdir -i0 -c1 $DIR/$tdir
11336         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11337                 skip_env "no early lock cancel on server"
11338
11339         lru_resize_disable mdc
11340         lru_resize_disable osc
11341         cancel_lru_locks mdc
11342         # asynchronous object destroy at MDT could cause bl ast to client
11343         cancel_lru_locks osc
11344
11345         stat $DIR/$tdir > /dev/null
11346         can1=$(do_facet mds1 \
11347                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11348                awk '/ldlm_cancel/ {print $2}')
11349         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11350                awk '/ldlm_bl_callback/ {print $2}')
11351         test_mkdir -i0 -c1 $DIR/$tdir/d1
11352         can2=$(do_facet mds1 \
11353                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11354                awk '/ldlm_cancel/ {print $2}')
11355         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11356                awk '/ldlm_bl_callback/ {print $2}')
11357         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11358         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11359         lru_resize_enable mdc
11360         lru_resize_enable osc
11361 }
11362 run_test 120a "Early Lock Cancel: mkdir test"
11363
11364 test_120b() {
11365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11366         remote_mds_nodsh && skip "remote MDS with nodsh"
11367         test_mkdir $DIR/$tdir
11368         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11369                 skip_env "no early lock cancel on server"
11370
11371         lru_resize_disable mdc
11372         lru_resize_disable osc
11373         cancel_lru_locks mdc
11374         stat $DIR/$tdir > /dev/null
11375         can1=$(do_facet $SINGLEMDS \
11376                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11377                awk '/ldlm_cancel/ {print $2}')
11378         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11379                awk '/ldlm_bl_callback/ {print $2}')
11380         touch $DIR/$tdir/f1
11381         can2=$(do_facet $SINGLEMDS \
11382                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11383                awk '/ldlm_cancel/ {print $2}')
11384         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11385                awk '/ldlm_bl_callback/ {print $2}')
11386         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11387         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11388         lru_resize_enable mdc
11389         lru_resize_enable osc
11390 }
11391 run_test 120b "Early Lock Cancel: create test"
11392
11393 test_120c() {
11394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11395         remote_mds_nodsh && skip "remote MDS with nodsh"
11396         test_mkdir -i0 -c1 $DIR/$tdir
11397         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11398                 skip "no early lock cancel on server"
11399
11400         lru_resize_disable mdc
11401         lru_resize_disable osc
11402         test_mkdir -i0 -c1 $DIR/$tdir/d1
11403         test_mkdir -i0 -c1 $DIR/$tdir/d2
11404         touch $DIR/$tdir/d1/f1
11405         cancel_lru_locks mdc
11406         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11407         can1=$(do_facet mds1 \
11408                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11409                awk '/ldlm_cancel/ {print $2}')
11410         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11411                awk '/ldlm_bl_callback/ {print $2}')
11412         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11413         can2=$(do_facet mds1 \
11414                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11415                awk '/ldlm_cancel/ {print $2}')
11416         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11417                awk '/ldlm_bl_callback/ {print $2}')
11418         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11419         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11420         lru_resize_enable mdc
11421         lru_resize_enable osc
11422 }
11423 run_test 120c "Early Lock Cancel: link test"
11424
11425 test_120d() {
11426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11427         remote_mds_nodsh && skip "remote MDS with nodsh"
11428         test_mkdir -i0 -c1 $DIR/$tdir
11429         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11430                 skip_env "no early lock cancel on server"
11431
11432         lru_resize_disable mdc
11433         lru_resize_disable osc
11434         touch $DIR/$tdir
11435         cancel_lru_locks mdc
11436         stat $DIR/$tdir > /dev/null
11437         can1=$(do_facet mds1 \
11438                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11439                awk '/ldlm_cancel/ {print $2}')
11440         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11441                awk '/ldlm_bl_callback/ {print $2}')
11442         chmod a+x $DIR/$tdir
11443         can2=$(do_facet mds1 \
11444                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11445                awk '/ldlm_cancel/ {print $2}')
11446         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11447                awk '/ldlm_bl_callback/ {print $2}')
11448         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11449         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11450         lru_resize_enable mdc
11451         lru_resize_enable osc
11452 }
11453 run_test 120d "Early Lock Cancel: setattr test"
11454
11455 test_120e() {
11456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11457         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11458                 skip_env "no early lock cancel on server"
11459         remote_mds_nodsh && skip "remote MDS with nodsh"
11460
11461         local dlmtrace_set=false
11462
11463         test_mkdir -i0 -c1 $DIR/$tdir
11464         lru_resize_disable mdc
11465         lru_resize_disable osc
11466         ! $LCTL get_param debug | grep -q dlmtrace &&
11467                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11468         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11469         cancel_lru_locks mdc
11470         cancel_lru_locks osc
11471         dd if=$DIR/$tdir/f1 of=/dev/null
11472         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11473         # XXX client can not do early lock cancel of OST lock
11474         # during unlink (LU-4206), so cancel osc lock now.
11475         sleep 2
11476         cancel_lru_locks osc
11477         can1=$(do_facet mds1 \
11478                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11479                awk '/ldlm_cancel/ {print $2}')
11480         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11481                awk '/ldlm_bl_callback/ {print $2}')
11482         unlink $DIR/$tdir/f1
11483         sleep 5
11484         can2=$(do_facet mds1 \
11485                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11486                awk '/ldlm_cancel/ {print $2}')
11487         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11488                awk '/ldlm_bl_callback/ {print $2}')
11489         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11490                 $LCTL dk $TMP/cancel.debug.txt
11491         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11492                 $LCTL dk $TMP/blocking.debug.txt
11493         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11494         lru_resize_enable mdc
11495         lru_resize_enable osc
11496 }
11497 run_test 120e "Early Lock Cancel: unlink test"
11498
11499 test_120f() {
11500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11501         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11502                 skip_env "no early lock cancel on server"
11503         remote_mds_nodsh && skip "remote MDS with nodsh"
11504
11505         test_mkdir -i0 -c1 $DIR/$tdir
11506         lru_resize_disable mdc
11507         lru_resize_disable osc
11508         test_mkdir -i0 -c1 $DIR/$tdir/d1
11509         test_mkdir -i0 -c1 $DIR/$tdir/d2
11510         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11511         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11512         cancel_lru_locks mdc
11513         cancel_lru_locks osc
11514         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11515         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11516         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11517         # XXX client can not do early lock cancel of OST lock
11518         # during rename (LU-4206), so cancel osc lock now.
11519         sleep 2
11520         cancel_lru_locks osc
11521         can1=$(do_facet mds1 \
11522                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11523                awk '/ldlm_cancel/ {print $2}')
11524         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11525                awk '/ldlm_bl_callback/ {print $2}')
11526         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11527         sleep 5
11528         can2=$(do_facet mds1 \
11529                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11530                awk '/ldlm_cancel/ {print $2}')
11531         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11532                awk '/ldlm_bl_callback/ {print $2}')
11533         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11534         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11535         lru_resize_enable mdc
11536         lru_resize_enable osc
11537 }
11538 run_test 120f "Early Lock Cancel: rename test"
11539
11540 test_120g() {
11541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11542         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11543                 skip_env "no early lock cancel on server"
11544         remote_mds_nodsh && skip "remote MDS with nodsh"
11545
11546         lru_resize_disable mdc
11547         lru_resize_disable osc
11548         count=10000
11549         echo create $count files
11550         test_mkdir $DIR/$tdir
11551         cancel_lru_locks mdc
11552         cancel_lru_locks osc
11553         t0=$(date +%s)
11554
11555         can0=$(do_facet $SINGLEMDS \
11556                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11557                awk '/ldlm_cancel/ {print $2}')
11558         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11559                awk '/ldlm_bl_callback/ {print $2}')
11560         createmany -o $DIR/$tdir/f $count
11561         sync
11562         can1=$(do_facet $SINGLEMDS \
11563                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11564                awk '/ldlm_cancel/ {print $2}')
11565         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11566                awk '/ldlm_bl_callback/ {print $2}')
11567         t1=$(date +%s)
11568         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11569         echo rm $count files
11570         rm -r $DIR/$tdir
11571         sync
11572         can2=$(do_facet $SINGLEMDS \
11573                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11574                awk '/ldlm_cancel/ {print $2}')
11575         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11576                awk '/ldlm_bl_callback/ {print $2}')
11577         t2=$(date +%s)
11578         echo total: $count removes in $((t2-t1))
11579         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11580         sleep 2
11581         # wait for commitment of removal
11582         lru_resize_enable mdc
11583         lru_resize_enable osc
11584 }
11585 run_test 120g "Early Lock Cancel: performance test"
11586
11587 test_121() { #bug #10589
11588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11589
11590         rm -rf $DIR/$tfile
11591         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11592 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11593         lctl set_param fail_loc=0x310
11594         cancel_lru_locks osc > /dev/null
11595         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11596         lctl set_param fail_loc=0
11597         [[ $reads -eq $writes ]] ||
11598                 error "read $reads blocks, must be $writes blocks"
11599 }
11600 run_test 121 "read cancel race ========="
11601
11602 test_123a_base() { # was test 123, statahead(bug 11401)
11603         local lsx="$1"
11604
11605         SLOWOK=0
11606         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11607                 log "testing UP system. Performance may be lower than expected."
11608                 SLOWOK=1
11609         fi
11610
11611         rm -rf $DIR/$tdir
11612         test_mkdir $DIR/$tdir
11613         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11614         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11615         MULT=10
11616         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11617                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11618
11619                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11620                 lctl set_param -n llite.*.statahead_max 0
11621                 lctl get_param llite.*.statahead_max
11622                 cancel_lru_locks mdc
11623                 cancel_lru_locks osc
11624                 stime=$(date +%s)
11625                 time $lsx $DIR/$tdir | wc -l
11626                 etime=$(date +%s)
11627                 delta=$((etime - stime))
11628                 log "$lsx $i files without statahead: $delta sec"
11629                 lctl set_param llite.*.statahead_max=$max
11630
11631                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11632                         grep "statahead wrong:" | awk '{print $3}')
11633                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11634                 cancel_lru_locks mdc
11635                 cancel_lru_locks osc
11636                 stime=$(date +%s)
11637                 time $lsx $DIR/$tdir | wc -l
11638                 etime=$(date +%s)
11639                 delta_sa=$((etime - stime))
11640                 log "$lsx $i files with statahead: $delta_sa sec"
11641                 lctl get_param -n llite.*.statahead_stats
11642                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11643                         grep "statahead wrong:" | awk '{print $3}')
11644
11645                 [[ $swrong -lt $ewrong ]] &&
11646                         log "statahead was stopped, maybe too many locks held!"
11647                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11648
11649                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11650                         max=$(lctl get_param -n llite.*.statahead_max |
11651                                 head -n 1)
11652                         lctl set_param -n llite.*.statahead_max 0
11653                         lctl get_param llite.*.statahead_max
11654                         cancel_lru_locks mdc
11655                         cancel_lru_locks osc
11656                         stime=$(date +%s)
11657                         time $lsx $DIR/$tdir | wc -l
11658                         etime=$(date +%s)
11659                         delta=$((etime - stime))
11660                         log "$lsx $i files again without statahead: $delta sec"
11661                         lctl set_param llite.*.statahead_max=$max
11662                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11663                                 if [  $SLOWOK -eq 0 ]; then
11664                                         error "$lsx $i files is slower with statahead!"
11665                                 else
11666                                         log "$lsx $i files is slower with statahead!"
11667                                 fi
11668                                 break
11669                         fi
11670                 fi
11671
11672                 [ $delta -gt 20 ] && break
11673                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11674                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11675         done
11676         log "$lsx done"
11677
11678         stime=$(date +%s)
11679         rm -r $DIR/$tdir
11680         sync
11681         etime=$(date +%s)
11682         delta=$((etime - stime))
11683         log "rm -r $DIR/$tdir/: $delta seconds"
11684         log "rm done"
11685         lctl get_param -n llite.*.statahead_stats
11686 }
11687
11688 test_123aa() {
11689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11690
11691         test_123a_base "ls -l"
11692 }
11693 run_test 123aa "verify statahead work"
11694
11695 test_123ab() {
11696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11697
11698         statx_supported || skip_env "Test must be statx() syscall supported"
11699
11700         test_123a_base "$STATX -l"
11701 }
11702 run_test 123ab "verify statahead work by using statx"
11703
11704 test_123ac() {
11705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11706
11707         statx_supported || skip_env "Test must be statx() syscall supported"
11708
11709         local rpcs_before
11710         local rpcs_after
11711         local agl_before
11712         local agl_after
11713
11714         cancel_lru_locks $OSC
11715         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11716         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11717                 awk '/agl.total:/ {print $3}')
11718         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11719         test_123a_base "$STATX --cached=always -D"
11720         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11721                 awk '/agl.total:/ {print $3}')
11722         [ $agl_before -eq $agl_after ] ||
11723                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11724         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11725         [ $rpcs_after -eq $rpcs_before ] ||
11726                 error "$STATX should not send glimpse RPCs to $OSC"
11727 }
11728 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11729
11730 test_123b () { # statahead(bug 15027)
11731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11732
11733         test_mkdir $DIR/$tdir
11734         createmany -o $DIR/$tdir/$tfile-%d 1000
11735
11736         cancel_lru_locks mdc
11737         cancel_lru_locks osc
11738
11739 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11740         lctl set_param fail_loc=0x80000803
11741         ls -lR $DIR/$tdir > /dev/null
11742         log "ls done"
11743         lctl set_param fail_loc=0x0
11744         lctl get_param -n llite.*.statahead_stats
11745         rm -r $DIR/$tdir
11746         sync
11747
11748 }
11749 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11750
11751 test_123c() {
11752         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11753
11754         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11755         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11756         touch $DIR/$tdir.1/{1..3}
11757         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11758
11759         remount_client $MOUNT
11760
11761         $MULTIOP $DIR/$tdir.0 Q
11762
11763         # let statahead to complete
11764         ls -l $DIR/$tdir.0 > /dev/null
11765
11766         testid=$(echo $TESTNAME | tr '_' ' ')
11767         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11768                 error "statahead warning" || true
11769 }
11770 run_test 123c "Can not initialize inode warning on DNE statahead"
11771
11772 test_124a() {
11773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11774         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11775                 skip_env "no lru resize on server"
11776
11777         local NR=2000
11778
11779         test_mkdir $DIR/$tdir
11780
11781         log "create $NR files at $DIR/$tdir"
11782         createmany -o $DIR/$tdir/f $NR ||
11783                 error "failed to create $NR files in $DIR/$tdir"
11784
11785         cancel_lru_locks mdc
11786         ls -l $DIR/$tdir > /dev/null
11787
11788         local NSDIR=""
11789         local LRU_SIZE=0
11790         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11791                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11792                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11793                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11794                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11795                         log "NSDIR=$NSDIR"
11796                         log "NS=$(basename $NSDIR)"
11797                         break
11798                 fi
11799         done
11800
11801         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11802                 skip "Not enough cached locks created!"
11803         fi
11804         log "LRU=$LRU_SIZE"
11805
11806         local SLEEP=30
11807
11808         # We know that lru resize allows one client to hold $LIMIT locks
11809         # for 10h. After that locks begin to be killed by client.
11810         local MAX_HRS=10
11811         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11812         log "LIMIT=$LIMIT"
11813         if [ $LIMIT -lt $LRU_SIZE ]; then
11814                 skip "Limit is too small $LIMIT"
11815         fi
11816
11817         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11818         # killing locks. Some time was spent for creating locks. This means
11819         # that up to the moment of sleep finish we must have killed some of
11820         # them (10-100 locks). This depends on how fast ther were created.
11821         # Many of them were touched in almost the same moment and thus will
11822         # be killed in groups.
11823         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11824
11825         # Use $LRU_SIZE_B here to take into account real number of locks
11826         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11827         local LRU_SIZE_B=$LRU_SIZE
11828         log "LVF=$LVF"
11829         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11830         log "OLD_LVF=$OLD_LVF"
11831         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11832
11833         # Let's make sure that we really have some margin. Client checks
11834         # cached locks every 10 sec.
11835         SLEEP=$((SLEEP+20))
11836         log "Sleep ${SLEEP} sec"
11837         local SEC=0
11838         while ((SEC<$SLEEP)); do
11839                 echo -n "..."
11840                 sleep 5
11841                 SEC=$((SEC+5))
11842                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11843                 echo -n "$LRU_SIZE"
11844         done
11845         echo ""
11846         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11847         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11848
11849         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11850                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11851                 unlinkmany $DIR/$tdir/f $NR
11852                 return
11853         }
11854
11855         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11856         log "unlink $NR files at $DIR/$tdir"
11857         unlinkmany $DIR/$tdir/f $NR
11858 }
11859 run_test 124a "lru resize ======================================="
11860
11861 get_max_pool_limit()
11862 {
11863         local limit=$($LCTL get_param \
11864                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11865         local max=0
11866         for l in $limit; do
11867                 if [[ $l -gt $max ]]; then
11868                         max=$l
11869                 fi
11870         done
11871         echo $max
11872 }
11873
11874 test_124b() {
11875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11876         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11877                 skip_env "no lru resize on server"
11878
11879         LIMIT=$(get_max_pool_limit)
11880
11881         NR=$(($(default_lru_size)*20))
11882         if [[ $NR -gt $LIMIT ]]; then
11883                 log "Limit lock number by $LIMIT locks"
11884                 NR=$LIMIT
11885         fi
11886
11887         IFree=$(mdsrate_inodes_available)
11888         if [ $IFree -lt $NR ]; then
11889                 log "Limit lock number by $IFree inodes"
11890                 NR=$IFree
11891         fi
11892
11893         lru_resize_disable mdc
11894         test_mkdir -p $DIR/$tdir/disable_lru_resize
11895
11896         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11897         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11898         cancel_lru_locks mdc
11899         stime=`date +%s`
11900         PID=""
11901         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11902         PID="$PID $!"
11903         sleep 2
11904         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11905         PID="$PID $!"
11906         sleep 2
11907         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11908         PID="$PID $!"
11909         wait $PID
11910         etime=`date +%s`
11911         nolruresize_delta=$((etime-stime))
11912         log "ls -la time: $nolruresize_delta seconds"
11913         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11914         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11915
11916         lru_resize_enable mdc
11917         test_mkdir -p $DIR/$tdir/enable_lru_resize
11918
11919         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11920         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11921         cancel_lru_locks mdc
11922         stime=`date +%s`
11923         PID=""
11924         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11925         PID="$PID $!"
11926         sleep 2
11927         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11928         PID="$PID $!"
11929         sleep 2
11930         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11931         PID="$PID $!"
11932         wait $PID
11933         etime=`date +%s`
11934         lruresize_delta=$((etime-stime))
11935         log "ls -la time: $lruresize_delta seconds"
11936         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11937
11938         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11939                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11940         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11941                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11942         else
11943                 log "lru resize performs the same with no lru resize"
11944         fi
11945         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11946 }
11947 run_test 124b "lru resize (performance test) ======================="
11948
11949 test_124c() {
11950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11951         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11952                 skip_env "no lru resize on server"
11953
11954         # cache ununsed locks on client
11955         local nr=100
11956         cancel_lru_locks mdc
11957         test_mkdir $DIR/$tdir
11958         createmany -o $DIR/$tdir/f $nr ||
11959                 error "failed to create $nr files in $DIR/$tdir"
11960         ls -l $DIR/$tdir > /dev/null
11961
11962         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11963         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11964         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11965         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11966         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11967
11968         # set lru_max_age to 1 sec
11969         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11970         echo "sleep $((recalc_p * 2)) seconds..."
11971         sleep $((recalc_p * 2))
11972
11973         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11974         # restore lru_max_age
11975         $LCTL set_param -n $nsdir.lru_max_age $max_age
11976         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11977         unlinkmany $DIR/$tdir/f $nr
11978 }
11979 run_test 124c "LRUR cancel very aged locks"
11980
11981 test_124d() {
11982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11983         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11984                 skip_env "no lru resize on server"
11985
11986         # cache ununsed locks on client
11987         local nr=100
11988
11989         lru_resize_disable mdc
11990         stack_trap "lru_resize_enable mdc" EXIT
11991
11992         cancel_lru_locks mdc
11993
11994         # asynchronous object destroy at MDT could cause bl ast to client
11995         test_mkdir $DIR/$tdir
11996         createmany -o $DIR/$tdir/f $nr ||
11997                 error "failed to create $nr files in $DIR/$tdir"
11998         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11999
12000         ls -l $DIR/$tdir > /dev/null
12001
12002         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12003         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12004         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12005         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12006
12007         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12008
12009         # set lru_max_age to 1 sec
12010         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12011         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12012
12013         echo "sleep $((recalc_p * 2)) seconds..."
12014         sleep $((recalc_p * 2))
12015
12016         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12017
12018         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12019 }
12020 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12021
12022 test_125() { # 13358
12023         $LCTL get_param -n llite.*.client_type | grep -q local ||
12024                 skip "must run as local client"
12025         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12026                 skip_env "must have acl enabled"
12027         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12028
12029         test_mkdir $DIR/$tdir
12030         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12031         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12032         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12033 }
12034 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12035
12036 test_126() { # bug 12829/13455
12037         $GSS && skip_env "must run as gss disabled"
12038         $LCTL get_param -n llite.*.client_type | grep -q local ||
12039                 skip "must run as local client"
12040         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12041
12042         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12043         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12044         rm -f $DIR/$tfile
12045         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12046 }
12047 run_test 126 "check that the fsgid provided by the client is taken into account"
12048
12049 test_127a() { # bug 15521
12050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12051         local name count samp unit min max sum sumsq
12052
12053         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12054         echo "stats before reset"
12055         $LCTL get_param osc.*.stats
12056         $LCTL set_param osc.*.stats=0
12057         local fsize=$((2048 * 1024))
12058
12059         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12060         cancel_lru_locks osc
12061         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12062
12063         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12064         stack_trap "rm -f $TMP/$tfile.tmp"
12065         while read name count samp unit min max sum sumsq; do
12066                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12067                 [ ! $min ] && error "Missing min value for $name proc entry"
12068                 eval $name=$count || error "Wrong proc format"
12069
12070                 case $name in
12071                 read_bytes|write_bytes)
12072                         [[ "$unit" =~ "bytes" ]] ||
12073                                 error "unit is not 'bytes': $unit"
12074                         (( $min >= 4096 )) || error "min is too small: $min"
12075                         (( $min <= $fsize )) || error "min is too big: $min"
12076                         (( $max >= 4096 )) || error "max is too small: $max"
12077                         (( $max <= $fsize )) || error "max is too big: $max"
12078                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12079                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12080                                 error "sumsquare is too small: $sumsq"
12081                         (( $sumsq <= $fsize * $fsize )) ||
12082                                 error "sumsquare is too big: $sumsq"
12083                         ;;
12084                 ost_read|ost_write)
12085                         [[ "$unit" =~ "usec" ]] ||
12086                                 error "unit is not 'usec': $unit"
12087                         ;;
12088                 *)      ;;
12089                 esac
12090         done < $DIR/$tfile.tmp
12091
12092         #check that we actually got some stats
12093         [ "$read_bytes" ] || error "Missing read_bytes stats"
12094         [ "$write_bytes" ] || error "Missing write_bytes stats"
12095         [ "$read_bytes" != 0 ] || error "no read done"
12096         [ "$write_bytes" != 0 ] || error "no write done"
12097 }
12098 run_test 127a "verify the client stats are sane"
12099
12100 test_127b() { # bug LU-333
12101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12102         local name count samp unit min max sum sumsq
12103
12104         echo "stats before reset"
12105         $LCTL get_param llite.*.stats
12106         $LCTL set_param llite.*.stats=0
12107
12108         # perform 2 reads and writes so MAX is different from SUM.
12109         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12110         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12111         cancel_lru_locks osc
12112         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12113         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12114
12115         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12116         stack_trap "rm -f $TMP/$tfile.tmp"
12117         while read name count samp unit min max sum sumsq; do
12118                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12119                 eval $name=$count || error "Wrong proc format"
12120
12121                 case $name in
12122                 read_bytes|write_bytes)
12123                         [[ "$unit" =~ "bytes" ]] ||
12124                                 error "unit is not 'bytes': $unit"
12125                         (( $count == 2 )) || error "count is not 2: $count"
12126                         (( $min == $PAGE_SIZE )) ||
12127                                 error "min is not $PAGE_SIZE: $min"
12128                         (( $max == $PAGE_SIZE )) ||
12129                                 error "max is not $PAGE_SIZE: $max"
12130                         (( $sum == $PAGE_SIZE * 2 )) ||
12131                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12132                         ;;
12133                 read|write)
12134                         [[ "$unit" =~ "usec" ]] ||
12135                                 error "unit is not 'usec': $unit"
12136                         ;;
12137                 *)      ;;
12138                 esac
12139         done < $TMP/$tfile.tmp
12140
12141         #check that we actually got some stats
12142         [ "$read_bytes" ] || error "Missing read_bytes stats"
12143         [ "$write_bytes" ] || error "Missing write_bytes stats"
12144         [ "$read_bytes" != 0 ] || error "no read done"
12145         [ "$write_bytes" != 0 ] || error "no write done"
12146 }
12147 run_test 127b "verify the llite client stats are sane"
12148
12149 test_127c() { # LU-12394
12150         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12151         local size
12152         local bsize
12153         local reads
12154         local writes
12155         local count
12156
12157         $LCTL set_param llite.*.extents_stats=1
12158         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12159
12160         # Use two stripes so there is enough space in default config
12161         $LFS setstripe -c 2 $DIR/$tfile
12162
12163         # Extent stats start at 0-4K and go in power of two buckets
12164         # LL_HIST_START = 12 --> 2^12 = 4K
12165         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12166         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12167         # small configs
12168         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12169                 do
12170                 # Write and read, 2x each, second time at a non-zero offset
12171                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12172                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12173                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12174                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12175                 rm -f $DIR/$tfile
12176         done
12177
12178         $LCTL get_param llite.*.extents_stats
12179
12180         count=2
12181         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12182                 do
12183                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12184                                 grep -m 1 $bsize)
12185                 reads=$(echo $bucket | awk '{print $5}')
12186                 writes=$(echo $bucket | awk '{print $9}')
12187                 [ "$reads" -eq $count ] ||
12188                         error "$reads reads in < $bsize bucket, expect $count"
12189                 [ "$writes" -eq $count ] ||
12190                         error "$writes writes in < $bsize bucket, expect $count"
12191         done
12192
12193         # Test mmap write and read
12194         $LCTL set_param llite.*.extents_stats=c
12195         size=512
12196         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12197         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12198         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12199
12200         $LCTL get_param llite.*.extents_stats
12201
12202         count=$(((size*1024) / PAGE_SIZE))
12203
12204         bsize=$((2 * PAGE_SIZE / 1024))K
12205
12206         bucket=$($LCTL get_param -n llite.*.extents_stats |
12207                         grep -m 1 $bsize)
12208         reads=$(echo $bucket | awk '{print $5}')
12209         writes=$(echo $bucket | awk '{print $9}')
12210         # mmap writes fault in the page first, creating an additonal read
12211         [ "$reads" -eq $((2 * count)) ] ||
12212                 error "$reads reads in < $bsize bucket, expect $count"
12213         [ "$writes" -eq $count ] ||
12214                 error "$writes writes in < $bsize bucket, expect $count"
12215 }
12216 run_test 127c "test llite extent stats with regular & mmap i/o"
12217
12218 test_128() { # bug 15212
12219         touch $DIR/$tfile
12220         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12221                 find $DIR/$tfile
12222                 find $DIR/$tfile
12223         EOF
12224
12225         result=$(grep error $TMP/$tfile.log)
12226         rm -f $DIR/$tfile $TMP/$tfile.log
12227         [ -z "$result" ] ||
12228                 error "consecutive find's under interactive lfs failed"
12229 }
12230 run_test 128 "interactive lfs for 2 consecutive find's"
12231
12232 set_dir_limits () {
12233         local mntdev
12234         local canondev
12235         local node
12236
12237         local ldproc=/proc/fs/ldiskfs
12238         local facets=$(get_facets MDS)
12239
12240         for facet in ${facets//,/ }; do
12241                 canondev=$(ldiskfs_canon \
12242                            *.$(convert_facet2label $facet).mntdev $facet)
12243                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12244                         ldproc=/sys/fs/ldiskfs
12245                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12246                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12247         done
12248 }
12249
12250 check_mds_dmesg() {
12251         local facets=$(get_facets MDS)
12252         for facet in ${facets//,/ }; do
12253                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12254         done
12255         return 1
12256 }
12257
12258 test_129() {
12259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12260         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12261                 skip "Need MDS version with at least 2.5.56"
12262         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12263                 skip_env "ldiskfs only test"
12264         fi
12265         remote_mds_nodsh && skip "remote MDS with nodsh"
12266
12267         local ENOSPC=28
12268         local has_warning=false
12269
12270         rm -rf $DIR/$tdir
12271         mkdir -p $DIR/$tdir
12272
12273         # block size of mds1
12274         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12275         set_dir_limits $maxsize $((maxsize * 6 / 8))
12276         stack_trap "set_dir_limits 0 0"
12277         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12278         local dirsize=$(stat -c%s "$DIR/$tdir")
12279         local nfiles=0
12280         while (( $dirsize <= $maxsize )); do
12281                 $MCREATE $DIR/$tdir/file_base_$nfiles
12282                 rc=$?
12283                 # check two errors:
12284                 # ENOSPC for ext4 max_dir_size, which has been used since
12285                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12286                 if (( rc == ENOSPC )); then
12287                         set_dir_limits 0 0
12288                         echo "rc=$rc returned as expected after $nfiles files"
12289
12290                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12291                                 error "create failed w/o dir size limit"
12292
12293                         # messages may be rate limited if test is run repeatedly
12294                         check_mds_dmesg '"is approaching max"' ||
12295                                 echo "warning message should be output"
12296                         check_mds_dmesg '"has reached max"' ||
12297                                 echo "reached message should be output"
12298
12299                         dirsize=$(stat -c%s "$DIR/$tdir")
12300
12301                         [[ $dirsize -ge $maxsize ]] && return 0
12302                         error "dirsize $dirsize < $maxsize after $nfiles files"
12303                 elif (( rc != 0 )); then
12304                         break
12305                 fi
12306                 nfiles=$((nfiles + 1))
12307                 dirsize=$(stat -c%s "$DIR/$tdir")
12308         done
12309
12310         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12311 }
12312 run_test 129 "test directory size limit ========================"
12313
12314 OLDIFS="$IFS"
12315 cleanup_130() {
12316         trap 0
12317         IFS="$OLDIFS"
12318 }
12319
12320 test_130a() {
12321         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12322         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12323
12324         trap cleanup_130 EXIT RETURN
12325
12326         local fm_file=$DIR/$tfile
12327         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12328         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12329                 error "dd failed for $fm_file"
12330
12331         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12332         filefrag -ves $fm_file
12333         RC=$?
12334         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12335                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12336         [ $RC != 0 ] && error "filefrag $fm_file failed"
12337
12338         filefrag_op=$(filefrag -ve -k $fm_file |
12339                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12340         lun=$($LFS getstripe -i $fm_file)
12341
12342         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12343         IFS=$'\n'
12344         tot_len=0
12345         for line in $filefrag_op
12346         do
12347                 frag_lun=`echo $line | cut -d: -f5`
12348                 ext_len=`echo $line | cut -d: -f4`
12349                 if (( $frag_lun != $lun )); then
12350                         cleanup_130
12351                         error "FIEMAP on 1-stripe file($fm_file) failed"
12352                         return
12353                 fi
12354                 (( tot_len += ext_len ))
12355         done
12356
12357         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12358                 cleanup_130
12359                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12360                 return
12361         fi
12362
12363         cleanup_130
12364
12365         echo "FIEMAP on single striped file succeeded"
12366 }
12367 run_test 130a "FIEMAP (1-stripe file)"
12368
12369 test_130b() {
12370         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12371
12372         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12373         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12374
12375         trap cleanup_130 EXIT RETURN
12376
12377         local fm_file=$DIR/$tfile
12378         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12379                         error "setstripe on $fm_file"
12380         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12381                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12382
12383         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12384                 error "dd failed on $fm_file"
12385
12386         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12387         filefrag_op=$(filefrag -ve -k $fm_file |
12388                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12389
12390         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12391                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12392
12393         IFS=$'\n'
12394         tot_len=0
12395         num_luns=1
12396         for line in $filefrag_op
12397         do
12398                 frag_lun=$(echo $line | cut -d: -f5 |
12399                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12400                 ext_len=$(echo $line | cut -d: -f4)
12401                 if (( $frag_lun != $last_lun )); then
12402                         if (( tot_len != 1024 )); then
12403                                 cleanup_130
12404                                 error "FIEMAP on $fm_file failed; returned " \
12405                                 "len $tot_len for OST $last_lun instead of 1024"
12406                                 return
12407                         else
12408                                 (( num_luns += 1 ))
12409                                 tot_len=0
12410                         fi
12411                 fi
12412                 (( tot_len += ext_len ))
12413                 last_lun=$frag_lun
12414         done
12415         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12416                 cleanup_130
12417                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12418                         "luns or wrong len for OST $last_lun"
12419                 return
12420         fi
12421
12422         cleanup_130
12423
12424         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12425 }
12426 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12427
12428 test_130c() {
12429         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12430
12431         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12432         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12433
12434         trap cleanup_130 EXIT RETURN
12435
12436         local fm_file=$DIR/$tfile
12437         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12438         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12439                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12440
12441         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12442                         error "dd failed on $fm_file"
12443
12444         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12445         filefrag_op=$(filefrag -ve -k $fm_file |
12446                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12447
12448         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12449                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12450
12451         IFS=$'\n'
12452         tot_len=0
12453         num_luns=1
12454         for line in $filefrag_op
12455         do
12456                 frag_lun=$(echo $line | cut -d: -f5 |
12457                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12458                 ext_len=$(echo $line | cut -d: -f4)
12459                 if (( $frag_lun != $last_lun )); then
12460                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12461                         if (( logical != 512 )); then
12462                                 cleanup_130
12463                                 error "FIEMAP on $fm_file failed; returned " \
12464                                 "logical start for lun $logical instead of 512"
12465                                 return
12466                         fi
12467                         if (( tot_len != 512 )); then
12468                                 cleanup_130
12469                                 error "FIEMAP on $fm_file failed; returned " \
12470                                 "len $tot_len for OST $last_lun instead of 1024"
12471                                 return
12472                         else
12473                                 (( num_luns += 1 ))
12474                                 tot_len=0
12475                         fi
12476                 fi
12477                 (( tot_len += ext_len ))
12478                 last_lun=$frag_lun
12479         done
12480         if (( num_luns != 2 || tot_len != 512 )); then
12481                 cleanup_130
12482                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12483                         "luns or wrong len for OST $last_lun"
12484                 return
12485         fi
12486
12487         cleanup_130
12488
12489         echo "FIEMAP on 2-stripe file with hole succeeded"
12490 }
12491 run_test 130c "FIEMAP (2-stripe file with hole)"
12492
12493 test_130d() {
12494         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12495
12496         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12497         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12498
12499         trap cleanup_130 EXIT RETURN
12500
12501         local fm_file=$DIR/$tfile
12502         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12503                         error "setstripe on $fm_file"
12504         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12505                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12506
12507         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12508         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12509                 error "dd failed on $fm_file"
12510
12511         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12512         filefrag_op=$(filefrag -ve -k $fm_file |
12513                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12514
12515         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12516                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12517
12518         IFS=$'\n'
12519         tot_len=0
12520         num_luns=1
12521         for line in $filefrag_op
12522         do
12523                 frag_lun=$(echo $line | cut -d: -f5 |
12524                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12525                 ext_len=$(echo $line | cut -d: -f4)
12526                 if (( $frag_lun != $last_lun )); then
12527                         if (( tot_len != 1024 )); then
12528                                 cleanup_130
12529                                 error "FIEMAP on $fm_file failed; returned " \
12530                                 "len $tot_len for OST $last_lun instead of 1024"
12531                                 return
12532                         else
12533                                 (( num_luns += 1 ))
12534                                 tot_len=0
12535                         fi
12536                 fi
12537                 (( tot_len += ext_len ))
12538                 last_lun=$frag_lun
12539         done
12540         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12541                 cleanup_130
12542                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12543                         "luns or wrong len for OST $last_lun"
12544                 return
12545         fi
12546
12547         cleanup_130
12548
12549         echo "FIEMAP on N-stripe file succeeded"
12550 }
12551 run_test 130d "FIEMAP (N-stripe file)"
12552
12553 test_130e() {
12554         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12555
12556         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12557         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12558
12559         trap cleanup_130 EXIT RETURN
12560
12561         local fm_file=$DIR/$tfile
12562         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12563         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12564                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12565
12566         NUM_BLKS=512
12567         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12568         for ((i = 0; i < $NUM_BLKS; i++))
12569         do
12570                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12571         done
12572
12573         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12574         filefrag_op=$(filefrag -ve -k $fm_file |
12575                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12576
12577         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12578                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12579
12580         IFS=$'\n'
12581         tot_len=0
12582         num_luns=1
12583         for line in $filefrag_op
12584         do
12585                 frag_lun=$(echo $line | cut -d: -f5 |
12586                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12587                 ext_len=$(echo $line | cut -d: -f4)
12588                 if (( $frag_lun != $last_lun )); then
12589                         if (( tot_len != $EXPECTED_LEN )); then
12590                                 cleanup_130
12591                                 error "FIEMAP on $fm_file failed; returned " \
12592                                 "len $tot_len for OST $last_lun instead " \
12593                                 "of $EXPECTED_LEN"
12594                                 return
12595                         else
12596                                 (( num_luns += 1 ))
12597                                 tot_len=0
12598                         fi
12599                 fi
12600                 (( tot_len += ext_len ))
12601                 last_lun=$frag_lun
12602         done
12603         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12604                 cleanup_130
12605                 error "FIEMAP on $fm_file failed; returned wrong number " \
12606                         "of luns or wrong len for OST $last_lun"
12607                 return
12608         fi
12609
12610         cleanup_130
12611
12612         echo "FIEMAP with continuation calls succeeded"
12613 }
12614 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12615
12616 test_130f() {
12617         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12618         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12619
12620         local fm_file=$DIR/$tfile
12621         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12622                 error "multiop create with lov_delay_create on $fm_file"
12623
12624         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12625         filefrag_extents=$(filefrag -vek $fm_file |
12626                            awk '/extents? found/ { print $2 }')
12627         if [[ "$filefrag_extents" != "0" ]]; then
12628                 error "FIEMAP on $fm_file failed; " \
12629                       "returned $filefrag_extents expected 0"
12630         fi
12631
12632         rm -f $fm_file
12633 }
12634 run_test 130f "FIEMAP (unstriped file)"
12635
12636 # Test for writev/readv
12637 test_131a() {
12638         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12639                 error "writev test failed"
12640         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12641                 error "readv failed"
12642         rm -f $DIR/$tfile
12643 }
12644 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12645
12646 test_131b() {
12647         local fsize=$((524288 + 1048576 + 1572864))
12648         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12649                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12650                         error "append writev test failed"
12651
12652         ((fsize += 1572864 + 1048576))
12653         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12654                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12655                         error "append writev test failed"
12656         rm -f $DIR/$tfile
12657 }
12658 run_test 131b "test append writev"
12659
12660 test_131c() {
12661         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12662         error "NOT PASS"
12663 }
12664 run_test 131c "test read/write on file w/o objects"
12665
12666 test_131d() {
12667         rwv -f $DIR/$tfile -w -n 1 1572864
12668         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12669         if [ "$NOB" != 1572864 ]; then
12670                 error "Short read filed: read $NOB bytes instead of 1572864"
12671         fi
12672         rm -f $DIR/$tfile
12673 }
12674 run_test 131d "test short read"
12675
12676 test_131e() {
12677         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12678         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12679         error "read hitting hole failed"
12680         rm -f $DIR/$tfile
12681 }
12682 run_test 131e "test read hitting hole"
12683
12684 check_stats() {
12685         local facet=$1
12686         local op=$2
12687         local want=${3:-0}
12688         local res
12689
12690         case $facet in
12691         mds*) res=$(do_facet $facet \
12692                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12693                  ;;
12694         ost*) res=$(do_facet $facet \
12695                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12696                  ;;
12697         *) error "Wrong facet '$facet'" ;;
12698         esac
12699         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12700         # if the argument $3 is zero, it means any stat increment is ok.
12701         if [[ $want -gt 0 ]]; then
12702                 local count=$(echo $res | awk '{ print $2 }')
12703                 [[ $count -ne $want ]] &&
12704                         error "The $op counter on $facet is $count, not $want"
12705         fi
12706 }
12707
12708 test_133a() {
12709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12710         remote_ost_nodsh && skip "remote OST with nodsh"
12711         remote_mds_nodsh && skip "remote MDS with nodsh"
12712         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12713                 skip_env "MDS doesn't support rename stats"
12714
12715         local testdir=$DIR/${tdir}/stats_testdir
12716
12717         mkdir -p $DIR/${tdir}
12718
12719         # clear stats.
12720         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12721         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12722
12723         # verify mdt stats first.
12724         mkdir ${testdir} || error "mkdir failed"
12725         check_stats $SINGLEMDS "mkdir" 1
12726         touch ${testdir}/${tfile} || error "touch failed"
12727         check_stats $SINGLEMDS "open" 1
12728         check_stats $SINGLEMDS "close" 1
12729         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12730                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12731                 check_stats $SINGLEMDS "mknod" 2
12732         }
12733         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12734         check_stats $SINGLEMDS "unlink" 1
12735         rm -f ${testdir}/${tfile} || error "file remove failed"
12736         check_stats $SINGLEMDS "unlink" 2
12737
12738         # remove working dir and check mdt stats again.
12739         rmdir ${testdir} || error "rmdir failed"
12740         check_stats $SINGLEMDS "rmdir" 1
12741
12742         local testdir1=$DIR/${tdir}/stats_testdir1
12743         mkdir -p ${testdir}
12744         mkdir -p ${testdir1}
12745         touch ${testdir1}/test1
12746         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12747         check_stats $SINGLEMDS "crossdir_rename" 1
12748
12749         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12750         check_stats $SINGLEMDS "samedir_rename" 1
12751
12752         rm -rf $DIR/${tdir}
12753 }
12754 run_test 133a "Verifying MDT stats ========================================"
12755
12756 test_133b() {
12757         local res
12758
12759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12760         remote_ost_nodsh && skip "remote OST with nodsh"
12761         remote_mds_nodsh && skip "remote MDS with nodsh"
12762
12763         local testdir=$DIR/${tdir}/stats_testdir
12764
12765         mkdir -p ${testdir} || error "mkdir failed"
12766         touch ${testdir}/${tfile} || error "touch failed"
12767         cancel_lru_locks mdc
12768
12769         # clear stats.
12770         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12771         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12772
12773         # extra mdt stats verification.
12774         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12775         check_stats $SINGLEMDS "setattr" 1
12776         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12777         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12778         then            # LU-1740
12779                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12780                 check_stats $SINGLEMDS "getattr" 1
12781         fi
12782         rm -rf $DIR/${tdir}
12783
12784         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12785         # so the check below is not reliable
12786         [ $MDSCOUNT -eq 1 ] || return 0
12787
12788         # Sleep to avoid a cached response.
12789         #define OBD_STATFS_CACHE_SECONDS 1
12790         sleep 2
12791         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12792         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12793         $LFS df || error "lfs failed"
12794         check_stats $SINGLEMDS "statfs" 1
12795
12796         # check aggregated statfs (LU-10018)
12797         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12798                 return 0
12799         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12800                 return 0
12801         sleep 2
12802         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12803         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12804         df $DIR
12805         check_stats $SINGLEMDS "statfs" 1
12806
12807         # We want to check that the client didn't send OST_STATFS to
12808         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12809         # extra care is needed here.
12810         if remote_mds; then
12811                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12812                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12813
12814                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12815                 [ "$res" ] && error "OST got STATFS"
12816         fi
12817
12818         return 0
12819 }
12820 run_test 133b "Verifying extra MDT stats =================================="
12821
12822 test_133c() {
12823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12824         remote_ost_nodsh && skip "remote OST with nodsh"
12825         remote_mds_nodsh && skip "remote MDS with nodsh"
12826
12827         local testdir=$DIR/$tdir/stats_testdir
12828
12829         test_mkdir -p $testdir
12830
12831         # verify obdfilter stats.
12832         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12833         sync
12834         cancel_lru_locks osc
12835         wait_delete_completed
12836
12837         # clear stats.
12838         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12839         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12840
12841         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12842                 error "dd failed"
12843         sync
12844         cancel_lru_locks osc
12845         check_stats ost1 "write" 1
12846
12847         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12848         check_stats ost1 "read" 1
12849
12850         > $testdir/$tfile || error "truncate failed"
12851         check_stats ost1 "punch" 1
12852
12853         rm -f $testdir/$tfile || error "file remove failed"
12854         wait_delete_completed
12855         check_stats ost1 "destroy" 1
12856
12857         rm -rf $DIR/$tdir
12858 }
12859 run_test 133c "Verifying OST stats ========================================"
12860
12861 order_2() {
12862         local value=$1
12863         local orig=$value
12864         local order=1
12865
12866         while [ $value -ge 2 ]; do
12867                 order=$((order*2))
12868                 value=$((value/2))
12869         done
12870
12871         if [ $orig -gt $order ]; then
12872                 order=$((order*2))
12873         fi
12874         echo $order
12875 }
12876
12877 size_in_KMGT() {
12878     local value=$1
12879     local size=('K' 'M' 'G' 'T');
12880     local i=0
12881     local size_string=$value
12882
12883     while [ $value -ge 1024 ]; do
12884         if [ $i -gt 3 ]; then
12885             #T is the biggest unit we get here, if that is bigger,
12886             #just return XXXT
12887             size_string=${value}T
12888             break
12889         fi
12890         value=$((value >> 10))
12891         if [ $value -lt 1024 ]; then
12892             size_string=${value}${size[$i]}
12893             break
12894         fi
12895         i=$((i + 1))
12896     done
12897
12898     echo $size_string
12899 }
12900
12901 get_rename_size() {
12902         local size=$1
12903         local context=${2:-.}
12904         local sample=$(do_facet $SINGLEMDS $LCTL \
12905                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12906                 grep -A1 $context |
12907                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12908         echo $sample
12909 }
12910
12911 test_133d() {
12912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12913         remote_ost_nodsh && skip "remote OST with nodsh"
12914         remote_mds_nodsh && skip "remote MDS with nodsh"
12915         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12916                 skip_env "MDS doesn't support rename stats"
12917
12918         local testdir1=$DIR/${tdir}/stats_testdir1
12919         local testdir2=$DIR/${tdir}/stats_testdir2
12920         mkdir -p $DIR/${tdir}
12921
12922         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12923
12924         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12925         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12926
12927         createmany -o $testdir1/test 512 || error "createmany failed"
12928
12929         # check samedir rename size
12930         mv ${testdir1}/test0 ${testdir1}/test_0
12931
12932         local testdir1_size=$(ls -l $DIR/${tdir} |
12933                 awk '/stats_testdir1/ {print $5}')
12934         local testdir2_size=$(ls -l $DIR/${tdir} |
12935                 awk '/stats_testdir2/ {print $5}')
12936
12937         testdir1_size=$(order_2 $testdir1_size)
12938         testdir2_size=$(order_2 $testdir2_size)
12939
12940         testdir1_size=$(size_in_KMGT $testdir1_size)
12941         testdir2_size=$(size_in_KMGT $testdir2_size)
12942
12943         echo "source rename dir size: ${testdir1_size}"
12944         echo "target rename dir size: ${testdir2_size}"
12945
12946         local cmd="do_facet $SINGLEMDS $LCTL "
12947         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12948
12949         eval $cmd || error "$cmd failed"
12950         local samedir=$($cmd | grep 'same_dir')
12951         local same_sample=$(get_rename_size $testdir1_size)
12952         [ -z "$samedir" ] && error "samedir_rename_size count error"
12953         [[ $same_sample -eq 1 ]] ||
12954                 error "samedir_rename_size error $same_sample"
12955         echo "Check same dir rename stats success"
12956
12957         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12958
12959         # check crossdir rename size
12960         mv ${testdir1}/test_0 ${testdir2}/test_0
12961
12962         testdir1_size=$(ls -l $DIR/${tdir} |
12963                 awk '/stats_testdir1/ {print $5}')
12964         testdir2_size=$(ls -l $DIR/${tdir} |
12965                 awk '/stats_testdir2/ {print $5}')
12966
12967         testdir1_size=$(order_2 $testdir1_size)
12968         testdir2_size=$(order_2 $testdir2_size)
12969
12970         testdir1_size=$(size_in_KMGT $testdir1_size)
12971         testdir2_size=$(size_in_KMGT $testdir2_size)
12972
12973         echo "source rename dir size: ${testdir1_size}"
12974         echo "target rename dir size: ${testdir2_size}"
12975
12976         eval $cmd || error "$cmd failed"
12977         local crossdir=$($cmd | grep 'crossdir')
12978         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12979         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12980         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12981         [[ $src_sample -eq 1 ]] ||
12982                 error "crossdir_rename_size error $src_sample"
12983         [[ $tgt_sample -eq 1 ]] ||
12984                 error "crossdir_rename_size error $tgt_sample"
12985         echo "Check cross dir rename stats success"
12986         rm -rf $DIR/${tdir}
12987 }
12988 run_test 133d "Verifying rename_stats ========================================"
12989
12990 test_133e() {
12991         remote_mds_nodsh && skip "remote MDS with nodsh"
12992         remote_ost_nodsh && skip "remote OST with nodsh"
12993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12994
12995         local testdir=$DIR/${tdir}/stats_testdir
12996         local ctr f0 f1 bs=32768 count=42 sum
12997
12998         mkdir -p ${testdir} || error "mkdir failed"
12999
13000         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13001
13002         for ctr in {write,read}_bytes; do
13003                 sync
13004                 cancel_lru_locks osc
13005
13006                 do_facet ost1 $LCTL set_param -n \
13007                         "obdfilter.*.exports.clear=clear"
13008
13009                 if [ $ctr = write_bytes ]; then
13010                         f0=/dev/zero
13011                         f1=${testdir}/${tfile}
13012                 else
13013                         f0=${testdir}/${tfile}
13014                         f1=/dev/null
13015                 fi
13016
13017                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13018                         error "dd failed"
13019                 sync
13020                 cancel_lru_locks osc
13021
13022                 sum=$(do_facet ost1 $LCTL get_param \
13023                         "obdfilter.*.exports.*.stats" |
13024                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13025                                 $1 == ctr { sum += $7 }
13026                                 END { printf("%0.0f", sum) }')
13027
13028                 if ((sum != bs * count)); then
13029                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13030                 fi
13031         done
13032
13033         rm -rf $DIR/${tdir}
13034 }
13035 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13036
13037 test_133f() {
13038         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13039                 skip "too old lustre for get_param -R ($facet_ver)"
13040
13041         # verifying readability.
13042         $LCTL get_param -R '*' &> /dev/null
13043
13044         # Verifing writability with badarea_io.
13045         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13046                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13047                 error "client badarea_io failed"
13048
13049         # remount the FS in case writes/reads /proc break the FS
13050         cleanup || error "failed to unmount"
13051         setup || error "failed to setup"
13052 }
13053 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13054
13055 test_133g() {
13056         remote_mds_nodsh && skip "remote MDS with nodsh"
13057         remote_ost_nodsh && skip "remote OST with nodsh"
13058
13059         local facet
13060         for facet in mds1 ost1; do
13061                 local facet_ver=$(lustre_version_code $facet)
13062                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13063                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13064                 else
13065                         log "$facet: too old lustre for get_param -R"
13066                 fi
13067                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13068                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13069                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13070                                 xargs badarea_io" ||
13071                                         error "$facet badarea_io failed"
13072                 else
13073                         skip_noexit "$facet: too old lustre for get_param -R"
13074                 fi
13075         done
13076
13077         # remount the FS in case writes/reads /proc break the FS
13078         cleanup || error "failed to unmount"
13079         setup || error "failed to setup"
13080 }
13081 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13082
13083 test_133h() {
13084         remote_mds_nodsh && skip "remote MDS with nodsh"
13085         remote_ost_nodsh && skip "remote OST with nodsh"
13086         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13087                 skip "Need MDS version at least 2.9.54"
13088
13089         local facet
13090         for facet in client mds1 ost1; do
13091                 # Get the list of files that are missing the terminating newline
13092                 local plist=$(do_facet $facet
13093                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13094                 local ent
13095                 for ent in $plist; do
13096                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13097                                 awk -v FS='\v' -v RS='\v\v' \
13098                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13099                                         print FILENAME}'" 2>/dev/null)
13100                         [ -z $missing ] || {
13101                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13102                                 error "file does not end with newline: $facet-$ent"
13103                         }
13104                 done
13105         done
13106 }
13107 run_test 133h "Proc files should end with newlines"
13108
13109 test_134a() {
13110         remote_mds_nodsh && skip "remote MDS with nodsh"
13111         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13112                 skip "Need MDS version at least 2.7.54"
13113
13114         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13115         cancel_lru_locks mdc
13116
13117         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13118         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13119         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13120
13121         local nr=1000
13122         createmany -o $DIR/$tdir/f $nr ||
13123                 error "failed to create $nr files in $DIR/$tdir"
13124         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13125
13126         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13127         do_facet mds1 $LCTL set_param fail_loc=0x327
13128         do_facet mds1 $LCTL set_param fail_val=500
13129         touch $DIR/$tdir/m
13130
13131         echo "sleep 10 seconds ..."
13132         sleep 10
13133         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13134
13135         do_facet mds1 $LCTL set_param fail_loc=0
13136         do_facet mds1 $LCTL set_param fail_val=0
13137         [ $lck_cnt -lt $unused ] ||
13138                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13139
13140         rm $DIR/$tdir/m
13141         unlinkmany $DIR/$tdir/f $nr
13142 }
13143 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13144
13145 test_134b() {
13146         remote_mds_nodsh && skip "remote MDS with nodsh"
13147         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13148                 skip "Need MDS version at least 2.7.54"
13149
13150         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13151         cancel_lru_locks mdc
13152
13153         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13154                         ldlm.lock_reclaim_threshold_mb)
13155         # disable reclaim temporarily
13156         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13157
13158         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13159         do_facet mds1 $LCTL set_param fail_loc=0x328
13160         do_facet mds1 $LCTL set_param fail_val=500
13161
13162         $LCTL set_param debug=+trace
13163
13164         local nr=600
13165         createmany -o $DIR/$tdir/f $nr &
13166         local create_pid=$!
13167
13168         echo "Sleep $TIMEOUT seconds ..."
13169         sleep $TIMEOUT
13170         if ! ps -p $create_pid  > /dev/null 2>&1; then
13171                 do_facet mds1 $LCTL set_param fail_loc=0
13172                 do_facet mds1 $LCTL set_param fail_val=0
13173                 do_facet mds1 $LCTL set_param \
13174                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13175                 error "createmany finished incorrectly!"
13176         fi
13177         do_facet mds1 $LCTL set_param fail_loc=0
13178         do_facet mds1 $LCTL set_param fail_val=0
13179         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13180         wait $create_pid || return 1
13181
13182         unlinkmany $DIR/$tdir/f $nr
13183 }
13184 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13185
13186 test_135() {
13187         remote_mds_nodsh && skip "remote MDS with nodsh"
13188         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13189                 skip "Need MDS version at least 2.13.50"
13190         local fname
13191
13192         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13193
13194 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13195         #set only one record at plain llog
13196         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13197
13198         #fill already existed plain llog each 64767
13199         #wrapping whole catalog
13200         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13201
13202         createmany -o $DIR/$tdir/$tfile_ 64700
13203         for (( i = 0; i < 64700; i = i + 2 ))
13204         do
13205                 rm $DIR/$tdir/$tfile_$i &
13206                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13207                 local pid=$!
13208                 wait $pid
13209         done
13210
13211         #waiting osp synchronization
13212         wait_delete_completed
13213 }
13214 run_test 135 "Race catalog processing"
13215
13216 test_136() {
13217         remote_mds_nodsh && skip "remote MDS with nodsh"
13218         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13219                 skip "Need MDS version at least 2.13.50"
13220         local fname
13221
13222         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13223         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13224         #set only one record at plain llog
13225 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13226         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13227
13228         #fill already existed 2 plain llogs each 64767
13229         #wrapping whole catalog
13230         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13231         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13232         wait_delete_completed
13233
13234         createmany -o $DIR/$tdir/$tfile_ 10
13235         sleep 25
13236
13237         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13238         for (( i = 0; i < 10; i = i + 3 ))
13239         do
13240                 rm $DIR/$tdir/$tfile_$i &
13241                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13242                 local pid=$!
13243                 wait $pid
13244                 sleep 7
13245                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13246         done
13247
13248         #waiting osp synchronization
13249         wait_delete_completed
13250 }
13251 run_test 136 "Race catalog processing 2"
13252
13253 test_140() { #bug-17379
13254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13255
13256         test_mkdir $DIR/$tdir
13257         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13258         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13259
13260         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13261         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13262         local i=0
13263         while i=$((i + 1)); do
13264                 test_mkdir $i
13265                 cd $i || error "Changing to $i"
13266                 ln -s ../stat stat || error "Creating stat symlink"
13267                 # Read the symlink until ELOOP present,
13268                 # not LBUGing the system is considered success,
13269                 # we didn't overrun the stack.
13270                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13271                 if [ $ret -ne 0 ]; then
13272                         if [ $ret -eq 40 ]; then
13273                                 break  # -ELOOP
13274                         else
13275                                 error "Open stat symlink"
13276                                         return
13277                         fi
13278                 fi
13279         done
13280         i=$((i - 1))
13281         echo "The symlink depth = $i"
13282         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13283                 error "Invalid symlink depth"
13284
13285         # Test recursive symlink
13286         ln -s symlink_self symlink_self
13287         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13288         echo "open symlink_self returns $ret"
13289         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13290 }
13291 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13292
13293 test_150a() {
13294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13295
13296         local TF="$TMP/$tfile"
13297
13298         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13299         cp $TF $DIR/$tfile
13300         cancel_lru_locks $OSC
13301         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13302         remount_client $MOUNT
13303         df -P $MOUNT
13304         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13305
13306         $TRUNCATE $TF 6000
13307         $TRUNCATE $DIR/$tfile 6000
13308         cancel_lru_locks $OSC
13309         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13310
13311         echo "12345" >>$TF
13312         echo "12345" >>$DIR/$tfile
13313         cancel_lru_locks $OSC
13314         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13315
13316         echo "12345" >>$TF
13317         echo "12345" >>$DIR/$tfile
13318         cancel_lru_locks $OSC
13319         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13320
13321         rm -f $TF
13322         true
13323 }
13324 run_test 150a "truncate/append tests"
13325
13326 test_150b() {
13327         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13328         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13329                 skip "Need OST version at least 2.13.53"
13330         touch $DIR/$tfile
13331         check_fallocate $DIR/$tfile || error "fallocate failed"
13332 }
13333 run_test 150b "Verify fallocate (prealloc) functionality"
13334
13335 test_150c() {
13336         local bytes
13337         local want
13338
13339         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13340         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13341                 skip "Need OST version at least 2.13.53"
13342
13343         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13344         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13345         sync; sync_all_data
13346         cancel_lru_locks $OSC
13347         sleep 5
13348         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13349         want=$((OSTCOUNT * 1048576))
13350
13351         # Must allocate all requested space, not more than 5% extra
13352         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13353                 error "bytes $bytes is not $want"
13354 }
13355 run_test 150c "Verify fallocate Size and Blocks"
13356
13357 test_150d() {
13358         local bytes
13359         local want
13360
13361         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13362         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13363                 skip "Need OST version at least 2.13.53"
13364
13365         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13366         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13367         sync; sync_all_data
13368         cancel_lru_locks $OSC
13369         sleep 5
13370         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13371         want=$((OSTCOUNT * 1048576))
13372
13373         # Must allocate all requested space, not more than 5% extra
13374         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13375                 error "bytes $bytes is not $want"
13376 }
13377 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13378
13379 #LU-2902 roc_hit was not able to read all values from lproc
13380 function roc_hit_init() {
13381         local list=$(comma_list $(osts_nodes))
13382         local dir=$DIR/$tdir-check
13383         local file=$dir/$tfile
13384         local BEFORE
13385         local AFTER
13386         local idx
13387
13388         test_mkdir $dir
13389         #use setstripe to do a write to every ost
13390         for i in $(seq 0 $((OSTCOUNT-1))); do
13391                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13392                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13393                 idx=$(printf %04x $i)
13394                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13395                         awk '$1 == "cache_access" {sum += $7}
13396                                 END { printf("%0.0f", sum) }')
13397
13398                 cancel_lru_locks osc
13399                 cat $file >/dev/null
13400
13401                 AFTER=$(get_osd_param $list *OST*$idx stats |
13402                         awk '$1 == "cache_access" {sum += $7}
13403                                 END { printf("%0.0f", sum) }')
13404
13405                 echo BEFORE:$BEFORE AFTER:$AFTER
13406                 if ! let "AFTER - BEFORE == 4"; then
13407                         rm -rf $dir
13408                         error "roc_hit is not safe to use"
13409                 fi
13410                 rm $file
13411         done
13412
13413         rm -rf $dir
13414 }
13415
13416 function roc_hit() {
13417         local list=$(comma_list $(osts_nodes))
13418         echo $(get_osd_param $list '' stats |
13419                 awk '$1 == "cache_hit" {sum += $7}
13420                         END { printf("%0.0f", sum) }')
13421 }
13422
13423 function set_cache() {
13424         local on=1
13425
13426         if [ "$2" == "off" ]; then
13427                 on=0;
13428         fi
13429         local list=$(comma_list $(osts_nodes))
13430         set_osd_param $list '' $1_cache_enable $on
13431
13432         cancel_lru_locks osc
13433 }
13434
13435 test_151() {
13436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13437         remote_ost_nodsh && skip "remote OST with nodsh"
13438
13439         local CPAGES=3
13440         local list=$(comma_list $(osts_nodes))
13441
13442         # check whether obdfilter is cache capable at all
13443         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13444                 skip "not cache-capable obdfilter"
13445         fi
13446
13447         # check cache is enabled on all obdfilters
13448         if get_osd_param $list '' read_cache_enable | grep 0; then
13449                 skip "oss cache is disabled"
13450         fi
13451
13452         set_osd_param $list '' writethrough_cache_enable 1
13453
13454         # check write cache is enabled on all obdfilters
13455         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13456                 skip "oss write cache is NOT enabled"
13457         fi
13458
13459         roc_hit_init
13460
13461         #define OBD_FAIL_OBD_NO_LRU  0x609
13462         do_nodes $list $LCTL set_param fail_loc=0x609
13463
13464         # pages should be in the case right after write
13465         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13466                 error "dd failed"
13467
13468         local BEFORE=$(roc_hit)
13469         cancel_lru_locks osc
13470         cat $DIR/$tfile >/dev/null
13471         local AFTER=$(roc_hit)
13472
13473         do_nodes $list $LCTL set_param fail_loc=0
13474
13475         if ! let "AFTER - BEFORE == CPAGES"; then
13476                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13477         fi
13478
13479         cancel_lru_locks osc
13480         # invalidates OST cache
13481         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13482         set_osd_param $list '' read_cache_enable 0
13483         cat $DIR/$tfile >/dev/null
13484
13485         # now data shouldn't be found in the cache
13486         BEFORE=$(roc_hit)
13487         cancel_lru_locks osc
13488         cat $DIR/$tfile >/dev/null
13489         AFTER=$(roc_hit)
13490         if let "AFTER - BEFORE != 0"; then
13491                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13492         fi
13493
13494         set_osd_param $list '' read_cache_enable 1
13495         rm -f $DIR/$tfile
13496 }
13497 run_test 151 "test cache on oss and controls ==============================="
13498
13499 test_152() {
13500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13501
13502         local TF="$TMP/$tfile"
13503
13504         # simulate ENOMEM during write
13505 #define OBD_FAIL_OST_NOMEM      0x226
13506         lctl set_param fail_loc=0x80000226
13507         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13508         cp $TF $DIR/$tfile
13509         sync || error "sync failed"
13510         lctl set_param fail_loc=0
13511
13512         # discard client's cache
13513         cancel_lru_locks osc
13514
13515         # simulate ENOMEM during read
13516         lctl set_param fail_loc=0x80000226
13517         cmp $TF $DIR/$tfile || error "cmp failed"
13518         lctl set_param fail_loc=0
13519
13520         rm -f $TF
13521 }
13522 run_test 152 "test read/write with enomem ============================"
13523
13524 test_153() {
13525         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13526 }
13527 run_test 153 "test if fdatasync does not crash ======================="
13528
13529 dot_lustre_fid_permission_check() {
13530         local fid=$1
13531         local ffid=$MOUNT/.lustre/fid/$fid
13532         local test_dir=$2
13533
13534         echo "stat fid $fid"
13535         stat $ffid > /dev/null || error "stat $ffid failed."
13536         echo "touch fid $fid"
13537         touch $ffid || error "touch $ffid failed."
13538         echo "write to fid $fid"
13539         cat /etc/hosts > $ffid || error "write $ffid failed."
13540         echo "read fid $fid"
13541         diff /etc/hosts $ffid || error "read $ffid failed."
13542         echo "append write to fid $fid"
13543         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13544         echo "rename fid $fid"
13545         mv $ffid $test_dir/$tfile.1 &&
13546                 error "rename $ffid to $tfile.1 should fail."
13547         touch $test_dir/$tfile.1
13548         mv $test_dir/$tfile.1 $ffid &&
13549                 error "rename $tfile.1 to $ffid should fail."
13550         rm -f $test_dir/$tfile.1
13551         echo "truncate fid $fid"
13552         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13553         echo "link fid $fid"
13554         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13555         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13556                 echo "setfacl fid $fid"
13557                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13558                 echo "getfacl fid $fid"
13559                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13560         fi
13561         echo "unlink fid $fid"
13562         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13563         echo "mknod fid $fid"
13564         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13565
13566         fid=[0xf00000400:0x1:0x0]
13567         ffid=$MOUNT/.lustre/fid/$fid
13568
13569         echo "stat non-exist fid $fid"
13570         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13571         echo "write to non-exist fid $fid"
13572         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13573         echo "link new fid $fid"
13574         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13575
13576         mkdir -p $test_dir/$tdir
13577         touch $test_dir/$tdir/$tfile
13578         fid=$($LFS path2fid $test_dir/$tdir)
13579         rc=$?
13580         [ $rc -ne 0 ] &&
13581                 error "error: could not get fid for $test_dir/$dir/$tfile."
13582
13583         ffid=$MOUNT/.lustre/fid/$fid
13584
13585         echo "ls $fid"
13586         ls $ffid > /dev/null || error "ls $ffid failed."
13587         echo "touch $fid/$tfile.1"
13588         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13589
13590         echo "touch $MOUNT/.lustre/fid/$tfile"
13591         touch $MOUNT/.lustre/fid/$tfile && \
13592                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13593
13594         echo "setxattr to $MOUNT/.lustre/fid"
13595         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13596
13597         echo "listxattr for $MOUNT/.lustre/fid"
13598         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13599
13600         echo "delxattr from $MOUNT/.lustre/fid"
13601         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13602
13603         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13604         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13605                 error "touch invalid fid should fail."
13606
13607         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13608         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13609                 error "touch non-normal fid should fail."
13610
13611         echo "rename $tdir to $MOUNT/.lustre/fid"
13612         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13613                 error "rename to $MOUNT/.lustre/fid should fail."
13614
13615         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13616         then            # LU-3547
13617                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13618                 local new_obf_mode=777
13619
13620                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13621                 chmod $new_obf_mode $DIR/.lustre/fid ||
13622                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13623
13624                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13625                 [ $obf_mode -eq $new_obf_mode ] ||
13626                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13627
13628                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13629                 chmod $old_obf_mode $DIR/.lustre/fid ||
13630                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13631         fi
13632
13633         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13634         fid=$($LFS path2fid $test_dir/$tfile-2)
13635
13636         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13637         then # LU-5424
13638                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13639                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13640                         error "create lov data thru .lustre failed"
13641         fi
13642         echo "cp /etc/passwd $test_dir/$tfile-2"
13643         cp /etc/passwd $test_dir/$tfile-2 ||
13644                 error "copy to $test_dir/$tfile-2 failed."
13645         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13646         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13647                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13648
13649         rm -rf $test_dir/tfile.lnk
13650         rm -rf $test_dir/$tfile-2
13651 }
13652
13653 test_154A() {
13654         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13655                 skip "Need MDS version at least 2.4.1"
13656
13657         local tf=$DIR/$tfile
13658         touch $tf
13659
13660         local fid=$($LFS path2fid $tf)
13661         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13662
13663         # check that we get the same pathname back
13664         local rootpath
13665         local found
13666         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13667                 echo "$rootpath $fid"
13668                 found=$($LFS fid2path $rootpath "$fid")
13669                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13670                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13671         done
13672
13673         # check wrong root path format
13674         rootpath=$MOUNT"_wrong"
13675         found=$($LFS fid2path $rootpath "$fid")
13676         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13677 }
13678 run_test 154A "lfs path2fid and fid2path basic checks"
13679
13680 test_154B() {
13681         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13682                 skip "Need MDS version at least 2.4.1"
13683
13684         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13685         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13686         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13687         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13688
13689         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13690         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13691
13692         # check that we get the same pathname
13693         echo "PFID: $PFID, name: $name"
13694         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13695         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13696         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13697                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13698
13699         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13700 }
13701 run_test 154B "verify the ll_decode_linkea tool"
13702
13703 test_154a() {
13704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13705         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13706         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13707                 skip "Need MDS version at least 2.2.51"
13708         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13709
13710         cp /etc/hosts $DIR/$tfile
13711
13712         fid=$($LFS path2fid $DIR/$tfile)
13713         rc=$?
13714         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13715
13716         dot_lustre_fid_permission_check "$fid" $DIR ||
13717                 error "dot lustre permission check $fid failed"
13718
13719         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13720
13721         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13722
13723         touch $MOUNT/.lustre/file &&
13724                 error "creation is not allowed under .lustre"
13725
13726         mkdir $MOUNT/.lustre/dir &&
13727                 error "mkdir is not allowed under .lustre"
13728
13729         rm -rf $DIR/$tfile
13730 }
13731 run_test 154a "Open-by-FID"
13732
13733 test_154b() {
13734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13735         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13736         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13737         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13738                 skip "Need MDS version at least 2.2.51"
13739
13740         local remote_dir=$DIR/$tdir/remote_dir
13741         local MDTIDX=1
13742         local rc=0
13743
13744         mkdir -p $DIR/$tdir
13745         $LFS mkdir -i $MDTIDX $remote_dir ||
13746                 error "create remote directory failed"
13747
13748         cp /etc/hosts $remote_dir/$tfile
13749
13750         fid=$($LFS path2fid $remote_dir/$tfile)
13751         rc=$?
13752         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13753
13754         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13755                 error "dot lustre permission check $fid failed"
13756         rm -rf $DIR/$tdir
13757 }
13758 run_test 154b "Open-by-FID for remote directory"
13759
13760 test_154c() {
13761         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13762                 skip "Need MDS version at least 2.4.1"
13763
13764         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13765         local FID1=$($LFS path2fid $DIR/$tfile.1)
13766         local FID2=$($LFS path2fid $DIR/$tfile.2)
13767         local FID3=$($LFS path2fid $DIR/$tfile.3)
13768
13769         local N=1
13770         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13771                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13772                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13773                 local want=FID$N
13774                 [ "$FID" = "${!want}" ] ||
13775                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13776                 N=$((N + 1))
13777         done
13778
13779         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13780         do
13781                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13782                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13783                 N=$((N + 1))
13784         done
13785 }
13786 run_test 154c "lfs path2fid and fid2path multiple arguments"
13787
13788 test_154d() {
13789         remote_mds_nodsh && skip "remote MDS with nodsh"
13790         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13791                 skip "Need MDS version at least 2.5.53"
13792
13793         if remote_mds; then
13794                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13795         else
13796                 nid="0@lo"
13797         fi
13798         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13799         local fd
13800         local cmd
13801
13802         rm -f $DIR/$tfile
13803         touch $DIR/$tfile
13804
13805         local fid=$($LFS path2fid $DIR/$tfile)
13806         # Open the file
13807         fd=$(free_fd)
13808         cmd="exec $fd<$DIR/$tfile"
13809         eval $cmd
13810         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13811         echo "$fid_list" | grep "$fid"
13812         rc=$?
13813
13814         cmd="exec $fd>/dev/null"
13815         eval $cmd
13816         if [ $rc -ne 0 ]; then
13817                 error "FID $fid not found in open files list $fid_list"
13818         fi
13819 }
13820 run_test 154d "Verify open file fid"
13821
13822 test_154e()
13823 {
13824         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13825                 skip "Need MDS version at least 2.6.50"
13826
13827         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13828                 error ".lustre returned by readdir"
13829         fi
13830 }
13831 run_test 154e ".lustre is not returned by readdir"
13832
13833 test_154f() {
13834         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13835
13836         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13837         test_mkdir -p -c1 $DIR/$tdir/d
13838         # test dirs inherit from its stripe
13839         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13840         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13841         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13842         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13843         touch $DIR/f
13844
13845         # get fid of parents
13846         local FID0=$($LFS path2fid $DIR/$tdir/d)
13847         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13848         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13849         local FID3=$($LFS path2fid $DIR)
13850
13851         # check that path2fid --parents returns expected <parent_fid>/name
13852         # 1) test for a directory (single parent)
13853         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13854         [ "$parent" == "$FID0/foo1" ] ||
13855                 error "expected parent: $FID0/foo1, got: $parent"
13856
13857         # 2) test for a file with nlink > 1 (multiple parents)
13858         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13859         echo "$parent" | grep -F "$FID1/$tfile" ||
13860                 error "$FID1/$tfile not returned in parent list"
13861         echo "$parent" | grep -F "$FID2/link" ||
13862                 error "$FID2/link not returned in parent list"
13863
13864         # 3) get parent by fid
13865         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13866         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13867         echo "$parent" | grep -F "$FID1/$tfile" ||
13868                 error "$FID1/$tfile not returned in parent list (by fid)"
13869         echo "$parent" | grep -F "$FID2/link" ||
13870                 error "$FID2/link not returned in parent list (by fid)"
13871
13872         # 4) test for entry in root directory
13873         parent=$($LFS path2fid --parents $DIR/f)
13874         echo "$parent" | grep -F "$FID3/f" ||
13875                 error "$FID3/f not returned in parent list"
13876
13877         # 5) test it on root directory
13878         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13879                 error "$MOUNT should not have parents"
13880
13881         # enable xattr caching and check that linkea is correctly updated
13882         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13883         save_lustre_params client "llite.*.xattr_cache" > $save
13884         lctl set_param llite.*.xattr_cache 1
13885
13886         # 6.1) linkea update on rename
13887         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13888
13889         # get parents by fid
13890         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13891         # foo1 should no longer be returned in parent list
13892         echo "$parent" | grep -F "$FID1" &&
13893                 error "$FID1 should no longer be in parent list"
13894         # the new path should appear
13895         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13896                 error "$FID2/$tfile.moved is not in parent list"
13897
13898         # 6.2) linkea update on unlink
13899         rm -f $DIR/$tdir/d/foo2/link
13900         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13901         # foo2/link should no longer be returned in parent list
13902         echo "$parent" | grep -F "$FID2/link" &&
13903                 error "$FID2/link should no longer be in parent list"
13904         true
13905
13906         rm -f $DIR/f
13907         restore_lustre_params < $save
13908         rm -f $save
13909 }
13910 run_test 154f "get parent fids by reading link ea"
13911
13912 test_154g()
13913 {
13914         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13915         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13916            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13917                 skip "Need MDS version at least 2.6.92"
13918
13919         mkdir -p $DIR/$tdir
13920         llapi_fid_test -d $DIR/$tdir
13921 }
13922 run_test 154g "various llapi FID tests"
13923
13924 test_155_small_load() {
13925     local temp=$TMP/$tfile
13926     local file=$DIR/$tfile
13927
13928     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13929         error "dd of=$temp bs=6096 count=1 failed"
13930     cp $temp $file
13931     cancel_lru_locks $OSC
13932     cmp $temp $file || error "$temp $file differ"
13933
13934     $TRUNCATE $temp 6000
13935     $TRUNCATE $file 6000
13936     cmp $temp $file || error "$temp $file differ (truncate1)"
13937
13938     echo "12345" >>$temp
13939     echo "12345" >>$file
13940     cmp $temp $file || error "$temp $file differ (append1)"
13941
13942     echo "12345" >>$temp
13943     echo "12345" >>$file
13944     cmp $temp $file || error "$temp $file differ (append2)"
13945
13946     rm -f $temp $file
13947     true
13948 }
13949
13950 test_155_big_load() {
13951         remote_ost_nodsh && skip "remote OST with nodsh"
13952
13953         local temp=$TMP/$tfile
13954         local file=$DIR/$tfile
13955
13956         free_min_max
13957         local cache_size=$(do_facet ost$((MAXI+1)) \
13958                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13959         local large_file_size=$((cache_size * 2))
13960
13961         echo "OSS cache size: $cache_size KB"
13962         echo "Large file size: $large_file_size KB"
13963
13964         [ $MAXV -le $large_file_size ] &&
13965                 skip_env "max available OST size needs > $large_file_size KB"
13966
13967         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13968
13969         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13970                 error "dd of=$temp bs=$large_file_size count=1k failed"
13971         cp $temp $file
13972         ls -lh $temp $file
13973         cancel_lru_locks osc
13974         cmp $temp $file || error "$temp $file differ"
13975
13976         rm -f $temp $file
13977         true
13978 }
13979
13980 save_writethrough() {
13981         local facets=$(get_facets OST)
13982
13983         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13984 }
13985
13986 test_155a() {
13987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13988
13989         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13990
13991         save_writethrough $p
13992
13993         set_cache read on
13994         set_cache writethrough on
13995         test_155_small_load
13996         restore_lustre_params < $p
13997         rm -f $p
13998 }
13999 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14000
14001 test_155b() {
14002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14003
14004         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14005
14006         save_writethrough $p
14007
14008         set_cache read on
14009         set_cache writethrough off
14010         test_155_small_load
14011         restore_lustre_params < $p
14012         rm -f $p
14013 }
14014 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14015
14016 test_155c() {
14017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14018
14019         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14020
14021         save_writethrough $p
14022
14023         set_cache read off
14024         set_cache writethrough on
14025         test_155_small_load
14026         restore_lustre_params < $p
14027         rm -f $p
14028 }
14029 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14030
14031 test_155d() {
14032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14033
14034         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14035
14036         save_writethrough $p
14037
14038         set_cache read off
14039         set_cache writethrough off
14040         test_155_small_load
14041         restore_lustre_params < $p
14042         rm -f $p
14043 }
14044 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14045
14046 test_155e() {
14047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14048
14049         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14050
14051         save_writethrough $p
14052
14053         set_cache read on
14054         set_cache writethrough on
14055         test_155_big_load
14056         restore_lustre_params < $p
14057         rm -f $p
14058 }
14059 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14060
14061 test_155f() {
14062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14063
14064         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14065
14066         save_writethrough $p
14067
14068         set_cache read on
14069         set_cache writethrough off
14070         test_155_big_load
14071         restore_lustre_params < $p
14072         rm -f $p
14073 }
14074 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14075
14076 test_155g() {
14077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14078
14079         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14080
14081         save_writethrough $p
14082
14083         set_cache read off
14084         set_cache writethrough on
14085         test_155_big_load
14086         restore_lustre_params < $p
14087         rm -f $p
14088 }
14089 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14090
14091 test_155h() {
14092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14093
14094         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14095
14096         save_writethrough $p
14097
14098         set_cache read off
14099         set_cache writethrough off
14100         test_155_big_load
14101         restore_lustre_params < $p
14102         rm -f $p
14103 }
14104 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14105
14106 test_156() {
14107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14108         remote_ost_nodsh && skip "remote OST with nodsh"
14109         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14110                 skip "stats not implemented on old servers"
14111         [ "$ost1_FSTYPE" = "zfs" ] &&
14112                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14113
14114         local CPAGES=3
14115         local BEFORE
14116         local AFTER
14117         local file="$DIR/$tfile"
14118         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14119
14120         save_writethrough $p
14121         roc_hit_init
14122
14123         log "Turn on read and write cache"
14124         set_cache read on
14125         set_cache writethrough on
14126
14127         log "Write data and read it back."
14128         log "Read should be satisfied from the cache."
14129         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14130         BEFORE=$(roc_hit)
14131         cancel_lru_locks osc
14132         cat $file >/dev/null
14133         AFTER=$(roc_hit)
14134         if ! let "AFTER - BEFORE == CPAGES"; then
14135                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14136         else
14137                 log "cache hits: before: $BEFORE, after: $AFTER"
14138         fi
14139
14140         log "Read again; it should be satisfied from the cache."
14141         BEFORE=$AFTER
14142         cancel_lru_locks osc
14143         cat $file >/dev/null
14144         AFTER=$(roc_hit)
14145         if ! let "AFTER - BEFORE == CPAGES"; then
14146                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14147         else
14148                 log "cache hits:: before: $BEFORE, after: $AFTER"
14149         fi
14150
14151         log "Turn off the read cache and turn on the write cache"
14152         set_cache read off
14153         set_cache writethrough on
14154
14155         log "Read again; it should be satisfied from the cache."
14156         BEFORE=$(roc_hit)
14157         cancel_lru_locks osc
14158         cat $file >/dev/null
14159         AFTER=$(roc_hit)
14160         if ! let "AFTER - BEFORE == CPAGES"; then
14161                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14162         else
14163                 log "cache hits:: before: $BEFORE, after: $AFTER"
14164         fi
14165
14166         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14167                 # > 2.12.56 uses pagecache if cached
14168                 log "Read again; it should not be satisfied from the cache."
14169                 BEFORE=$AFTER
14170                 cancel_lru_locks osc
14171                 cat $file >/dev/null
14172                 AFTER=$(roc_hit)
14173                 if ! let "AFTER - BEFORE == 0"; then
14174                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14175                 else
14176                         log "cache hits:: before: $BEFORE, after: $AFTER"
14177                 fi
14178         fi
14179
14180         log "Write data and read it back."
14181         log "Read should be satisfied from the cache."
14182         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14183         BEFORE=$(roc_hit)
14184         cancel_lru_locks osc
14185         cat $file >/dev/null
14186         AFTER=$(roc_hit)
14187         if ! let "AFTER - BEFORE == CPAGES"; then
14188                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14189         else
14190                 log "cache hits:: before: $BEFORE, after: $AFTER"
14191         fi
14192
14193         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14194                 # > 2.12.56 uses pagecache if cached
14195                 log "Read again; it should not be satisfied from the cache."
14196                 BEFORE=$AFTER
14197                 cancel_lru_locks osc
14198                 cat $file >/dev/null
14199                 AFTER=$(roc_hit)
14200                 if ! let "AFTER - BEFORE == 0"; then
14201                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14202                 else
14203                         log "cache hits:: before: $BEFORE, after: $AFTER"
14204                 fi
14205         fi
14206
14207         log "Turn off read and write cache"
14208         set_cache read off
14209         set_cache writethrough off
14210
14211         log "Write data and read it back"
14212         log "It should not be satisfied from the cache."
14213         rm -f $file
14214         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14215         cancel_lru_locks osc
14216         BEFORE=$(roc_hit)
14217         cat $file >/dev/null
14218         AFTER=$(roc_hit)
14219         if ! let "AFTER - BEFORE == 0"; then
14220                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14221         else
14222                 log "cache hits:: before: $BEFORE, after: $AFTER"
14223         fi
14224
14225         log "Turn on the read cache and turn off the write cache"
14226         set_cache read on
14227         set_cache writethrough off
14228
14229         log "Write data and read it back"
14230         log "It should not be satisfied from the cache."
14231         rm -f $file
14232         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14233         BEFORE=$(roc_hit)
14234         cancel_lru_locks osc
14235         cat $file >/dev/null
14236         AFTER=$(roc_hit)
14237         if ! let "AFTER - BEFORE == 0"; then
14238                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14239         else
14240                 log "cache hits:: before: $BEFORE, after: $AFTER"
14241         fi
14242
14243         log "Read again; it should be satisfied from the cache."
14244         BEFORE=$(roc_hit)
14245         cancel_lru_locks osc
14246         cat $file >/dev/null
14247         AFTER=$(roc_hit)
14248         if ! let "AFTER - BEFORE == CPAGES"; then
14249                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14250         else
14251                 log "cache hits:: before: $BEFORE, after: $AFTER"
14252         fi
14253
14254         restore_lustre_params < $p
14255         rm -f $p $file
14256 }
14257 run_test 156 "Verification of tunables"
14258
14259 test_160a() {
14260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14261         remote_mds_nodsh && skip "remote MDS with nodsh"
14262         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14263                 skip "Need MDS version at least 2.2.0"
14264
14265         changelog_register || error "changelog_register failed"
14266         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14267         changelog_users $SINGLEMDS | grep -q $cl_user ||
14268                 error "User $cl_user not found in changelog_users"
14269
14270         # change something
14271         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14272         changelog_clear 0 || error "changelog_clear failed"
14273         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14274         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14275         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14276         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14277         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14278         rm $DIR/$tdir/pics/desktop.jpg
14279
14280         changelog_dump | tail -10
14281
14282         echo "verifying changelog mask"
14283         changelog_chmask "-MKDIR"
14284         changelog_chmask "-CLOSE"
14285
14286         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14287         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14288
14289         changelog_chmask "+MKDIR"
14290         changelog_chmask "+CLOSE"
14291
14292         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14293         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14294
14295         changelog_dump | tail -10
14296         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14297         CLOSES=$(changelog_dump | grep -c "CLOSE")
14298         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14299         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14300
14301         # verify contents
14302         echo "verifying target fid"
14303         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14304         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14305         [ "$fidc" == "$fidf" ] ||
14306                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14307         echo "verifying parent fid"
14308         # The FID returned from the Changelog may be the directory shard on
14309         # a different MDT, and not the FID returned by path2fid on the parent.
14310         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14311         # since this is what will matter when recreating this file in the tree.
14312         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14313         local pathp=$($LFS fid2path $MOUNT "$fidp")
14314         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14315                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14316
14317         echo "getting records for $cl_user"
14318         changelog_users $SINGLEMDS
14319         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14320         local nclr=3
14321         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14322                 error "changelog_clear failed"
14323         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14324         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14325         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14326                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14327
14328         local min0_rec=$(changelog_users $SINGLEMDS |
14329                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14330         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14331                           awk '{ print $1; exit; }')
14332
14333         changelog_dump | tail -n 5
14334         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14335         [ $first_rec == $((min0_rec + 1)) ] ||
14336                 error "first index should be $min0_rec + 1 not $first_rec"
14337
14338         # LU-3446 changelog index reset on MDT restart
14339         local cur_rec1=$(changelog_users $SINGLEMDS |
14340                          awk '/^current.index:/ { print $NF }')
14341         changelog_clear 0 ||
14342                 error "clear all changelog records for $cl_user failed"
14343         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14344         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14345                 error "Fail to start $SINGLEMDS"
14346         local cur_rec2=$(changelog_users $SINGLEMDS |
14347                          awk '/^current.index:/ { print $NF }')
14348         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14349         [ $cur_rec1 == $cur_rec2 ] ||
14350                 error "current index should be $cur_rec1 not $cur_rec2"
14351
14352         echo "verifying users from this test are deregistered"
14353         changelog_deregister || error "changelog_deregister failed"
14354         changelog_users $SINGLEMDS | grep -q $cl_user &&
14355                 error "User '$cl_user' still in changelog_users"
14356
14357         # lctl get_param -n mdd.*.changelog_users
14358         # current index: 144
14359         # ID    index (idle seconds)
14360         # cl3   144 (2)
14361         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14362                 # this is the normal case where all users were deregistered
14363                 # make sure no new records are added when no users are present
14364                 local last_rec1=$(changelog_users $SINGLEMDS |
14365                                   awk '/^current.index:/ { print $NF }')
14366                 touch $DIR/$tdir/chloe
14367                 local last_rec2=$(changelog_users $SINGLEMDS |
14368                                   awk '/^current.index:/ { print $NF }')
14369                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14370                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14371         else
14372                 # any changelog users must be leftovers from a previous test
14373                 changelog_users $SINGLEMDS
14374                 echo "other changelog users; can't verify off"
14375         fi
14376 }
14377 run_test 160a "changelog sanity"
14378
14379 test_160b() { # LU-3587
14380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14381         remote_mds_nodsh && skip "remote MDS with nodsh"
14382         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14383                 skip "Need MDS version at least 2.2.0"
14384
14385         changelog_register || error "changelog_register failed"
14386         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14387         changelog_users $SINGLEMDS | grep -q $cl_user ||
14388                 error "User '$cl_user' not found in changelog_users"
14389
14390         local longname1=$(str_repeat a 255)
14391         local longname2=$(str_repeat b 255)
14392
14393         cd $DIR
14394         echo "creating very long named file"
14395         touch $longname1 || error "create of '$longname1' failed"
14396         echo "renaming very long named file"
14397         mv $longname1 $longname2
14398
14399         changelog_dump | grep RENME | tail -n 5
14400         rm -f $longname2
14401 }
14402 run_test 160b "Verify that very long rename doesn't crash in changelog"
14403
14404 test_160c() {
14405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14406         remote_mds_nodsh && skip "remote MDS with nodsh"
14407
14408         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14409                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14410                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14411                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14412
14413         local rc=0
14414
14415         # Registration step
14416         changelog_register || error "changelog_register failed"
14417
14418         rm -rf $DIR/$tdir
14419         mkdir -p $DIR/$tdir
14420         $MCREATE $DIR/$tdir/foo_160c
14421         changelog_chmask "-TRUNC"
14422         $TRUNCATE $DIR/$tdir/foo_160c 200
14423         changelog_chmask "+TRUNC"
14424         $TRUNCATE $DIR/$tdir/foo_160c 199
14425         changelog_dump | tail -n 5
14426         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14427         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14428 }
14429 run_test 160c "verify that changelog log catch the truncate event"
14430
14431 test_160d() {
14432         remote_mds_nodsh && skip "remote MDS with nodsh"
14433         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14435         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14436                 skip "Need MDS version at least 2.7.60"
14437
14438         # Registration step
14439         changelog_register || error "changelog_register failed"
14440
14441         mkdir -p $DIR/$tdir/migrate_dir
14442         changelog_clear 0 || error "changelog_clear failed"
14443
14444         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14445         changelog_dump | tail -n 5
14446         local migrates=$(changelog_dump | grep -c "MIGRT")
14447         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14448 }
14449 run_test 160d "verify that changelog log catch the migrate event"
14450
14451 test_160e() {
14452         remote_mds_nodsh && skip "remote MDS with nodsh"
14453
14454         # Create a user
14455         changelog_register || error "changelog_register failed"
14456
14457         # Delete a future user (expect fail)
14458         local MDT0=$(facet_svc $SINGLEMDS)
14459         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14460         local rc=$?
14461
14462         if [ $rc -eq 0 ]; then
14463                 error "Deleted non-existant user cl77"
14464         elif [ $rc -ne 2 ]; then
14465                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14466         fi
14467
14468         # Clear to a bad index (1 billion should be safe)
14469         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14470         rc=$?
14471
14472         if [ $rc -eq 0 ]; then
14473                 error "Successfully cleared to invalid CL index"
14474         elif [ $rc -ne 22 ]; then
14475                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14476         fi
14477 }
14478 run_test 160e "changelog negative testing (should return errors)"
14479
14480 test_160f() {
14481         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14482         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14483                 skip "Need MDS version at least 2.10.56"
14484
14485         local mdts=$(comma_list $(mdts_nodes))
14486
14487         # Create a user
14488         changelog_register || error "first changelog_register failed"
14489         changelog_register || error "second changelog_register failed"
14490         local cl_users
14491         declare -A cl_user1
14492         declare -A cl_user2
14493         local user_rec1
14494         local user_rec2
14495         local i
14496
14497         # generate some changelog records to accumulate on each MDT
14498         # use fnv1a because created files should be evenly distributed
14499         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14500                 error "test_mkdir $tdir failed"
14501         log "$(date +%s): creating first files"
14502         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14503                 error "create $DIR/$tdir/$tfile failed"
14504
14505         # check changelogs have been generated
14506         local start=$SECONDS
14507         local idle_time=$((MDSCOUNT * 5 + 5))
14508         local nbcl=$(changelog_dump | wc -l)
14509         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14510
14511         for param in "changelog_max_idle_time=$idle_time" \
14512                      "changelog_gc=1" \
14513                      "changelog_min_gc_interval=2" \
14514                      "changelog_min_free_cat_entries=3"; do
14515                 local MDT0=$(facet_svc $SINGLEMDS)
14516                 local var="${param%=*}"
14517                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14518
14519                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14520                 do_nodes $mdts $LCTL set_param mdd.*.$param
14521         done
14522
14523         # force cl_user2 to be idle (1st part), but also cancel the
14524         # cl_user1 records so that it is not evicted later in the test.
14525         local sleep1=$((idle_time / 2))
14526         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14527         sleep $sleep1
14528
14529         # simulate changelog catalog almost full
14530         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14531         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14532
14533         for i in $(seq $MDSCOUNT); do
14534                 cl_users=(${CL_USERS[mds$i]})
14535                 cl_user1[mds$i]="${cl_users[0]}"
14536                 cl_user2[mds$i]="${cl_users[1]}"
14537
14538                 [ -n "${cl_user1[mds$i]}" ] ||
14539                         error "mds$i: no user registered"
14540                 [ -n "${cl_user2[mds$i]}" ] ||
14541                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14542
14543                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14544                 [ -n "$user_rec1" ] ||
14545                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14546                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14547                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14548                 [ -n "$user_rec2" ] ||
14549                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14550                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14551                      "$user_rec1 + 2 == $user_rec2"
14552                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14553                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14554                               "$user_rec1 + 2, but is $user_rec2"
14555                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14556                 [ -n "$user_rec2" ] ||
14557                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14558                 [ $user_rec1 == $user_rec2 ] ||
14559                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14560                               "$user_rec1, but is $user_rec2"
14561         done
14562
14563         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14564         local sleep2=$((idle_time - (SECONDS - start) + 1))
14565         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14566         sleep $sleep2
14567
14568         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14569         # cl_user1 should be OK because it recently processed records.
14570         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14571         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14572                 error "create $DIR/$tdir/${tfile}b failed"
14573
14574         # ensure gc thread is done
14575         for i in $(mdts_nodes); do
14576                 wait_update $i \
14577                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14578                         error "$i: GC-thread not done"
14579         done
14580
14581         local first_rec
14582         for i in $(seq $MDSCOUNT); do
14583                 # check cl_user1 still registered
14584                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14585                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14586                 # check cl_user2 unregistered
14587                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14588                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14589
14590                 # check changelogs are present and starting at $user_rec1 + 1
14591                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14592                 [ -n "$user_rec1" ] ||
14593                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14594                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14595                             awk '{ print $1; exit; }')
14596
14597                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14598                 [ $((user_rec1 + 1)) == $first_rec ] ||
14599                         error "mds$i: first index should be $user_rec1 + 1, " \
14600                               "but is $first_rec"
14601         done
14602 }
14603 run_test 160f "changelog garbage collect (timestamped users)"
14604
14605 test_160g() {
14606         remote_mds_nodsh && skip "remote MDS with nodsh"
14607         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14608                 skip "Need MDS version at least 2.10.56"
14609
14610         local mdts=$(comma_list $(mdts_nodes))
14611
14612         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14613         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14614
14615         # Create a user
14616         changelog_register || error "first changelog_register failed"
14617         changelog_register || error "second changelog_register failed"
14618         local cl_users
14619         declare -A cl_user1
14620         declare -A cl_user2
14621         local user_rec1
14622         local user_rec2
14623         local i
14624
14625         # generate some changelog records to accumulate on each MDT
14626         # use fnv1a because created files should be evenly distributed
14627         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14628                 error "mkdir $tdir failed"
14629         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14630                 error "create $DIR/$tdir/$tfile failed"
14631
14632         # check changelogs have been generated
14633         local nbcl=$(changelog_dump | wc -l)
14634         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14635
14636         # reduce the max_idle_indexes value to make sure we exceed it
14637         max_ndx=$((nbcl / 2 - 1))
14638
14639         for param in "changelog_max_idle_indexes=$max_ndx" \
14640                      "changelog_gc=1" \
14641                      "changelog_min_gc_interval=2" \
14642                      "changelog_min_free_cat_entries=3"; do
14643                 local MDT0=$(facet_svc $SINGLEMDS)
14644                 local var="${param%=*}"
14645                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14646
14647                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14648                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14649                         error "unable to set mdd.*.$param"
14650         done
14651
14652         # simulate changelog catalog almost full
14653         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14654         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14655
14656         for i in $(seq $MDSCOUNT); do
14657                 cl_users=(${CL_USERS[mds$i]})
14658                 cl_user1[mds$i]="${cl_users[0]}"
14659                 cl_user2[mds$i]="${cl_users[1]}"
14660
14661                 [ -n "${cl_user1[mds$i]}" ] ||
14662                         error "mds$i: no user registered"
14663                 [ -n "${cl_user2[mds$i]}" ] ||
14664                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14665
14666                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14667                 [ -n "$user_rec1" ] ||
14668                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14669                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14670                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14671                 [ -n "$user_rec2" ] ||
14672                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14673                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14674                      "$user_rec1 + 2 == $user_rec2"
14675                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14676                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14677                               "$user_rec1 + 2, but is $user_rec2"
14678                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14679                 [ -n "$user_rec2" ] ||
14680                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14681                 [ $user_rec1 == $user_rec2 ] ||
14682                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14683                               "$user_rec1, but is $user_rec2"
14684         done
14685
14686         # ensure we are past the previous changelog_min_gc_interval set above
14687         sleep 2
14688
14689         # generate one more changelog to trigger fail_loc
14690         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14691                 error "create $DIR/$tdir/${tfile}bis failed"
14692
14693         # ensure gc thread is done
14694         for i in $(mdts_nodes); do
14695                 wait_update $i \
14696                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14697                         error "$i: GC-thread not done"
14698         done
14699
14700         local first_rec
14701         for i in $(seq $MDSCOUNT); do
14702                 # check cl_user1 still registered
14703                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14704                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14705                 # check cl_user2 unregistered
14706                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14707                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14708
14709                 # check changelogs are present and starting at $user_rec1 + 1
14710                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14711                 [ -n "$user_rec1" ] ||
14712                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14713                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14714                             awk '{ print $1; exit; }')
14715
14716                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14717                 [ $((user_rec1 + 1)) == $first_rec ] ||
14718                         error "mds$i: first index should be $user_rec1 + 1, " \
14719                               "but is $first_rec"
14720         done
14721 }
14722 run_test 160g "changelog garbage collect (old users)"
14723
14724 test_160h() {
14725         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14726         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14727                 skip "Need MDS version at least 2.10.56"
14728
14729         local mdts=$(comma_list $(mdts_nodes))
14730
14731         # Create a user
14732         changelog_register || error "first changelog_register failed"
14733         changelog_register || error "second changelog_register failed"
14734         local cl_users
14735         declare -A cl_user1
14736         declare -A cl_user2
14737         local user_rec1
14738         local user_rec2
14739         local i
14740
14741         # generate some changelog records to accumulate on each MDT
14742         # use fnv1a because created files should be evenly distributed
14743         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14744                 error "test_mkdir $tdir failed"
14745         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14746                 error "create $DIR/$tdir/$tfile failed"
14747
14748         # check changelogs have been generated
14749         local nbcl=$(changelog_dump | wc -l)
14750         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14751
14752         for param in "changelog_max_idle_time=10" \
14753                      "changelog_gc=1" \
14754                      "changelog_min_gc_interval=2"; do
14755                 local MDT0=$(facet_svc $SINGLEMDS)
14756                 local var="${param%=*}"
14757                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14758
14759                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14760                 do_nodes $mdts $LCTL set_param mdd.*.$param
14761         done
14762
14763         # force cl_user2 to be idle (1st part)
14764         sleep 9
14765
14766         for i in $(seq $MDSCOUNT); do
14767                 cl_users=(${CL_USERS[mds$i]})
14768                 cl_user1[mds$i]="${cl_users[0]}"
14769                 cl_user2[mds$i]="${cl_users[1]}"
14770
14771                 [ -n "${cl_user1[mds$i]}" ] ||
14772                         error "mds$i: no user registered"
14773                 [ -n "${cl_user2[mds$i]}" ] ||
14774                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14775
14776                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14777                 [ -n "$user_rec1" ] ||
14778                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14779                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14780                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14781                 [ -n "$user_rec2" ] ||
14782                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14783                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14784                      "$user_rec1 + 2 == $user_rec2"
14785                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14786                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14787                               "$user_rec1 + 2, but is $user_rec2"
14788                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14789                 [ -n "$user_rec2" ] ||
14790                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14791                 [ $user_rec1 == $user_rec2 ] ||
14792                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14793                               "$user_rec1, but is $user_rec2"
14794         done
14795
14796         # force cl_user2 to be idle (2nd part) and to reach
14797         # changelog_max_idle_time
14798         sleep 2
14799
14800         # force each GC-thread start and block then
14801         # one per MDT/MDD, set fail_val accordingly
14802         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14803         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14804
14805         # generate more changelogs to trigger fail_loc
14806         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14807                 error "create $DIR/$tdir/${tfile}bis failed"
14808
14809         # stop MDT to stop GC-thread, should be done in back-ground as it will
14810         # block waiting for the thread to be released and exit
14811         declare -A stop_pids
14812         for i in $(seq $MDSCOUNT); do
14813                 stop mds$i &
14814                 stop_pids[mds$i]=$!
14815         done
14816
14817         for i in $(mdts_nodes); do
14818                 local facet
14819                 local nb=0
14820                 local facets=$(facets_up_on_host $i)
14821
14822                 for facet in ${facets//,/ }; do
14823                         if [[ $facet == mds* ]]; then
14824                                 nb=$((nb + 1))
14825                         fi
14826                 done
14827                 # ensure each MDS's gc threads are still present and all in "R"
14828                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14829                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14830                         error "$i: expected $nb GC-thread"
14831                 wait_update $i \
14832                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14833                         "R" 20 ||
14834                         error "$i: GC-thread not found in R-state"
14835                 # check umounts of each MDT on MDS have reached kthread_stop()
14836                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14837                         error "$i: expected $nb umount"
14838                 wait_update $i \
14839                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14840                         error "$i: umount not found in D-state"
14841         done
14842
14843         # release all GC-threads
14844         do_nodes $mdts $LCTL set_param fail_loc=0
14845
14846         # wait for MDT stop to complete
14847         for i in $(seq $MDSCOUNT); do
14848                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14849         done
14850
14851         # XXX
14852         # may try to check if any orphan changelog records are present
14853         # via ldiskfs/zfs and llog_reader...
14854
14855         # re-start/mount MDTs
14856         for i in $(seq $MDSCOUNT); do
14857                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14858                         error "Fail to start mds$i"
14859         done
14860
14861         local first_rec
14862         for i in $(seq $MDSCOUNT); do
14863                 # check cl_user1 still registered
14864                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14865                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14866                 # check cl_user2 unregistered
14867                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14868                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14869
14870                 # check changelogs are present and starting at $user_rec1 + 1
14871                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14872                 [ -n "$user_rec1" ] ||
14873                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14874                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14875                             awk '{ print $1; exit; }')
14876
14877                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14878                 [ $((user_rec1 + 1)) == $first_rec ] ||
14879                         error "mds$i: first index should be $user_rec1 + 1, " \
14880                               "but is $first_rec"
14881         done
14882 }
14883 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14884               "during mount"
14885
14886 test_160i() {
14887
14888         local mdts=$(comma_list $(mdts_nodes))
14889
14890         changelog_register || error "first changelog_register failed"
14891
14892         # generate some changelog records to accumulate on each MDT
14893         # use fnv1a because created files should be evenly distributed
14894         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14895                 error "mkdir $tdir failed"
14896         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14897                 error "create $DIR/$tdir/$tfile failed"
14898
14899         # check changelogs have been generated
14900         local nbcl=$(changelog_dump | wc -l)
14901         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14902
14903         # simulate race between register and unregister
14904         # XXX as fail_loc is set per-MDS, with DNE configs the race
14905         # simulation will only occur for one MDT per MDS and for the
14906         # others the normal race scenario will take place
14907         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14908         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14909         do_nodes $mdts $LCTL set_param fail_val=1
14910
14911         # unregister 1st user
14912         changelog_deregister &
14913         local pid1=$!
14914         # wait some time for deregister work to reach race rdv
14915         sleep 2
14916         # register 2nd user
14917         changelog_register || error "2nd user register failed"
14918
14919         wait $pid1 || error "1st user deregister failed"
14920
14921         local i
14922         local last_rec
14923         declare -A LAST_REC
14924         for i in $(seq $MDSCOUNT); do
14925                 if changelog_users mds$i | grep "^cl"; then
14926                         # make sure new records are added with one user present
14927                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14928                                           awk '/^current.index:/ { print $NF }')
14929                 else
14930                         error "mds$i has no user registered"
14931                 fi
14932         done
14933
14934         # generate more changelog records to accumulate on each MDT
14935         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14936                 error "create $DIR/$tdir/${tfile}bis failed"
14937
14938         for i in $(seq $MDSCOUNT); do
14939                 last_rec=$(changelog_users $SINGLEMDS |
14940                            awk '/^current.index:/ { print $NF }')
14941                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14942                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14943                         error "changelogs are off on mds$i"
14944         done
14945 }
14946 run_test 160i "changelog user register/unregister race"
14947
14948 test_160j() {
14949         remote_mds_nodsh && skip "remote MDS with nodsh"
14950         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14951                 skip "Need MDS version at least 2.12.56"
14952
14953         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14954         stack_trap "umount $MOUNT2" EXIT
14955
14956         changelog_register || error "first changelog_register failed"
14957         stack_trap "changelog_deregister" EXIT
14958
14959         # generate some changelog
14960         # use fnv1a because created files should be evenly distributed
14961         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14962                 error "mkdir $tdir failed"
14963         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14964                 error "create $DIR/$tdir/${tfile}bis failed"
14965
14966         # open the changelog device
14967         exec 3>/dev/changelog-$FSNAME-MDT0000
14968         stack_trap "exec 3>&-" EXIT
14969         exec 4</dev/changelog-$FSNAME-MDT0000
14970         stack_trap "exec 4<&-" EXIT
14971
14972         # umount the first lustre mount
14973         umount $MOUNT
14974         stack_trap "mount_client $MOUNT" EXIT
14975
14976         # read changelog
14977         cat <&4 >/dev/null || error "read changelog failed"
14978
14979         # clear changelog
14980         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14981         changelog_users $SINGLEMDS | grep -q $cl_user ||
14982                 error "User $cl_user not found in changelog_users"
14983
14984         printf 'clear:'$cl_user':0' >&3
14985 }
14986 run_test 160j "client can be umounted  while its chanangelog is being used"
14987
14988 test_160k() {
14989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14990         remote_mds_nodsh && skip "remote MDS with nodsh"
14991
14992         mkdir -p $DIR/$tdir/1/1
14993
14994         changelog_register || error "changelog_register failed"
14995         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14996
14997         changelog_users $SINGLEMDS | grep -q $cl_user ||
14998                 error "User '$cl_user' not found in changelog_users"
14999 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15000         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15001         rmdir $DIR/$tdir/1/1 & sleep 1
15002         mkdir $DIR/$tdir/2
15003         touch $DIR/$tdir/2/2
15004         rm -rf $DIR/$tdir/2
15005
15006         wait
15007         sleep 4
15008
15009         changelog_dump | grep rmdir || error "rmdir not recorded"
15010
15011         rm -rf $DIR/$tdir
15012         changelog_deregister
15013 }
15014 run_test 160k "Verify that changelog records are not lost"
15015
15016 # Verifies that a file passed as a parameter has recently had an operation
15017 # performed on it that has generated an MTIME changelog which contains the
15018 # correct parent FID. As files might reside on a different MDT from the
15019 # parent directory in DNE configurations, the FIDs are translated to paths
15020 # before being compared, which should be identical
15021 compare_mtime_changelog() {
15022         local file="${1}"
15023         local mdtidx
15024         local mtime
15025         local cl_fid
15026         local pdir
15027         local dir
15028
15029         mdtidx=$($LFS getstripe --mdt-index $file)
15030         mdtidx=$(printf "%04x" $mdtidx)
15031
15032         # Obtain the parent FID from the MTIME changelog
15033         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15034         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15035
15036         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15037         [ -z "$cl_fid" ] && error "parent FID not present"
15038
15039         # Verify that the path for the parent FID is the same as the path for
15040         # the test directory
15041         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15042
15043         dir=$(dirname $1)
15044
15045         [[ "${pdir%/}" == "$dir" ]] ||
15046                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15047 }
15048
15049 test_160l() {
15050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15051
15052         remote_mds_nodsh && skip "remote MDS with nodsh"
15053         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15054                 skip "Need MDS version at least 2.13.55"
15055
15056         local cl_user
15057
15058         changelog_register || error "changelog_register failed"
15059         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15060
15061         changelog_users $SINGLEMDS | grep -q $cl_user ||
15062                 error "User '$cl_user' not found in changelog_users"
15063
15064         # Clear some types so that MTIME changelogs are generated
15065         changelog_chmask "-CREAT"
15066         changelog_chmask "-CLOSE"
15067
15068         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15069
15070         # Test CL_MTIME during setattr
15071         touch $DIR/$tdir/$tfile
15072         compare_mtime_changelog $DIR/$tdir/$tfile
15073
15074         # Test CL_MTIME during close
15075         dd if=/dev/urandom of=$DIR/$tdir/${tfile}_2 bs=1M count=64 ||
15076                 error "cannot create file $DIR/$tdir/${tfile}_2"
15077         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15078 }
15079 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15080
15081 test_161a() {
15082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15083
15084         test_mkdir -c1 $DIR/$tdir
15085         cp /etc/hosts $DIR/$tdir/$tfile
15086         test_mkdir -c1 $DIR/$tdir/foo1
15087         test_mkdir -c1 $DIR/$tdir/foo2
15088         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15089         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15090         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15091         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15092         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15093         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15094                 $LFS fid2path $DIR $FID
15095                 error "bad link ea"
15096         fi
15097         # middle
15098         rm $DIR/$tdir/foo2/zachary
15099         # last
15100         rm $DIR/$tdir/foo2/thor
15101         # first
15102         rm $DIR/$tdir/$tfile
15103         # rename
15104         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15105         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15106                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15107         rm $DIR/$tdir/foo2/maggie
15108
15109         # overflow the EA
15110         local longname=$tfile.avg_len_is_thirty_two_
15111         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15112                 error_noexit 'failed to unlink many hardlinks'" EXIT
15113         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15114                 error "failed to hardlink many files"
15115         links=$($LFS fid2path $DIR $FID | wc -l)
15116         echo -n "${links}/1000 links in link EA"
15117         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15118 }
15119 run_test 161a "link ea sanity"
15120
15121 test_161b() {
15122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15123         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15124
15125         local MDTIDX=1
15126         local remote_dir=$DIR/$tdir/remote_dir
15127
15128         mkdir -p $DIR/$tdir
15129         $LFS mkdir -i $MDTIDX $remote_dir ||
15130                 error "create remote directory failed"
15131
15132         cp /etc/hosts $remote_dir/$tfile
15133         mkdir -p $remote_dir/foo1
15134         mkdir -p $remote_dir/foo2
15135         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15136         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15137         ln $remote_dir/$tfile $remote_dir/foo1/luna
15138         ln $remote_dir/$tfile $remote_dir/foo2/thor
15139
15140         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15141                      tr -d ']')
15142         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15143                 $LFS fid2path $DIR $FID
15144                 error "bad link ea"
15145         fi
15146         # middle
15147         rm $remote_dir/foo2/zachary
15148         # last
15149         rm $remote_dir/foo2/thor
15150         # first
15151         rm $remote_dir/$tfile
15152         # rename
15153         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15154         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15155         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15156                 $LFS fid2path $DIR $FID
15157                 error "bad link rename"
15158         fi
15159         rm $remote_dir/foo2/maggie
15160
15161         # overflow the EA
15162         local longname=filename_avg_len_is_thirty_two_
15163         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15164                 error "failed to hardlink many files"
15165         links=$($LFS fid2path $DIR $FID | wc -l)
15166         echo -n "${links}/1000 links in link EA"
15167         [[ ${links} -gt 60 ]] ||
15168                 error "expected at least 60 links in link EA"
15169         unlinkmany $remote_dir/foo2/$longname 1000 ||
15170         error "failed to unlink many hardlinks"
15171 }
15172 run_test 161b "link ea sanity under remote directory"
15173
15174 test_161c() {
15175         remote_mds_nodsh && skip "remote MDS with nodsh"
15176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15177         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15178                 skip "Need MDS version at least 2.1.5"
15179
15180         # define CLF_RENAME_LAST 0x0001
15181         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15182         changelog_register || error "changelog_register failed"
15183
15184         rm -rf $DIR/$tdir
15185         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15186         touch $DIR/$tdir/foo_161c
15187         touch $DIR/$tdir/bar_161c
15188         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15189         changelog_dump | grep RENME | tail -n 5
15190         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15191         changelog_clear 0 || error "changelog_clear failed"
15192         if [ x$flags != "x0x1" ]; then
15193                 error "flag $flags is not 0x1"
15194         fi
15195
15196         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15197         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15198         touch $DIR/$tdir/foo_161c
15199         touch $DIR/$tdir/bar_161c
15200         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15201         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15202         changelog_dump | grep RENME | tail -n 5
15203         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15204         changelog_clear 0 || error "changelog_clear failed"
15205         if [ x$flags != "x0x0" ]; then
15206                 error "flag $flags is not 0x0"
15207         fi
15208         echo "rename overwrite a target having nlink > 1," \
15209                 "changelog record has flags of $flags"
15210
15211         # rename doesn't overwrite a target (changelog flag 0x0)
15212         touch $DIR/$tdir/foo_161c
15213         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15214         changelog_dump | grep RENME | tail -n 5
15215         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15216         changelog_clear 0 || error "changelog_clear failed"
15217         if [ x$flags != "x0x0" ]; then
15218                 error "flag $flags is not 0x0"
15219         fi
15220         echo "rename doesn't overwrite a target," \
15221                 "changelog record has flags of $flags"
15222
15223         # define CLF_UNLINK_LAST 0x0001
15224         # unlink a file having nlink = 1 (changelog flag 0x1)
15225         rm -f $DIR/$tdir/foo2_161c
15226         changelog_dump | grep UNLNK | tail -n 5
15227         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15228         changelog_clear 0 || error "changelog_clear failed"
15229         if [ x$flags != "x0x1" ]; then
15230                 error "flag $flags is not 0x1"
15231         fi
15232         echo "unlink a file having nlink = 1," \
15233                 "changelog record has flags of $flags"
15234
15235         # unlink a file having nlink > 1 (changelog flag 0x0)
15236         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15237         rm -f $DIR/$tdir/foobar_161c
15238         changelog_dump | grep UNLNK | tail -n 5
15239         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15240         changelog_clear 0 || error "changelog_clear failed"
15241         if [ x$flags != "x0x0" ]; then
15242                 error "flag $flags is not 0x0"
15243         fi
15244         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15245 }
15246 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15247
15248 test_161d() {
15249         remote_mds_nodsh && skip "remote MDS with nodsh"
15250         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15251
15252         local pid
15253         local fid
15254
15255         changelog_register || error "changelog_register failed"
15256
15257         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15258         # interfer with $MOUNT/.lustre/fid/ access
15259         mkdir $DIR/$tdir
15260         [[ $? -eq 0 ]] || error "mkdir failed"
15261
15262         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15263         $LCTL set_param fail_loc=0x8000140c
15264         # 5s pause
15265         $LCTL set_param fail_val=5
15266
15267         # create file
15268         echo foofoo > $DIR/$tdir/$tfile &
15269         pid=$!
15270
15271         # wait for create to be delayed
15272         sleep 2
15273
15274         ps -p $pid
15275         [[ $? -eq 0 ]] || error "create should be blocked"
15276
15277         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15278         stack_trap "rm -f $tempfile"
15279         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15280         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15281         # some delay may occur during ChangeLog publishing and file read just
15282         # above, that could allow file write to happen finally
15283         [[ -s $tempfile ]] && echo "file should be empty"
15284
15285         $LCTL set_param fail_loc=0
15286
15287         wait $pid
15288         [[ $? -eq 0 ]] || error "create failed"
15289 }
15290 run_test 161d "create with concurrent .lustre/fid access"
15291
15292 check_path() {
15293         local expected="$1"
15294         shift
15295         local fid="$2"
15296
15297         local path
15298         path=$($LFS fid2path "$@")
15299         local rc=$?
15300
15301         if [ $rc -ne 0 ]; then
15302                 error "path looked up of '$expected' failed: rc=$rc"
15303         elif [ "$path" != "$expected" ]; then
15304                 error "path looked up '$path' instead of '$expected'"
15305         else
15306                 echo "FID '$fid' resolves to path '$path' as expected"
15307         fi
15308 }
15309
15310 test_162a() { # was test_162
15311         test_mkdir -p -c1 $DIR/$tdir/d2
15312         touch $DIR/$tdir/d2/$tfile
15313         touch $DIR/$tdir/d2/x1
15314         touch $DIR/$tdir/d2/x2
15315         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15316         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15317         # regular file
15318         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15319         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15320
15321         # softlink
15322         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15323         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15324         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15325
15326         # softlink to wrong file
15327         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15328         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15329         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15330
15331         # hardlink
15332         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15333         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15334         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15335         # fid2path dir/fsname should both work
15336         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15337         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15338
15339         # hardlink count: check that there are 2 links
15340         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15341         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15342
15343         # hardlink indexing: remove the first link
15344         rm $DIR/$tdir/d2/p/q/r/hlink
15345         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15346 }
15347 run_test 162a "path lookup sanity"
15348
15349 test_162b() {
15350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15351         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15352
15353         mkdir $DIR/$tdir
15354         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15355                                 error "create striped dir failed"
15356
15357         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15358                                         tail -n 1 | awk '{print $2}')
15359         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15360
15361         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15362         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15363
15364         # regular file
15365         for ((i=0;i<5;i++)); do
15366                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15367                         error "get fid for f$i failed"
15368                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15369
15370                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15371                         error "get fid for d$i failed"
15372                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15373         done
15374
15375         return 0
15376 }
15377 run_test 162b "striped directory path lookup sanity"
15378
15379 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15380 test_162c() {
15381         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15382                 skip "Need MDS version at least 2.7.51"
15383
15384         local lpath=$tdir.local
15385         local rpath=$tdir.remote
15386
15387         test_mkdir $DIR/$lpath
15388         test_mkdir $DIR/$rpath
15389
15390         for ((i = 0; i <= 101; i++)); do
15391                 lpath="$lpath/$i"
15392                 mkdir $DIR/$lpath
15393                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15394                         error "get fid for local directory $DIR/$lpath failed"
15395                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15396
15397                 rpath="$rpath/$i"
15398                 test_mkdir $DIR/$rpath
15399                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15400                         error "get fid for remote directory $DIR/$rpath failed"
15401                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15402         done
15403
15404         return 0
15405 }
15406 run_test 162c "fid2path works with paths 100 or more directories deep"
15407
15408 oalr_event_count() {
15409         local event="${1}"
15410         local trace="${2}"
15411
15412         awk -v name="${FSNAME}-OST0000" \
15413             -v event="${event}" \
15414             '$1 == "TRACE" && $2 == event && $3 == name' \
15415             "${trace}" |
15416         wc -l
15417 }
15418
15419 oalr_expect_event_count() {
15420         local event="${1}"
15421         local trace="${2}"
15422         local expect="${3}"
15423         local count
15424
15425         count=$(oalr_event_count "${event}" "${trace}")
15426         if ((count == expect)); then
15427                 return 0
15428         fi
15429
15430         error_noexit "${event} event count was '${count}', expected ${expect}"
15431         cat "${trace}" >&2
15432         exit 1
15433 }
15434
15435 cleanup_165() {
15436         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15437         stop ost1
15438         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15439 }
15440
15441 setup_165() {
15442         sync # Flush previous IOs so we can count log entries.
15443         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15444         stack_trap cleanup_165 EXIT
15445 }
15446
15447 test_165a() {
15448         local trace="/tmp/${tfile}.trace"
15449         local rc
15450         local count
15451
15452         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15453         setup_165
15454         sleep 5
15455
15456         do_facet ost1 ofd_access_log_reader --list
15457         stop ost1
15458
15459         do_facet ost1 killall -TERM ofd_access_log_reader
15460         wait
15461         rc=$?
15462
15463         if ((rc != 0)); then
15464                 error "ofd_access_log_reader exited with rc = '${rc}'"
15465         fi
15466
15467         # Parse trace file for discovery events:
15468         oalr_expect_event_count alr_log_add "${trace}" 1
15469         oalr_expect_event_count alr_log_eof "${trace}" 1
15470         oalr_expect_event_count alr_log_free "${trace}" 1
15471 }
15472 run_test 165a "ofd access log discovery"
15473
15474 test_165b() {
15475         local trace="/tmp/${tfile}.trace"
15476         local file="${DIR}/${tfile}"
15477         local pfid1
15478         local pfid2
15479         local -a entry
15480         local rc
15481         local count
15482         local size
15483         local flags
15484
15485         setup_165
15486
15487         lfs setstripe -c 1 -i 0 "${file}"
15488         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15489         do_facet ost1 ofd_access_log_reader --list
15490
15491         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15492         sleep 5
15493         do_facet ost1 killall -TERM ofd_access_log_reader
15494         wait
15495         rc=$?
15496
15497         if ((rc != 0)); then
15498                 error "ofd_access_log_reader exited with rc = '${rc}'"
15499         fi
15500
15501         oalr_expect_event_count alr_log_entry "${trace}" 1
15502
15503         pfid1=$($LFS path2fid "${file}")
15504
15505         # 1     2             3   4    5     6   7    8    9     10
15506         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15507         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15508
15509         echo "entry = '${entry[*]}'" >&2
15510
15511         pfid2=${entry[4]}
15512         if [[ "${pfid1}" != "${pfid2}" ]]; then
15513                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15514         fi
15515
15516         size=${entry[8]}
15517         if ((size != 1048576)); then
15518                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15519         fi
15520
15521         flags=${entry[10]}
15522         if [[ "${flags}" != "w" ]]; then
15523                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15524         fi
15525
15526         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15527         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c || error "cannot read '${file}'"
15528         sleep 5
15529         do_facet ost1 killall -TERM ofd_access_log_reader
15530         wait
15531         rc=$?
15532
15533         if ((rc != 0)); then
15534                 error "ofd_access_log_reader exited with rc = '${rc}'"
15535         fi
15536
15537         oalr_expect_event_count alr_log_entry "${trace}" 1
15538
15539         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15540         echo "entry = '${entry[*]}'" >&2
15541
15542         pfid2=${entry[4]}
15543         if [[ "${pfid1}" != "${pfid2}" ]]; then
15544                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15545         fi
15546
15547         size=${entry[8]}
15548         if ((size != 524288)); then
15549                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15550         fi
15551
15552         flags=${entry[10]}
15553         if [[ "${flags}" != "r" ]]; then
15554                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15555         fi
15556 }
15557 run_test 165b "ofd access log entries are produced and consumed"
15558
15559 test_165c() {
15560         local file="${DIR}/${tdir}/${tfile}"
15561         test_mkdir "${DIR}/${tdir}"
15562
15563         setup_165
15564
15565         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15566
15567         # 4096 / 64 = 64. Create twice as many entries.
15568         for ((i = 0; i < 128; i++)); do
15569                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c || error "cannot create file"
15570         done
15571
15572         sync
15573         do_facet ost1 ofd_access_log_reader --list
15574         unlinkmany  "${file}-%d" 128
15575 }
15576 run_test 165c "full ofd access logs do not block IOs"
15577
15578 oal_peek_entry_count() {
15579         do_facet ost1 ofd_access_log_reader --list | awk '$1 == "_entry_count:" { print $2; }'
15580 }
15581
15582 oal_expect_entry_count() {
15583         local entry_count=$(oal_peek_entry_count)
15584         local expect="$1"
15585
15586         if ((entry_count == expect)); then
15587                 return 0
15588         fi
15589
15590         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15591         do_facet ost1 ofd_access_log_reader --list >&2
15592         exit 1
15593 }
15594
15595 test_165d() {
15596         local trace="/tmp/${tfile}.trace"
15597         local file="${DIR}/${tdir}/${tfile}"
15598         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15599         local entry_count
15600         test_mkdir "${DIR}/${tdir}"
15601
15602         setup_165
15603         lfs setstripe -c 1 -i 0 "${file}"
15604
15605         do_facet ost1 lctl set_param "${param}=rw"
15606         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15607         oal_expect_entry_count 1
15608
15609         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15610         oal_expect_entry_count 2
15611
15612         do_facet ost1 lctl set_param "${param}=r"
15613         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15614         oal_expect_entry_count 2
15615
15616         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15617         oal_expect_entry_count 3
15618
15619         do_facet ost1 lctl set_param "${param}=w"
15620         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15621         oal_expect_entry_count 4
15622
15623         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15624         oal_expect_entry_count 4
15625
15626         do_facet ost1 lctl set_param "${param}=0"
15627         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15628         oal_expect_entry_count 4
15629
15630         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15631         oal_expect_entry_count 4
15632 }
15633 run_test 165d "ofd_access_log mask works"
15634
15635 test_169() {
15636         # do directio so as not to populate the page cache
15637         log "creating a 10 Mb file"
15638         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15639         log "starting reads"
15640         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15641         log "truncating the file"
15642         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15643         log "killing dd"
15644         kill %+ || true # reads might have finished
15645         echo "wait until dd is finished"
15646         wait
15647         log "removing the temporary file"
15648         rm -rf $DIR/$tfile || error "tmp file removal failed"
15649 }
15650 run_test 169 "parallel read and truncate should not deadlock"
15651
15652 test_170() {
15653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15654
15655         $LCTL clear     # bug 18514
15656         $LCTL debug_daemon start $TMP/${tfile}_log_good
15657         touch $DIR/$tfile
15658         $LCTL debug_daemon stop
15659         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15660                 error "sed failed to read log_good"
15661
15662         $LCTL debug_daemon start $TMP/${tfile}_log_good
15663         rm -rf $DIR/$tfile
15664         $LCTL debug_daemon stop
15665
15666         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15667                error "lctl df log_bad failed"
15668
15669         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15670         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15671
15672         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15673         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15674
15675         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15676                 error "bad_line good_line1 good_line2 are empty"
15677
15678         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15679         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15680         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15681
15682         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15683         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15684         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15685
15686         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15687                 error "bad_line_new good_line_new are empty"
15688
15689         local expected_good=$((good_line1 + good_line2*2))
15690
15691         rm -f $TMP/${tfile}*
15692         # LU-231, short malformed line may not be counted into bad lines
15693         if [ $bad_line -ne $bad_line_new ] &&
15694                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15695                 error "expected $bad_line bad lines, but got $bad_line_new"
15696                 return 1
15697         fi
15698
15699         if [ $expected_good -ne $good_line_new ]; then
15700                 error "expected $expected_good good lines, but got $good_line_new"
15701                 return 2
15702         fi
15703         true
15704 }
15705 run_test 170 "test lctl df to handle corrupted log ====================="
15706
15707 test_171() { # bug20592
15708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15709
15710         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15711         $LCTL set_param fail_loc=0x50e
15712         $LCTL set_param fail_val=3000
15713         multiop_bg_pause $DIR/$tfile O_s || true
15714         local MULTIPID=$!
15715         kill -USR1 $MULTIPID
15716         # cause log dump
15717         sleep 3
15718         wait $MULTIPID
15719         if dmesg | grep "recursive fault"; then
15720                 error "caught a recursive fault"
15721         fi
15722         $LCTL set_param fail_loc=0
15723         true
15724 }
15725 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15726
15727 # it would be good to share it with obdfilter-survey/iokit-libecho code
15728 setup_obdecho_osc () {
15729         local rc=0
15730         local ost_nid=$1
15731         local obdfilter_name=$2
15732         echo "Creating new osc for $obdfilter_name on $ost_nid"
15733         # make sure we can find loopback nid
15734         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15735
15736         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15737                            ${obdfilter_name}_osc_UUID || rc=2; }
15738         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15739                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15740         return $rc
15741 }
15742
15743 cleanup_obdecho_osc () {
15744         local obdfilter_name=$1
15745         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15746         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15747         return 0
15748 }
15749
15750 obdecho_test() {
15751         local OBD=$1
15752         local node=$2
15753         local pages=${3:-64}
15754         local rc=0
15755         local id
15756
15757         local count=10
15758         local obd_size=$(get_obd_size $node $OBD)
15759         local page_size=$(get_page_size $node)
15760         if [[ -n "$obd_size" ]]; then
15761                 local new_count=$((obd_size / (pages * page_size / 1024)))
15762                 [[ $new_count -ge $count ]] || count=$new_count
15763         fi
15764
15765         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15766         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15767                            rc=2; }
15768         if [ $rc -eq 0 ]; then
15769             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15770             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15771         fi
15772         echo "New object id is $id"
15773         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15774                            rc=4; }
15775         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15776                            "test_brw $count w v $pages $id" || rc=4; }
15777         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15778                            rc=4; }
15779         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15780                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15781         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15782                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15783         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15784         return $rc
15785 }
15786
15787 test_180a() {
15788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15789
15790         if ! [ -d /sys/fs/lustre/echo_client ] &&
15791            ! module_loaded obdecho; then
15792                 load_module obdecho/obdecho &&
15793                         stack_trap "rmmod obdecho" EXIT ||
15794                         error "unable to load obdecho on client"
15795         fi
15796
15797         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15798         local host=$($LCTL get_param -n osc.$osc.import |
15799                      awk '/current_connection:/ { print $2 }' )
15800         local target=$($LCTL get_param -n osc.$osc.import |
15801                        awk '/target:/ { print $2 }' )
15802         target=${target%_UUID}
15803
15804         if [ -n "$target" ]; then
15805                 setup_obdecho_osc $host $target &&
15806                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15807                         { error "obdecho setup failed with $?"; return; }
15808
15809                 obdecho_test ${target}_osc client ||
15810                         error "obdecho_test failed on ${target}_osc"
15811         else
15812                 $LCTL get_param osc.$osc.import
15813                 error "there is no osc.$osc.import target"
15814         fi
15815 }
15816 run_test 180a "test obdecho on osc"
15817
15818 test_180b() {
15819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15820         remote_ost_nodsh && skip "remote OST with nodsh"
15821
15822         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15823                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15824                 error "failed to load module obdecho"
15825
15826         local target=$(do_facet ost1 $LCTL dl |
15827                        awk '/obdfilter/ { print $4; exit; }')
15828
15829         if [ -n "$target" ]; then
15830                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15831         else
15832                 do_facet ost1 $LCTL dl
15833                 error "there is no obdfilter target on ost1"
15834         fi
15835 }
15836 run_test 180b "test obdecho directly on obdfilter"
15837
15838 test_180c() { # LU-2598
15839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15840         remote_ost_nodsh && skip "remote OST with nodsh"
15841         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15842                 skip "Need MDS version at least 2.4.0"
15843
15844         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15845                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15846                 error "failed to load module obdecho"
15847
15848         local target=$(do_facet ost1 $LCTL dl |
15849                        awk '/obdfilter/ { print $4; exit; }')
15850
15851         if [ -n "$target" ]; then
15852                 local pages=16384 # 64MB bulk I/O RPC size
15853
15854                 obdecho_test "$target" ost1 "$pages" ||
15855                         error "obdecho_test with pages=$pages failed with $?"
15856         else
15857                 do_facet ost1 $LCTL dl
15858                 error "there is no obdfilter target on ost1"
15859         fi
15860 }
15861 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15862
15863 test_181() { # bug 22177
15864         test_mkdir $DIR/$tdir
15865         # create enough files to index the directory
15866         createmany -o $DIR/$tdir/foobar 4000
15867         # print attributes for debug purpose
15868         lsattr -d .
15869         # open dir
15870         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15871         MULTIPID=$!
15872         # remove the files & current working dir
15873         unlinkmany $DIR/$tdir/foobar 4000
15874         rmdir $DIR/$tdir
15875         kill -USR1 $MULTIPID
15876         wait $MULTIPID
15877         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15878         return 0
15879 }
15880 run_test 181 "Test open-unlinked dir ========================"
15881
15882 test_182() {
15883         local fcount=1000
15884         local tcount=10
15885
15886         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15887
15888         $LCTL set_param mdc.*.rpc_stats=clear
15889
15890         for (( i = 0; i < $tcount; i++ )) ; do
15891                 mkdir $DIR/$tdir/$i
15892         done
15893
15894         for (( i = 0; i < $tcount; i++ )) ; do
15895                 createmany -o $DIR/$tdir/$i/f- $fcount &
15896         done
15897         wait
15898
15899         for (( i = 0; i < $tcount; i++ )) ; do
15900                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15901         done
15902         wait
15903
15904         $LCTL get_param mdc.*.rpc_stats
15905
15906         rm -rf $DIR/$tdir
15907 }
15908 run_test 182 "Test parallel modify metadata operations ================"
15909
15910 test_183() { # LU-2275
15911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15912         remote_mds_nodsh && skip "remote MDS with nodsh"
15913         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15914                 skip "Need MDS version at least 2.3.56"
15915
15916         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15917         echo aaa > $DIR/$tdir/$tfile
15918
15919 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
15920         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
15921
15922         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
15923         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
15924
15925         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15926
15927         # Flush negative dentry cache
15928         touch $DIR/$tdir/$tfile
15929
15930         # We are not checking for any leaked references here, they'll
15931         # become evident next time we do cleanup with module unload.
15932         rm -rf $DIR/$tdir
15933 }
15934 run_test 183 "No crash or request leak in case of strange dispositions ========"
15935
15936 # test suite 184 is for LU-2016, LU-2017
15937 test_184a() {
15938         check_swap_layouts_support
15939
15940         dir0=$DIR/$tdir/$testnum
15941         test_mkdir -p -c1 $dir0
15942         ref1=/etc/passwd
15943         ref2=/etc/group
15944         file1=$dir0/f1
15945         file2=$dir0/f2
15946         $LFS setstripe -c1 $file1
15947         cp $ref1 $file1
15948         $LFS setstripe -c2 $file2
15949         cp $ref2 $file2
15950         gen1=$($LFS getstripe -g $file1)
15951         gen2=$($LFS getstripe -g $file2)
15952
15953         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
15954         gen=$($LFS getstripe -g $file1)
15955         [[ $gen1 != $gen ]] ||
15956                 "Layout generation on $file1 does not change"
15957         gen=$($LFS getstripe -g $file2)
15958         [[ $gen2 != $gen ]] ||
15959                 "Layout generation on $file2 does not change"
15960
15961         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
15962         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15963
15964         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
15965 }
15966 run_test 184a "Basic layout swap"
15967
15968 test_184b() {
15969         check_swap_layouts_support
15970
15971         dir0=$DIR/$tdir/$testnum
15972         mkdir -p $dir0 || error "creating dir $dir0"
15973         file1=$dir0/f1
15974         file2=$dir0/f2
15975         file3=$dir0/f3
15976         dir1=$dir0/d1
15977         dir2=$dir0/d2
15978         mkdir $dir1 $dir2
15979         $LFS setstripe -c1 $file1
15980         $LFS setstripe -c2 $file2
15981         $LFS setstripe -c1 $file3
15982         chown $RUNAS_ID $file3
15983         gen1=$($LFS getstripe -g $file1)
15984         gen2=$($LFS getstripe -g $file2)
15985
15986         $LFS swap_layouts $dir1 $dir2 &&
15987                 error "swap of directories layouts should fail"
15988         $LFS swap_layouts $dir1 $file1 &&
15989                 error "swap of directory and file layouts should fail"
15990         $RUNAS $LFS swap_layouts $file1 $file2 &&
15991                 error "swap of file we cannot write should fail"
15992         $LFS swap_layouts $file1 $file3 &&
15993                 error "swap of file with different owner should fail"
15994         /bin/true # to clear error code
15995 }
15996 run_test 184b "Forbidden layout swap (will generate errors)"
15997
15998 test_184c() {
15999         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16000         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16001         check_swap_layouts_support
16002         check_swap_layout_no_dom $DIR
16003
16004         local dir0=$DIR/$tdir/$testnum
16005         mkdir -p $dir0 || error "creating dir $dir0"
16006
16007         local ref1=$dir0/ref1
16008         local ref2=$dir0/ref2
16009         local file1=$dir0/file1
16010         local file2=$dir0/file2
16011         # create a file large enough for the concurrent test
16012         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16013         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16014         echo "ref file size: ref1($(stat -c %s $ref1))," \
16015              "ref2($(stat -c %s $ref2))"
16016
16017         cp $ref2 $file2
16018         dd if=$ref1 of=$file1 bs=16k &
16019         local DD_PID=$!
16020
16021         # Make sure dd starts to copy file
16022         while [ ! -f $file1 ]; do sleep 0.1; done
16023
16024         $LFS swap_layouts $file1 $file2
16025         local rc=$?
16026         wait $DD_PID
16027         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16028         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16029
16030         # how many bytes copied before swapping layout
16031         local copied=$(stat -c %s $file2)
16032         local remaining=$(stat -c %s $ref1)
16033         remaining=$((remaining - copied))
16034         echo "Copied $copied bytes before swapping layout..."
16035
16036         cmp -n $copied $file1 $ref2 | grep differ &&
16037                 error "Content mismatch [0, $copied) of ref2 and file1"
16038         cmp -n $copied $file2 $ref1 ||
16039                 error "Content mismatch [0, $copied) of ref1 and file2"
16040         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16041                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16042
16043         # clean up
16044         rm -f $ref1 $ref2 $file1 $file2
16045 }
16046 run_test 184c "Concurrent write and layout swap"
16047
16048 test_184d() {
16049         check_swap_layouts_support
16050         check_swap_layout_no_dom $DIR
16051         [ -z "$(which getfattr 2>/dev/null)" ] &&
16052                 skip_env "no getfattr command"
16053
16054         local file1=$DIR/$tdir/$tfile-1
16055         local file2=$DIR/$tdir/$tfile-2
16056         local file3=$DIR/$tdir/$tfile-3
16057         local lovea1
16058         local lovea2
16059
16060         mkdir -p $DIR/$tdir
16061         touch $file1 || error "create $file1 failed"
16062         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16063                 error "create $file2 failed"
16064         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16065                 error "create $file3 failed"
16066         lovea1=$(get_layout_param $file1)
16067
16068         $LFS swap_layouts $file2 $file3 ||
16069                 error "swap $file2 $file3 layouts failed"
16070         $LFS swap_layouts $file1 $file2 ||
16071                 error "swap $file1 $file2 layouts failed"
16072
16073         lovea2=$(get_layout_param $file2)
16074         echo "$lovea1"
16075         echo "$lovea2"
16076         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16077
16078         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16079         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16080 }
16081 run_test 184d "allow stripeless layouts swap"
16082
16083 test_184e() {
16084         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16085                 skip "Need MDS version at least 2.6.94"
16086         check_swap_layouts_support
16087         check_swap_layout_no_dom $DIR
16088         [ -z "$(which getfattr 2>/dev/null)" ] &&
16089                 skip_env "no getfattr command"
16090
16091         local file1=$DIR/$tdir/$tfile-1
16092         local file2=$DIR/$tdir/$tfile-2
16093         local file3=$DIR/$tdir/$tfile-3
16094         local lovea
16095
16096         mkdir -p $DIR/$tdir
16097         touch $file1 || error "create $file1 failed"
16098         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16099                 error "create $file2 failed"
16100         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16101                 error "create $file3 failed"
16102
16103         $LFS swap_layouts $file1 $file2 ||
16104                 error "swap $file1 $file2 layouts failed"
16105
16106         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16107         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16108
16109         echo 123 > $file1 || error "Should be able to write into $file1"
16110
16111         $LFS swap_layouts $file1 $file3 ||
16112                 error "swap $file1 $file3 layouts failed"
16113
16114         echo 123 > $file1 || error "Should be able to write into $file1"
16115
16116         rm -rf $file1 $file2 $file3
16117 }
16118 run_test 184e "Recreate layout after stripeless layout swaps"
16119
16120 test_184f() {
16121         # Create a file with name longer than sizeof(struct stat) ==
16122         # 144 to see if we can get chars from the file name to appear
16123         # in the returned striping. Note that 'f' == 0x66.
16124         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16125
16126         mkdir -p $DIR/$tdir
16127         mcreate $DIR/$tdir/$file
16128         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16129                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16130         fi
16131 }
16132 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16133
16134 test_185() { # LU-2441
16135         # LU-3553 - no volatile file support in old servers
16136         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16137                 skip "Need MDS version at least 2.3.60"
16138
16139         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16140         touch $DIR/$tdir/spoo
16141         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16142         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16143                 error "cannot create/write a volatile file"
16144         [ "$FILESET" == "" ] &&
16145         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16146                 error "FID is still valid after close"
16147
16148         multiop_bg_pause $DIR/$tdir vVw4096_c
16149         local multi_pid=$!
16150
16151         local OLD_IFS=$IFS
16152         IFS=":"
16153         local fidv=($fid)
16154         IFS=$OLD_IFS
16155         # assume that the next FID for this client is sequential, since stdout
16156         # is unfortunately eaten by multiop_bg_pause
16157         local n=$((${fidv[1]} + 1))
16158         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16159         if [ "$FILESET" == "" ]; then
16160                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16161                         error "FID is missing before close"
16162         fi
16163         kill -USR1 $multi_pid
16164         # 1 second delay, so if mtime change we will see it
16165         sleep 1
16166         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16167         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16168 }
16169 run_test 185 "Volatile file support"
16170
16171 function create_check_volatile() {
16172         local idx=$1
16173         local tgt
16174
16175         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16176         local PID=$!
16177         sleep 1
16178         local FID=$(cat /tmp/${tfile}.fid)
16179         [ "$FID" == "" ] && error "can't get FID for volatile"
16180         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16181         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16182         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16183         kill -USR1 $PID
16184         wait
16185         sleep 1
16186         cancel_lru_locks mdc # flush opencache
16187         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16188         return 0
16189 }
16190
16191 test_185a(){
16192         # LU-12516 - volatile creation via .lustre
16193         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16194                 skip "Need MDS version at least 2.3.55"
16195
16196         create_check_volatile 0
16197         [ $MDSCOUNT -lt 2 ] && return 0
16198
16199         # DNE case
16200         create_check_volatile 1
16201
16202         return 0
16203 }
16204 run_test 185a "Volatile file creation in .lustre/fid/"
16205
16206 test_187a() {
16207         remote_mds_nodsh && skip "remote MDS with nodsh"
16208         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16209                 skip "Need MDS version at least 2.3.0"
16210
16211         local dir0=$DIR/$tdir/$testnum
16212         mkdir -p $dir0 || error "creating dir $dir0"
16213
16214         local file=$dir0/file1
16215         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16216         local dv1=$($LFS data_version $file)
16217         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16218         local dv2=$($LFS data_version $file)
16219         [[ $dv1 != $dv2 ]] ||
16220                 error "data version did not change on write $dv1 == $dv2"
16221
16222         # clean up
16223         rm -f $file1
16224 }
16225 run_test 187a "Test data version change"
16226
16227 test_187b() {
16228         remote_mds_nodsh && skip "remote MDS with nodsh"
16229         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16230                 skip "Need MDS version at least 2.3.0"
16231
16232         local dir0=$DIR/$tdir/$testnum
16233         mkdir -p $dir0 || error "creating dir $dir0"
16234
16235         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16236         [[ ${DV[0]} != ${DV[1]} ]] ||
16237                 error "data version did not change on write"\
16238                       " ${DV[0]} == ${DV[1]}"
16239
16240         # clean up
16241         rm -f $file1
16242 }
16243 run_test 187b "Test data version change on volatile file"
16244
16245 test_200() {
16246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16247         remote_mgs_nodsh && skip "remote MGS with nodsh"
16248         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16249
16250         local POOL=${POOL:-cea1}
16251         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16252         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16253         # Pool OST targets
16254         local first_ost=0
16255         local last_ost=$(($OSTCOUNT - 1))
16256         local ost_step=2
16257         local ost_list=$(seq $first_ost $ost_step $last_ost)
16258         local ost_range="$first_ost $last_ost $ost_step"
16259         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16260         local file_dir=$POOL_ROOT/file_tst
16261         local subdir=$test_path/subdir
16262         local rc=0
16263
16264         while : ; do
16265                 # former test_200a test_200b
16266                 pool_add $POOL                          || { rc=$? ; break; }
16267                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16268                 # former test_200c test_200d
16269                 mkdir -p $test_path
16270                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16271                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16272                 mkdir -p $subdir
16273                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16274                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16275                                                         || { rc=$? ; break; }
16276                 # former test_200e test_200f
16277                 local files=$((OSTCOUNT*3))
16278                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16279                                                         || { rc=$? ; break; }
16280                 pool_create_files $POOL $file_dir $files "$ost_list" \
16281                                                         || { rc=$? ; break; }
16282                 # former test_200g test_200h
16283                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16284                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16285
16286                 # former test_201a test_201b test_201c
16287                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16288
16289                 local f=$test_path/$tfile
16290                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16291                 pool_remove $POOL $f                    || { rc=$? ; break; }
16292                 break
16293         done
16294
16295         destroy_test_pools
16296
16297         return $rc
16298 }
16299 run_test 200 "OST pools"
16300
16301 # usage: default_attr <count | size | offset>
16302 default_attr() {
16303         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16304 }
16305
16306 # usage: check_default_stripe_attr
16307 check_default_stripe_attr() {
16308         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16309         case $1 in
16310         --stripe-count|-c)
16311                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16312         --stripe-size|-S)
16313                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16314         --stripe-index|-i)
16315                 EXPECTED=-1;;
16316         *)
16317                 error "unknown getstripe attr '$1'"
16318         esac
16319
16320         [ $ACTUAL == $EXPECTED ] ||
16321                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16322 }
16323
16324 test_204a() {
16325         test_mkdir $DIR/$tdir
16326         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16327
16328         check_default_stripe_attr --stripe-count
16329         check_default_stripe_attr --stripe-size
16330         check_default_stripe_attr --stripe-index
16331 }
16332 run_test 204a "Print default stripe attributes"
16333
16334 test_204b() {
16335         test_mkdir $DIR/$tdir
16336         $LFS setstripe --stripe-count 1 $DIR/$tdir
16337
16338         check_default_stripe_attr --stripe-size
16339         check_default_stripe_attr --stripe-index
16340 }
16341 run_test 204b "Print default stripe size and offset"
16342
16343 test_204c() {
16344         test_mkdir $DIR/$tdir
16345         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16346
16347         check_default_stripe_attr --stripe-count
16348         check_default_stripe_attr --stripe-index
16349 }
16350 run_test 204c "Print default stripe count and offset"
16351
16352 test_204d() {
16353         test_mkdir $DIR/$tdir
16354         $LFS setstripe --stripe-index 0 $DIR/$tdir
16355
16356         check_default_stripe_attr --stripe-count
16357         check_default_stripe_attr --stripe-size
16358 }
16359 run_test 204d "Print default stripe count and size"
16360
16361 test_204e() {
16362         test_mkdir $DIR/$tdir
16363         $LFS setstripe -d $DIR/$tdir
16364
16365         check_default_stripe_attr --stripe-count --raw
16366         check_default_stripe_attr --stripe-size --raw
16367         check_default_stripe_attr --stripe-index --raw
16368 }
16369 run_test 204e "Print raw stripe attributes"
16370
16371 test_204f() {
16372         test_mkdir $DIR/$tdir
16373         $LFS setstripe --stripe-count 1 $DIR/$tdir
16374
16375         check_default_stripe_attr --stripe-size --raw
16376         check_default_stripe_attr --stripe-index --raw
16377 }
16378 run_test 204f "Print raw stripe size and offset"
16379
16380 test_204g() {
16381         test_mkdir $DIR/$tdir
16382         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16383
16384         check_default_stripe_attr --stripe-count --raw
16385         check_default_stripe_attr --stripe-index --raw
16386 }
16387 run_test 204g "Print raw stripe count and offset"
16388
16389 test_204h() {
16390         test_mkdir $DIR/$tdir
16391         $LFS setstripe --stripe-index 0 $DIR/$tdir
16392
16393         check_default_stripe_attr --stripe-count --raw
16394         check_default_stripe_attr --stripe-size --raw
16395 }
16396 run_test 204h "Print raw stripe count and size"
16397
16398 # Figure out which job scheduler is being used, if any,
16399 # or use a fake one
16400 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16401         JOBENV=SLURM_JOB_ID
16402 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16403         JOBENV=LSB_JOBID
16404 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16405         JOBENV=PBS_JOBID
16406 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16407         JOBENV=LOADL_STEP_ID
16408 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16409         JOBENV=JOB_ID
16410 else
16411         $LCTL list_param jobid_name > /dev/null 2>&1
16412         if [ $? -eq 0 ]; then
16413                 JOBENV=nodelocal
16414         else
16415                 JOBENV=FAKE_JOBID
16416         fi
16417 fi
16418 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16419
16420 verify_jobstats() {
16421         local cmd=($1)
16422         shift
16423         local facets="$@"
16424
16425 # we don't really need to clear the stats for this test to work, since each
16426 # command has a unique jobid, but it makes debugging easier if needed.
16427 #       for facet in $facets; do
16428 #               local dev=$(convert_facet2label $facet)
16429 #               # clear old jobstats
16430 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16431 #       done
16432
16433         # use a new JobID for each test, or we might see an old one
16434         [ "$JOBENV" = "FAKE_JOBID" ] &&
16435                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16436
16437         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16438
16439         [ "$JOBENV" = "nodelocal" ] && {
16440                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16441                 $LCTL set_param jobid_name=$FAKE_JOBID
16442                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16443         }
16444
16445         log "Test: ${cmd[*]}"
16446         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16447
16448         if [ $JOBENV = "FAKE_JOBID" ]; then
16449                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16450         else
16451                 ${cmd[*]}
16452         fi
16453
16454         # all files are created on OST0000
16455         for facet in $facets; do
16456                 local stats="*.$(convert_facet2label $facet).job_stats"
16457
16458                 # strip out libtool wrappers for in-tree executables
16459                 if [ $(do_facet $facet lctl get_param $stats |
16460                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16461                         do_facet $facet lctl get_param $stats
16462                         error "No jobstats for $JOBVAL found on $facet::$stats"
16463                 fi
16464         done
16465 }
16466
16467 jobstats_set() {
16468         local new_jobenv=$1
16469
16470         set_persistent_param_and_check client "jobid_var" \
16471                 "$FSNAME.sys.jobid_var" $new_jobenv
16472 }
16473
16474 test_205a() { # Job stats
16475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16476         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16477                 skip "Need MDS version with at least 2.7.1"
16478         remote_mgs_nodsh && skip "remote MGS with nodsh"
16479         remote_mds_nodsh && skip "remote MDS with nodsh"
16480         remote_ost_nodsh && skip "remote OST with nodsh"
16481         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16482                 skip "Server doesn't support jobstats"
16483         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16484
16485         local old_jobenv=$($LCTL get_param -n jobid_var)
16486         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16487
16488         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16489                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16490         else
16491                 stack_trap "do_facet mgs $PERM_CMD \
16492                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16493         fi
16494         changelog_register
16495
16496         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16497                                 mdt.*.job_cleanup_interval | head -n 1)
16498         local new_interval=5
16499         do_facet $SINGLEMDS \
16500                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16501         stack_trap "do_facet $SINGLEMDS \
16502                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16503         local start=$SECONDS
16504
16505         local cmd
16506         # mkdir
16507         cmd="mkdir $DIR/$tdir"
16508         verify_jobstats "$cmd" "$SINGLEMDS"
16509         # rmdir
16510         cmd="rmdir $DIR/$tdir"
16511         verify_jobstats "$cmd" "$SINGLEMDS"
16512         # mkdir on secondary MDT
16513         if [ $MDSCOUNT -gt 1 ]; then
16514                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16515                 verify_jobstats "$cmd" "mds2"
16516         fi
16517         # mknod
16518         cmd="mknod $DIR/$tfile c 1 3"
16519         verify_jobstats "$cmd" "$SINGLEMDS"
16520         # unlink
16521         cmd="rm -f $DIR/$tfile"
16522         verify_jobstats "$cmd" "$SINGLEMDS"
16523         # create all files on OST0000 so verify_jobstats can find OST stats
16524         # open & close
16525         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16526         verify_jobstats "$cmd" "$SINGLEMDS"
16527         # setattr
16528         cmd="touch $DIR/$tfile"
16529         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16530         # write
16531         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16532         verify_jobstats "$cmd" "ost1"
16533         # read
16534         cancel_lru_locks osc
16535         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16536         verify_jobstats "$cmd" "ost1"
16537         # truncate
16538         cmd="$TRUNCATE $DIR/$tfile 0"
16539         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16540         # rename
16541         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16542         verify_jobstats "$cmd" "$SINGLEMDS"
16543         # jobstats expiry - sleep until old stats should be expired
16544         local left=$((new_interval + 5 - (SECONDS - start)))
16545         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16546                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16547                         "0" $left
16548         cmd="mkdir $DIR/$tdir.expire"
16549         verify_jobstats "$cmd" "$SINGLEMDS"
16550         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16551             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16552
16553         # Ensure that jobid are present in changelog (if supported by MDS)
16554         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16555                 changelog_dump | tail -10
16556                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16557                 [ $jobids -eq 9 ] ||
16558                         error "Wrong changelog jobid count $jobids != 9"
16559
16560                 # LU-5862
16561                 JOBENV="disable"
16562                 jobstats_set $JOBENV
16563                 touch $DIR/$tfile
16564                 changelog_dump | grep $tfile
16565                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16566                 [ $jobids -eq 0 ] ||
16567                         error "Unexpected jobids when jobid_var=$JOBENV"
16568         fi
16569
16570         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
16571         JOBENV="JOBCOMPLEX"
16572         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16573
16574         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16575 }
16576 run_test 205a "Verify job stats"
16577
16578 # LU-13117, LU-13597
16579 test_205b() {
16580         job_stats="mdt.*.job_stats"
16581         $LCTL set_param $job_stats=clear
16582         $LCTL set_param jobid_var=USER jobid_name="%e.%u"
16583         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16584         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16585                 grep "job_id:.*foolish" &&
16586                         error "Unexpected jobid found"
16587         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16588                 grep "open:.*min.*max.*sum" ||
16589                         error "wrong job_stats format found"
16590 }
16591 run_test 205b "Verify job stats jobid and output format"
16592
16593 # LU-13733
16594 test_205c() {
16595         $LCTL set_param llite.*.stats=0
16596         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16597         $LCTL get_param llite.*.stats
16598         $LCTL get_param llite.*.stats | grep \
16599                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16600                         error "wrong client stats format found"
16601 }
16602 run_test 205c "Verify client stats format"
16603
16604 # LU-1480, LU-1773 and LU-1657
16605 test_206() {
16606         mkdir -p $DIR/$tdir
16607         $LFS setstripe -c -1 $DIR/$tdir
16608 #define OBD_FAIL_LOV_INIT 0x1403
16609         $LCTL set_param fail_loc=0xa0001403
16610         $LCTL set_param fail_val=1
16611         touch $DIR/$tdir/$tfile || true
16612 }
16613 run_test 206 "fail lov_init_raid0() doesn't lbug"
16614
16615 test_207a() {
16616         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16617         local fsz=`stat -c %s $DIR/$tfile`
16618         cancel_lru_locks mdc
16619
16620         # do not return layout in getattr intent
16621 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16622         $LCTL set_param fail_loc=0x170
16623         local sz=`stat -c %s $DIR/$tfile`
16624
16625         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16626
16627         rm -rf $DIR/$tfile
16628 }
16629 run_test 207a "can refresh layout at glimpse"
16630
16631 test_207b() {
16632         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16633         local cksum=`md5sum $DIR/$tfile`
16634         local fsz=`stat -c %s $DIR/$tfile`
16635         cancel_lru_locks mdc
16636         cancel_lru_locks osc
16637
16638         # do not return layout in getattr intent
16639 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16640         $LCTL set_param fail_loc=0x171
16641
16642         # it will refresh layout after the file is opened but before read issues
16643         echo checksum is "$cksum"
16644         echo "$cksum" |md5sum -c --quiet || error "file differs"
16645
16646         rm -rf $DIR/$tfile
16647 }
16648 run_test 207b "can refresh layout at open"
16649
16650 test_208() {
16651         # FIXME: in this test suite, only RD lease is used. This is okay
16652         # for now as only exclusive open is supported. After generic lease
16653         # is done, this test suite should be revised. - Jinshan
16654
16655         remote_mds_nodsh && skip "remote MDS with nodsh"
16656         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16657                 skip "Need MDS version at least 2.4.52"
16658
16659         echo "==== test 1: verify get lease work"
16660         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16661
16662         echo "==== test 2: verify lease can be broken by upcoming open"
16663         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16664         local PID=$!
16665         sleep 1
16666
16667         $MULTIOP $DIR/$tfile oO_RDONLY:c
16668         kill -USR1 $PID && wait $PID || error "break lease error"
16669
16670         echo "==== test 3: verify lease can't be granted if an open already exists"
16671         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16672         local PID=$!
16673         sleep 1
16674
16675         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16676         kill -USR1 $PID && wait $PID || error "open file error"
16677
16678         echo "==== test 4: lease can sustain over recovery"
16679         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16680         PID=$!
16681         sleep 1
16682
16683         fail mds1
16684
16685         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16686
16687         echo "==== test 5: lease broken can't be regained by replay"
16688         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16689         PID=$!
16690         sleep 1
16691
16692         # open file to break lease and then recovery
16693         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16694         fail mds1
16695
16696         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16697
16698         rm -f $DIR/$tfile
16699 }
16700 run_test 208 "Exclusive open"
16701
16702 test_209() {
16703         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16704                 skip_env "must have disp_stripe"
16705
16706         touch $DIR/$tfile
16707         sync; sleep 5; sync;
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_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16713
16714         # open/close 500 times
16715         for i in $(seq 500); do
16716                 cat $DIR/$tfile
16717         done
16718
16719         echo 3 > /proc/sys/vm/drop_caches
16720         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16721                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16722         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16723
16724         echo "before: $req_before, after: $req_after"
16725         [ $((req_after - req_before)) -ge 300 ] &&
16726                 error "open/close requests are not freed"
16727         return 0
16728 }
16729 run_test 209 "read-only open/close requests should be freed promptly"
16730
16731 test_210() {
16732         local pid
16733
16734         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16735         pid=$!
16736         sleep 1
16737
16738         $LFS getstripe $DIR/$tfile
16739         kill -USR1 $pid
16740         wait $pid || error "multiop failed"
16741
16742         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16743         pid=$!
16744         sleep 1
16745
16746         $LFS getstripe $DIR/$tfile
16747         kill -USR1 $pid
16748         wait $pid || error "multiop failed"
16749 }
16750 run_test 210 "lfs getstripe does not break leases"
16751
16752 test_212() {
16753         size=`date +%s`
16754         size=$((size % 8192 + 1))
16755         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16756         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16757         rm -f $DIR/f212 $DIR/f212.xyz
16758 }
16759 run_test 212 "Sendfile test ============================================"
16760
16761 test_213() {
16762         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16763         cancel_lru_locks osc
16764         lctl set_param fail_loc=0x8000040f
16765         # generate a read lock
16766         cat $DIR/$tfile > /dev/null
16767         # write to the file, it will try to cancel the above read lock.
16768         cat /etc/hosts >> $DIR/$tfile
16769 }
16770 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16771
16772 test_214() { # for bug 20133
16773         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16774         for (( i=0; i < 340; i++ )) ; do
16775                 touch $DIR/$tdir/d214c/a$i
16776         done
16777
16778         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16779         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16780         ls $DIR/d214c || error "ls $DIR/d214c failed"
16781         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16782         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16783 }
16784 run_test 214 "hash-indexed directory test - bug 20133"
16785
16786 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16787 create_lnet_proc_files() {
16788         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16789 }
16790
16791 # counterpart of create_lnet_proc_files
16792 remove_lnet_proc_files() {
16793         rm -f $TMP/lnet_$1.sys
16794 }
16795
16796 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16797 # 3rd arg as regexp for body
16798 check_lnet_proc_stats() {
16799         local l=$(cat "$TMP/lnet_$1" |wc -l)
16800         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16801
16802         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16803 }
16804
16805 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16806 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16807 # optional and can be regexp for 2nd line (lnet.routes case)
16808 check_lnet_proc_entry() {
16809         local blp=2          # blp stands for 'position of 1st line of body'
16810         [ -z "$5" ] || blp=3 # lnet.routes case
16811
16812         local l=$(cat "$TMP/lnet_$1" |wc -l)
16813         # subtracting one from $blp because the body can be empty
16814         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16815
16816         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16817                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16818
16819         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16820                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16821
16822         # bail out if any unexpected line happened
16823         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16824         [ "$?" != 0 ] || error "$2 misformatted"
16825 }
16826
16827 test_215() { # for bugs 18102, 21079, 21517
16828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16829
16830         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16831         local P='[1-9][0-9]*'           # positive numeric
16832         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16833         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16834         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16835         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16836
16837         local L1 # regexp for 1st line
16838         local L2 # regexp for 2nd line (optional)
16839         local BR # regexp for the rest (body)
16840
16841         # lnet.stats should look as 11 space-separated non-negative numerics
16842         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16843         create_lnet_proc_files "stats"
16844         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16845         remove_lnet_proc_files "stats"
16846
16847         # lnet.routes should look like this:
16848         # Routing disabled/enabled
16849         # net hops priority state router
16850         # where net is a string like tcp0, hops > 0, priority >= 0,
16851         # state is up/down,
16852         # router is a string like 192.168.1.1@tcp2
16853         L1="^Routing (disabled|enabled)$"
16854         L2="^net +hops +priority +state +router$"
16855         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16856         create_lnet_proc_files "routes"
16857         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16858         remove_lnet_proc_files "routes"
16859
16860         # lnet.routers should look like this:
16861         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16862         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16863         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16864         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16865         L1="^ref +rtr_ref +alive +router$"
16866         BR="^$P +$P +(up|down) +$NID$"
16867         create_lnet_proc_files "routers"
16868         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16869         remove_lnet_proc_files "routers"
16870
16871         # lnet.peers should look like this:
16872         # nid refs state last max rtr min tx min queue
16873         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16874         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16875         # numeric (0 or >0 or <0), queue >= 0.
16876         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16877         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16878         create_lnet_proc_files "peers"
16879         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16880         remove_lnet_proc_files "peers"
16881
16882         # lnet.buffers  should look like this:
16883         # pages count credits min
16884         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16885         L1="^pages +count +credits +min$"
16886         BR="^ +$N +$N +$I +$I$"
16887         create_lnet_proc_files "buffers"
16888         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16889         remove_lnet_proc_files "buffers"
16890
16891         # lnet.nis should look like this:
16892         # nid status alive refs peer rtr max tx min
16893         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16894         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16895         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16896         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16897         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16898         create_lnet_proc_files "nis"
16899         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16900         remove_lnet_proc_files "nis"
16901
16902         # can we successfully write to lnet.stats?
16903         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
16904 }
16905 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
16906
16907 test_216() { # bug 20317
16908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16909         remote_ost_nodsh && skip "remote OST with nodsh"
16910
16911         local node
16912         local facets=$(get_facets OST)
16913         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16914
16915         save_lustre_params client "osc.*.contention_seconds" > $p
16916         save_lustre_params $facets \
16917                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
16918         save_lustre_params $facets \
16919                 "ldlm.namespaces.filter-*.contended_locks" >> $p
16920         save_lustre_params $facets \
16921                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
16922         clear_stats osc.*.osc_stats
16923
16924         # agressive lockless i/o settings
16925         do_nodes $(comma_list $(osts_nodes)) \
16926                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
16927                         ldlm.namespaces.filter-*.contended_locks=0 \
16928                         ldlm.namespaces.filter-*.contention_seconds=60"
16929         lctl set_param -n osc.*.contention_seconds=60
16930
16931         $DIRECTIO write $DIR/$tfile 0 10 4096
16932         $CHECKSTAT -s 40960 $DIR/$tfile
16933
16934         # disable lockless i/o
16935         do_nodes $(comma_list $(osts_nodes)) \
16936                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
16937                         ldlm.namespaces.filter-*.contended_locks=32 \
16938                         ldlm.namespaces.filter-*.contention_seconds=0"
16939         lctl set_param -n osc.*.contention_seconds=0
16940         clear_stats osc.*.osc_stats
16941
16942         dd if=/dev/zero of=$DIR/$tfile count=0
16943         $CHECKSTAT -s 0 $DIR/$tfile
16944
16945         restore_lustre_params <$p
16946         rm -f $p
16947         rm $DIR/$tfile
16948 }
16949 run_test 216 "check lockless direct write updates file size and kms correctly"
16950
16951 test_217() { # bug 22430
16952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16953
16954         local node
16955         local nid
16956
16957         for node in $(nodes_list); do
16958                 nid=$(host_nids_address $node $NETTYPE)
16959                 if [[ $nid = *-* ]] ; then
16960                         echo "lctl ping $(h2nettype $nid)"
16961                         lctl ping $(h2nettype $nid)
16962                 else
16963                         echo "skipping $node (no hyphen detected)"
16964                 fi
16965         done
16966 }
16967 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
16968
16969 test_218() {
16970        # do directio so as not to populate the page cache
16971        log "creating a 10 Mb file"
16972        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
16973        log "starting reads"
16974        dd if=$DIR/$tfile of=/dev/null bs=4096 &
16975        log "truncating the file"
16976        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
16977        log "killing dd"
16978        kill %+ || true # reads might have finished
16979        echo "wait until dd is finished"
16980        wait
16981        log "removing the temporary file"
16982        rm -rf $DIR/$tfile || error "tmp file removal failed"
16983 }
16984 run_test 218 "parallel read and truncate should not deadlock"
16985
16986 test_219() {
16987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16988
16989         # write one partial page
16990         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
16991         # set no grant so vvp_io_commit_write will do sync write
16992         $LCTL set_param fail_loc=0x411
16993         # write a full page at the end of file
16994         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
16995
16996         $LCTL set_param fail_loc=0
16997         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
16998         $LCTL set_param fail_loc=0x411
16999         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17000
17001         # LU-4201
17002         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17003         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17004 }
17005 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17006
17007 test_220() { #LU-325
17008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17009         remote_ost_nodsh && skip "remote OST with nodsh"
17010         remote_mds_nodsh && skip "remote MDS with nodsh"
17011         remote_mgs_nodsh && skip "remote MGS with nodsh"
17012
17013         local OSTIDX=0
17014
17015         # create on MDT0000 so the last_id and next_id are correct
17016         mkdir $DIR/$tdir
17017         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17018         OST=${OST%_UUID}
17019
17020         # on the mdt's osc
17021         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17022         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17023                         osp.$mdtosc_proc1.prealloc_last_id)
17024         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17025                         osp.$mdtosc_proc1.prealloc_next_id)
17026
17027         $LFS df -i
17028
17029         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17030         #define OBD_FAIL_OST_ENOINO              0x229
17031         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17032         create_pool $FSNAME.$TESTNAME || return 1
17033         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17034
17035         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17036
17037         MDSOBJS=$((last_id - next_id))
17038         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17039
17040         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17041         echo "OST still has $count kbytes free"
17042
17043         echo "create $MDSOBJS files @next_id..."
17044         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17045
17046         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17047                         osp.$mdtosc_proc1.prealloc_last_id)
17048         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17049                         osp.$mdtosc_proc1.prealloc_next_id)
17050
17051         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17052         $LFS df -i
17053
17054         echo "cleanup..."
17055
17056         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17057         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17058
17059         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17060                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17061         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17062                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17063         echo "unlink $MDSOBJS files @$next_id..."
17064         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17065 }
17066 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17067
17068 test_221() {
17069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17070
17071         dd if=`which date` of=$MOUNT/date oflag=sync
17072         chmod +x $MOUNT/date
17073
17074         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17075         $LCTL set_param fail_loc=0x80001401
17076
17077         $MOUNT/date > /dev/null
17078         rm -f $MOUNT/date
17079 }
17080 run_test 221 "make sure fault and truncate race to not cause OOM"
17081
17082 test_222a () {
17083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17084
17085         rm -rf $DIR/$tdir
17086         test_mkdir $DIR/$tdir
17087         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17088         createmany -o $DIR/$tdir/$tfile 10
17089         cancel_lru_locks mdc
17090         cancel_lru_locks osc
17091         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17092         $LCTL set_param fail_loc=0x31a
17093         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17094         $LCTL set_param fail_loc=0
17095         rm -r $DIR/$tdir
17096 }
17097 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17098
17099 test_222b () {
17100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17101
17102         rm -rf $DIR/$tdir
17103         test_mkdir $DIR/$tdir
17104         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17105         createmany -o $DIR/$tdir/$tfile 10
17106         cancel_lru_locks mdc
17107         cancel_lru_locks osc
17108         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17109         $LCTL set_param fail_loc=0x31a
17110         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17111         $LCTL set_param fail_loc=0
17112 }
17113 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17114
17115 test_223 () {
17116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17117
17118         rm -rf $DIR/$tdir
17119         test_mkdir $DIR/$tdir
17120         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17121         createmany -o $DIR/$tdir/$tfile 10
17122         cancel_lru_locks mdc
17123         cancel_lru_locks osc
17124         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17125         $LCTL set_param fail_loc=0x31b
17126         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17127         $LCTL set_param fail_loc=0
17128         rm -r $DIR/$tdir
17129 }
17130 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17131
17132 test_224a() { # LU-1039, MRP-303
17133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17134
17135         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17136         $LCTL set_param fail_loc=0x508
17137         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17138         $LCTL set_param fail_loc=0
17139         df $DIR
17140 }
17141 run_test 224a "Don't panic on bulk IO failure"
17142
17143 test_224b() { # LU-1039, MRP-303
17144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17145
17146         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17147         cancel_lru_locks osc
17148         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17149         $LCTL set_param fail_loc=0x515
17150         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17151         $LCTL set_param fail_loc=0
17152         df $DIR
17153 }
17154 run_test 224b "Don't panic on bulk IO failure"
17155
17156 test_224c() { # LU-6441
17157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17158         remote_mds_nodsh && skip "remote MDS with nodsh"
17159
17160         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17161         save_writethrough $p
17162         set_cache writethrough on
17163
17164         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17165         local at_max=$($LCTL get_param -n at_max)
17166         local timeout=$($LCTL get_param -n timeout)
17167         local test_at="at_max"
17168         local param_at="$FSNAME.sys.at_max"
17169         local test_timeout="timeout"
17170         local param_timeout="$FSNAME.sys.timeout"
17171
17172         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17173
17174         set_persistent_param_and_check client "$test_at" "$param_at" 0
17175         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17176
17177         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17178         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17179         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17180         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17181         sync
17182         do_facet ost1 "$LCTL set_param fail_loc=0"
17183
17184         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17185         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17186                 $timeout
17187
17188         $LCTL set_param -n $pages_per_rpc
17189         restore_lustre_params < $p
17190         rm -f $p
17191 }
17192 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17193
17194 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17195 test_225a () {
17196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17197         if [ -z ${MDSSURVEY} ]; then
17198                 skip_env "mds-survey not found"
17199         fi
17200         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17201                 skip "Need MDS version at least 2.2.51"
17202
17203         local mds=$(facet_host $SINGLEMDS)
17204         local target=$(do_nodes $mds 'lctl dl' |
17205                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17206
17207         local cmd1="file_count=1000 thrhi=4"
17208         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17209         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17210         local cmd="$cmd1 $cmd2 $cmd3"
17211
17212         rm -f ${TMP}/mds_survey*
17213         echo + $cmd
17214         eval $cmd || error "mds-survey with zero-stripe failed"
17215         cat ${TMP}/mds_survey*
17216         rm -f ${TMP}/mds_survey*
17217 }
17218 run_test 225a "Metadata survey sanity with zero-stripe"
17219
17220 test_225b () {
17221         if [ -z ${MDSSURVEY} ]; then
17222                 skip_env "mds-survey not found"
17223         fi
17224         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17225                 skip "Need MDS version at least 2.2.51"
17226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17227         remote_mds_nodsh && skip "remote MDS with nodsh"
17228         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17229                 skip_env "Need to mount OST to test"
17230         fi
17231
17232         local mds=$(facet_host $SINGLEMDS)
17233         local target=$(do_nodes $mds 'lctl dl' |
17234                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17235
17236         local cmd1="file_count=1000 thrhi=4"
17237         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17238         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17239         local cmd="$cmd1 $cmd2 $cmd3"
17240
17241         rm -f ${TMP}/mds_survey*
17242         echo + $cmd
17243         eval $cmd || error "mds-survey with stripe_count failed"
17244         cat ${TMP}/mds_survey*
17245         rm -f ${TMP}/mds_survey*
17246 }
17247 run_test 225b "Metadata survey sanity with stripe_count = 1"
17248
17249 mcreate_path2fid () {
17250         local mode=$1
17251         local major=$2
17252         local minor=$3
17253         local name=$4
17254         local desc=$5
17255         local path=$DIR/$tdir/$name
17256         local fid
17257         local rc
17258         local fid_path
17259
17260         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17261                 error "cannot create $desc"
17262
17263         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17264         rc=$?
17265         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17266
17267         fid_path=$($LFS fid2path $MOUNT $fid)
17268         rc=$?
17269         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17270
17271         [ "$path" == "$fid_path" ] ||
17272                 error "fid2path returned $fid_path, expected $path"
17273
17274         echo "pass with $path and $fid"
17275 }
17276
17277 test_226a () {
17278         rm -rf $DIR/$tdir
17279         mkdir -p $DIR/$tdir
17280
17281         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17282         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17283         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17284         mcreate_path2fid 0040666 0 0 dir "directory"
17285         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17286         mcreate_path2fid 0100666 0 0 file "regular file"
17287         mcreate_path2fid 0120666 0 0 link "symbolic link"
17288         mcreate_path2fid 0140666 0 0 sock "socket"
17289 }
17290 run_test 226a "call path2fid and fid2path on files of all type"
17291
17292 test_226b () {
17293         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17294
17295         local MDTIDX=1
17296
17297         rm -rf $DIR/$tdir
17298         mkdir -p $DIR/$tdir
17299         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17300                 error "create remote directory failed"
17301         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17302         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17303                                 "character special file (null)"
17304         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17305                                 "character special file (no device)"
17306         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17307         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17308                                 "block special file (loop)"
17309         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17310         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17311         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17312 }
17313 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17314
17315 test_226c () {
17316         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17317         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17318                 skip "Need MDS version at least 2.13.55"
17319
17320         local submnt=/mnt/submnt
17321         local srcfile=/etc/passwd
17322         local dstfile=$submnt/passwd
17323         local path
17324         local fid
17325
17326         rm -rf $DIR/$tdir
17327         rm -rf $submnt
17328         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17329                 error "create remote directory failed"
17330         mkdir -p $submnt || error "create $submnt failed"
17331         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17332                 error "mount $submnt failed"
17333         stack_trap "umount $submnt" EXIT
17334
17335         cp $srcfile $dstfile
17336         fid=$($LFS path2fid $dstfile)
17337         path=$($LFS fid2path $submnt "$fid")
17338         [ "$path" = "$dstfile" ] ||
17339                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17340 }
17341 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17342
17343 # LU-1299 Executing or running ldd on a truncated executable does not
17344 # cause an out-of-memory condition.
17345 test_227() {
17346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17347         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17348
17349         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17350         chmod +x $MOUNT/date
17351
17352         $MOUNT/date > /dev/null
17353         ldd $MOUNT/date > /dev/null
17354         rm -f $MOUNT/date
17355 }
17356 run_test 227 "running truncated executable does not cause OOM"
17357
17358 # LU-1512 try to reuse idle OI blocks
17359 test_228a() {
17360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17361         remote_mds_nodsh && skip "remote MDS with nodsh"
17362         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17363
17364         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17365         local myDIR=$DIR/$tdir
17366
17367         mkdir -p $myDIR
17368         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17369         $LCTL set_param fail_loc=0x80001002
17370         createmany -o $myDIR/t- 10000
17371         $LCTL set_param fail_loc=0
17372         # The guard is current the largest FID holder
17373         touch $myDIR/guard
17374         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17375                     tr -d '[')
17376         local IDX=$(($SEQ % 64))
17377
17378         do_facet $SINGLEMDS sync
17379         # Make sure journal flushed.
17380         sleep 6
17381         local blk1=$(do_facet $SINGLEMDS \
17382                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17383                      grep Blockcount | awk '{print $4}')
17384
17385         # Remove old files, some OI blocks will become idle.
17386         unlinkmany $myDIR/t- 10000
17387         # Create new files, idle OI blocks should be reused.
17388         createmany -o $myDIR/t- 2000
17389         do_facet $SINGLEMDS sync
17390         # Make sure journal flushed.
17391         sleep 6
17392         local blk2=$(do_facet $SINGLEMDS \
17393                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17394                      grep Blockcount | awk '{print $4}')
17395
17396         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17397 }
17398 run_test 228a "try to reuse idle OI blocks"
17399
17400 test_228b() {
17401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17402         remote_mds_nodsh && skip "remote MDS with nodsh"
17403         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17404
17405         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17406         local myDIR=$DIR/$tdir
17407
17408         mkdir -p $myDIR
17409         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17410         $LCTL set_param fail_loc=0x80001002
17411         createmany -o $myDIR/t- 10000
17412         $LCTL set_param fail_loc=0
17413         # The guard is current the largest FID holder
17414         touch $myDIR/guard
17415         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17416                     tr -d '[')
17417         local IDX=$(($SEQ % 64))
17418
17419         do_facet $SINGLEMDS sync
17420         # Make sure journal flushed.
17421         sleep 6
17422         local blk1=$(do_facet $SINGLEMDS \
17423                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17424                      grep Blockcount | awk '{print $4}')
17425
17426         # Remove old files, some OI blocks will become idle.
17427         unlinkmany $myDIR/t- 10000
17428
17429         # stop the MDT
17430         stop $SINGLEMDS || error "Fail to stop MDT."
17431         # remount the MDT
17432         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17433
17434         df $MOUNT || error "Fail to df."
17435         # Create new files, idle OI blocks should be reused.
17436         createmany -o $myDIR/t- 2000
17437         do_facet $SINGLEMDS sync
17438         # Make sure journal flushed.
17439         sleep 6
17440         local blk2=$(do_facet $SINGLEMDS \
17441                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17442                      grep Blockcount | awk '{print $4}')
17443
17444         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17445 }
17446 run_test 228b "idle OI blocks can be reused after MDT restart"
17447
17448 #LU-1881
17449 test_228c() {
17450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17451         remote_mds_nodsh && skip "remote MDS with nodsh"
17452         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17453
17454         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17455         local myDIR=$DIR/$tdir
17456
17457         mkdir -p $myDIR
17458         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17459         $LCTL set_param fail_loc=0x80001002
17460         # 20000 files can guarantee there are index nodes in the OI file
17461         createmany -o $myDIR/t- 20000
17462         $LCTL set_param fail_loc=0
17463         # The guard is current the largest FID holder
17464         touch $myDIR/guard
17465         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17466                     tr -d '[')
17467         local IDX=$(($SEQ % 64))
17468
17469         do_facet $SINGLEMDS sync
17470         # Make sure journal flushed.
17471         sleep 6
17472         local blk1=$(do_facet $SINGLEMDS \
17473                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17474                      grep Blockcount | awk '{print $4}')
17475
17476         # Remove old files, some OI blocks will become idle.
17477         unlinkmany $myDIR/t- 20000
17478         rm -f $myDIR/guard
17479         # The OI file should become empty now
17480
17481         # Create new files, idle OI blocks should be reused.
17482         createmany -o $myDIR/t- 2000
17483         do_facet $SINGLEMDS sync
17484         # Make sure journal flushed.
17485         sleep 6
17486         local blk2=$(do_facet $SINGLEMDS \
17487                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17488                      grep Blockcount | awk '{print $4}')
17489
17490         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17491 }
17492 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17493
17494 test_229() { # LU-2482, LU-3448
17495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17496         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17497         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17498                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17499
17500         rm -f $DIR/$tfile
17501
17502         # Create a file with a released layout and stripe count 2.
17503         $MULTIOP $DIR/$tfile H2c ||
17504                 error "failed to create file with released layout"
17505
17506         $LFS getstripe -v $DIR/$tfile
17507
17508         local pattern=$($LFS getstripe -L $DIR/$tfile)
17509         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17510
17511         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17512                 error "getstripe"
17513         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17514         stat $DIR/$tfile || error "failed to stat released file"
17515
17516         chown $RUNAS_ID $DIR/$tfile ||
17517                 error "chown $RUNAS_ID $DIR/$tfile failed"
17518
17519         chgrp $RUNAS_ID $DIR/$tfile ||
17520                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17521
17522         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17523         rm $DIR/$tfile || error "failed to remove released file"
17524 }
17525 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17526
17527 test_230a() {
17528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17529         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17530         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17531                 skip "Need MDS version at least 2.11.52"
17532
17533         local MDTIDX=1
17534
17535         test_mkdir $DIR/$tdir
17536         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17537         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17538         [ $mdt_idx -ne 0 ] &&
17539                 error "create local directory on wrong MDT $mdt_idx"
17540
17541         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17542                         error "create remote directory failed"
17543         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17544         [ $mdt_idx -ne $MDTIDX ] &&
17545                 error "create remote directory on wrong MDT $mdt_idx"
17546
17547         createmany -o $DIR/$tdir/test_230/t- 10 ||
17548                 error "create files on remote directory failed"
17549         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17550         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17551         rm -r $DIR/$tdir || error "unlink remote directory failed"
17552 }
17553 run_test 230a "Create remote directory and files under the remote directory"
17554
17555 test_230b() {
17556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17557         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17558         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17559                 skip "Need MDS version at least 2.11.52"
17560
17561         local MDTIDX=1
17562         local mdt_index
17563         local i
17564         local file
17565         local pid
17566         local stripe_count
17567         local migrate_dir=$DIR/$tdir/migrate_dir
17568         local other_dir=$DIR/$tdir/other_dir
17569
17570         test_mkdir $DIR/$tdir
17571         test_mkdir -i0 -c1 $migrate_dir
17572         test_mkdir -i0 -c1 $other_dir
17573         for ((i=0; i<10; i++)); do
17574                 mkdir -p $migrate_dir/dir_${i}
17575                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17576                         error "create files under remote dir failed $i"
17577         done
17578
17579         cp /etc/passwd $migrate_dir/$tfile
17580         cp /etc/passwd $other_dir/$tfile
17581         chattr +SAD $migrate_dir
17582         chattr +SAD $migrate_dir/$tfile
17583
17584         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17585         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17586         local old_dir_mode=$(stat -c%f $migrate_dir)
17587         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17588
17589         mkdir -p $migrate_dir/dir_default_stripe2
17590         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17591         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17592
17593         mkdir -p $other_dir
17594         ln $migrate_dir/$tfile $other_dir/luna
17595         ln $migrate_dir/$tfile $migrate_dir/sofia
17596         ln $other_dir/$tfile $migrate_dir/david
17597         ln -s $migrate_dir/$tfile $other_dir/zachary
17598         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17599         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17600
17601         local len
17602         local lnktgt
17603
17604         # inline symlink
17605         for len in 58 59 60; do
17606                 lnktgt=$(str_repeat 'l' $len)
17607                 touch $migrate_dir/$lnktgt
17608                 ln -s $lnktgt $migrate_dir/${len}char_ln
17609         done
17610
17611         # PATH_MAX
17612         for len in 4094 4095; do
17613                 lnktgt=$(str_repeat 'l' $len)
17614                 ln -s $lnktgt $migrate_dir/${len}char_ln
17615         done
17616
17617         # NAME_MAX
17618         for len in 254 255; do
17619                 touch $migrate_dir/$(str_repeat 'l' $len)
17620         done
17621
17622         $LFS migrate -m $MDTIDX $migrate_dir ||
17623                 error "fails on migrating remote dir to MDT1"
17624
17625         echo "migratate to MDT1, then checking.."
17626         for ((i = 0; i < 10; i++)); do
17627                 for file in $(find $migrate_dir/dir_${i}); do
17628                         mdt_index=$($LFS getstripe -m $file)
17629                         # broken symlink getstripe will fail
17630                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17631                                 error "$file is not on MDT${MDTIDX}"
17632                 done
17633         done
17634
17635         # the multiple link file should still in MDT0
17636         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17637         [ $mdt_index == 0 ] ||
17638                 error "$file is not on MDT${MDTIDX}"
17639
17640         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17641         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17642                 error " expect $old_dir_flag get $new_dir_flag"
17643
17644         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17645         [ "$old_file_flag" = "$new_file_flag" ] ||
17646                 error " expect $old_file_flag get $new_file_flag"
17647
17648         local new_dir_mode=$(stat -c%f $migrate_dir)
17649         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17650                 error "expect mode $old_dir_mode get $new_dir_mode"
17651
17652         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17653         [ "$old_file_mode" = "$new_file_mode" ] ||
17654                 error "expect mode $old_file_mode get $new_file_mode"
17655
17656         diff /etc/passwd $migrate_dir/$tfile ||
17657                 error "$tfile different after migration"
17658
17659         diff /etc/passwd $other_dir/luna ||
17660                 error "luna different after migration"
17661
17662         diff /etc/passwd $migrate_dir/sofia ||
17663                 error "sofia different after migration"
17664
17665         diff /etc/passwd $migrate_dir/david ||
17666                 error "david different after migration"
17667
17668         diff /etc/passwd $other_dir/zachary ||
17669                 error "zachary different after migration"
17670
17671         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17672                 error "${tfile}_ln different after migration"
17673
17674         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17675                 error "${tfile}_ln_other different after migration"
17676
17677         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17678         [ $stripe_count = 2 ] ||
17679                 error "dir strpe_count $d != 2 after migration."
17680
17681         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17682         [ $stripe_count = 2 ] ||
17683                 error "file strpe_count $d != 2 after migration."
17684
17685         #migrate back to MDT0
17686         MDTIDX=0
17687
17688         $LFS migrate -m $MDTIDX $migrate_dir ||
17689                 error "fails on migrating remote dir to MDT0"
17690
17691         echo "migrate back to MDT0, checking.."
17692         for file in $(find $migrate_dir); do
17693                 mdt_index=$($LFS getstripe -m $file)
17694                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17695                         error "$file is not on MDT${MDTIDX}"
17696         done
17697
17698         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17699         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17700                 error " expect $old_dir_flag get $new_dir_flag"
17701
17702         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17703         [ "$old_file_flag" = "$new_file_flag" ] ||
17704                 error " expect $old_file_flag get $new_file_flag"
17705
17706         local new_dir_mode=$(stat -c%f $migrate_dir)
17707         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17708                 error "expect mode $old_dir_mode get $new_dir_mode"
17709
17710         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17711         [ "$old_file_mode" = "$new_file_mode" ] ||
17712                 error "expect mode $old_file_mode get $new_file_mode"
17713
17714         diff /etc/passwd ${migrate_dir}/$tfile ||
17715                 error "$tfile different after migration"
17716
17717         diff /etc/passwd ${other_dir}/luna ||
17718                 error "luna different after migration"
17719
17720         diff /etc/passwd ${migrate_dir}/sofia ||
17721                 error "sofia different after migration"
17722
17723         diff /etc/passwd ${other_dir}/zachary ||
17724                 error "zachary different after migration"
17725
17726         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17727                 error "${tfile}_ln different after migration"
17728
17729         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17730                 error "${tfile}_ln_other different after migration"
17731
17732         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17733         [ $stripe_count = 2 ] ||
17734                 error "dir strpe_count $d != 2 after migration."
17735
17736         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17737         [ $stripe_count = 2 ] ||
17738                 error "file strpe_count $d != 2 after migration."
17739
17740         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17741 }
17742 run_test 230b "migrate directory"
17743
17744 test_230c() {
17745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17746         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17747         remote_mds_nodsh && skip "remote MDS with nodsh"
17748         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17749                 skip "Need MDS version at least 2.11.52"
17750
17751         local MDTIDX=1
17752         local total=3
17753         local mdt_index
17754         local file
17755         local migrate_dir=$DIR/$tdir/migrate_dir
17756
17757         #If migrating directory fails in the middle, all entries of
17758         #the directory is still accessiable.
17759         test_mkdir $DIR/$tdir
17760         test_mkdir -i0 -c1 $migrate_dir
17761         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17762         stat $migrate_dir
17763         createmany -o $migrate_dir/f $total ||
17764                 error "create files under ${migrate_dir} failed"
17765
17766         # fail after migrating top dir, and this will fail only once, so the
17767         # first sub file migration will fail (currently f3), others succeed.
17768         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17769         do_facet mds1 lctl set_param fail_loc=0x1801
17770         local t=$(ls $migrate_dir | wc -l)
17771         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17772                 error "migrate should fail"
17773         local u=$(ls $migrate_dir | wc -l)
17774         [ "$u" == "$t" ] || error "$u != $t during migration"
17775
17776         # add new dir/file should succeed
17777         mkdir $migrate_dir/dir ||
17778                 error "mkdir failed under migrating directory"
17779         touch $migrate_dir/file ||
17780                 error "create file failed under migrating directory"
17781
17782         # add file with existing name should fail
17783         for file in $migrate_dir/f*; do
17784                 stat $file > /dev/null || error "stat $file failed"
17785                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17786                         error "open(O_CREAT|O_EXCL) $file should fail"
17787                 $MULTIOP $file m && error "create $file should fail"
17788                 touch $DIR/$tdir/remote_dir/$tfile ||
17789                         error "touch $tfile failed"
17790                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17791                         error "link $file should fail"
17792                 mdt_index=$($LFS getstripe -m $file)
17793                 if [ $mdt_index == 0 ]; then
17794                         # file failed to migrate is not allowed to rename to
17795                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17796                                 error "rename to $file should fail"
17797                 else
17798                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17799                                 error "rename to $file failed"
17800                 fi
17801                 echo hello >> $file || error "write $file failed"
17802         done
17803
17804         # resume migration with different options should fail
17805         $LFS migrate -m 0 $migrate_dir &&
17806                 error "migrate -m 0 $migrate_dir should fail"
17807
17808         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17809                 error "migrate -c 2 $migrate_dir should fail"
17810
17811         # resume migration should succeed
17812         $LFS migrate -m $MDTIDX $migrate_dir ||
17813                 error "migrate $migrate_dir failed"
17814
17815         echo "Finish migration, then checking.."
17816         for file in $(find $migrate_dir); do
17817                 mdt_index=$($LFS getstripe -m $file)
17818                 [ $mdt_index == $MDTIDX ] ||
17819                         error "$file is not on MDT${MDTIDX}"
17820         done
17821
17822         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17823 }
17824 run_test 230c "check directory accessiblity if migration failed"
17825
17826 test_230d() {
17827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17828         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17829         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17830                 skip "Need MDS version at least 2.11.52"
17831         # LU-11235
17832         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17833
17834         local migrate_dir=$DIR/$tdir/migrate_dir
17835         local old_index
17836         local new_index
17837         local old_count
17838         local new_count
17839         local new_hash
17840         local mdt_index
17841         local i
17842         local j
17843
17844         old_index=$((RANDOM % MDSCOUNT))
17845         old_count=$((MDSCOUNT - old_index))
17846         new_index=$((RANDOM % MDSCOUNT))
17847         new_count=$((MDSCOUNT - new_index))
17848         new_hash=1 # for all_char
17849
17850         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17851         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17852
17853         test_mkdir $DIR/$tdir
17854         test_mkdir -i $old_index -c $old_count $migrate_dir
17855
17856         for ((i=0; i<100; i++)); do
17857                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17858                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17859                         error "create files under remote dir failed $i"
17860         done
17861
17862         echo -n "Migrate from MDT$old_index "
17863         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17864         echo -n "to MDT$new_index"
17865         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17866         echo
17867
17868         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17869         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17870                 error "migrate remote dir error"
17871
17872         echo "Finish migration, then checking.."
17873         for file in $(find $migrate_dir); do
17874                 mdt_index=$($LFS getstripe -m $file)
17875                 if [ $mdt_index -lt $new_index ] ||
17876                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17877                         error "$file is on MDT$mdt_index"
17878                 fi
17879         done
17880
17881         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17882 }
17883 run_test 230d "check migrate big directory"
17884
17885 test_230e() {
17886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17887         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17888         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17889                 skip "Need MDS version at least 2.11.52"
17890
17891         local i
17892         local j
17893         local a_fid
17894         local b_fid
17895
17896         mkdir -p $DIR/$tdir
17897         mkdir $DIR/$tdir/migrate_dir
17898         mkdir $DIR/$tdir/other_dir
17899         touch $DIR/$tdir/migrate_dir/a
17900         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17901         ls $DIR/$tdir/other_dir
17902
17903         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17904                 error "migrate dir fails"
17905
17906         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17907         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17908
17909         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17910         [ $mdt_index == 0 ] || error "a is not on MDT0"
17911
17912         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
17913                 error "migrate dir fails"
17914
17915         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
17916         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
17917
17918         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17919         [ $mdt_index == 1 ] || error "a is not on MDT1"
17920
17921         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
17922         [ $mdt_index == 1 ] || error "b is not on MDT1"
17923
17924         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17925         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
17926
17927         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
17928
17929         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17930 }
17931 run_test 230e "migrate mulitple local link files"
17932
17933 test_230f() {
17934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17935         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17936         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17937                 skip "Need MDS version at least 2.11.52"
17938
17939         local a_fid
17940         local ln_fid
17941
17942         mkdir -p $DIR/$tdir
17943         mkdir $DIR/$tdir/migrate_dir
17944         $LFS mkdir -i1 $DIR/$tdir/other_dir
17945         touch $DIR/$tdir/migrate_dir/a
17946         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
17947         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
17948         ls $DIR/$tdir/other_dir
17949
17950         # a should be migrated to MDT1, since no other links on MDT0
17951         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17952                 error "#1 migrate dir fails"
17953         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17954         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17955         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17956         [ $mdt_index == 1 ] || error "a is not on MDT1"
17957
17958         # a should stay on MDT1, because it is a mulitple link file
17959         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17960                 error "#2 migrate dir fails"
17961         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17962         [ $mdt_index == 1 ] || error "a is not on MDT1"
17963
17964         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17965                 error "#3 migrate dir fails"
17966
17967         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17968         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
17969         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
17970
17971         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
17972         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
17973
17974         # a should be migrated to MDT0, since no other links on MDT1
17975         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17976                 error "#4 migrate dir fails"
17977         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17978         [ $mdt_index == 0 ] || error "a is not on MDT0"
17979
17980         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17981 }
17982 run_test 230f "migrate mulitple remote link files"
17983
17984 test_230g() {
17985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17986         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17987         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17988                 skip "Need MDS version at least 2.11.52"
17989
17990         mkdir -p $DIR/$tdir/migrate_dir
17991
17992         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
17993                 error "migrating dir to non-exist MDT succeeds"
17994         true
17995 }
17996 run_test 230g "migrate dir to non-exist MDT"
17997
17998 test_230h() {
17999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18000         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18001         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18002                 skip "Need MDS version at least 2.11.52"
18003
18004         local mdt_index
18005
18006         mkdir -p $DIR/$tdir/migrate_dir
18007
18008         $LFS migrate -m1 $DIR &&
18009                 error "migrating mountpoint1 should fail"
18010
18011         $LFS migrate -m1 $DIR/$tdir/.. &&
18012                 error "migrating mountpoint2 should fail"
18013
18014         # same as mv
18015         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18016                 error "migrating $tdir/migrate_dir/.. should fail"
18017
18018         true
18019 }
18020 run_test 230h "migrate .. and root"
18021
18022 test_230i() {
18023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18024         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18025         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18026                 skip "Need MDS version at least 2.11.52"
18027
18028         mkdir -p $DIR/$tdir/migrate_dir
18029
18030         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18031                 error "migration fails with a tailing slash"
18032
18033         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18034                 error "migration fails with two tailing slashes"
18035 }
18036 run_test 230i "lfs migrate -m tolerates trailing slashes"
18037
18038 test_230j() {
18039         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18040         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18041                 skip "Need MDS version at least 2.11.52"
18042
18043         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18044         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18045                 error "create $tfile failed"
18046         cat /etc/passwd > $DIR/$tdir/$tfile
18047
18048         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18049
18050         cmp /etc/passwd $DIR/$tdir/$tfile ||
18051                 error "DoM file mismatch after migration"
18052 }
18053 run_test 230j "DoM file data not changed after dir migration"
18054
18055 test_230k() {
18056         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18057         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18058                 skip "Need MDS version at least 2.11.56"
18059
18060         local total=20
18061         local files_on_starting_mdt=0
18062
18063         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18064         $LFS getdirstripe $DIR/$tdir
18065         for i in $(seq $total); do
18066                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18067                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18068                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18069         done
18070
18071         echo "$files_on_starting_mdt files on MDT0"
18072
18073         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18074         $LFS getdirstripe $DIR/$tdir
18075
18076         files_on_starting_mdt=0
18077         for i in $(seq $total); do
18078                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18079                         error "file $tfile.$i mismatch after migration"
18080                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18081                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18082         done
18083
18084         echo "$files_on_starting_mdt files on MDT1 after migration"
18085         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18086
18087         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18088         $LFS getdirstripe $DIR/$tdir
18089
18090         files_on_starting_mdt=0
18091         for i in $(seq $total); do
18092                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18093                         error "file $tfile.$i mismatch after 2nd migration"
18094                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18095                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18096         done
18097
18098         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18099         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18100
18101         true
18102 }
18103 run_test 230k "file data not changed after dir migration"
18104
18105 test_230l() {
18106         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18107         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18108                 skip "Need MDS version at least 2.11.56"
18109
18110         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18111         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18112                 error "create files under remote dir failed $i"
18113         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18114 }
18115 run_test 230l "readdir between MDTs won't crash"
18116
18117 test_230m() {
18118         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18119         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18120                 skip "Need MDS version at least 2.11.56"
18121
18122         local MDTIDX=1
18123         local mig_dir=$DIR/$tdir/migrate_dir
18124         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18125         local shortstr="b"
18126         local val
18127
18128         echo "Creating files and dirs with xattrs"
18129         test_mkdir $DIR/$tdir
18130         test_mkdir -i0 -c1 $mig_dir
18131         mkdir $mig_dir/dir
18132         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18133                 error "cannot set xattr attr1 on dir"
18134         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18135                 error "cannot set xattr attr2 on dir"
18136         touch $mig_dir/dir/f0
18137         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18138                 error "cannot set xattr attr1 on file"
18139         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18140                 error "cannot set xattr attr2 on file"
18141         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18142         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18143         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18144         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18145         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18146         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18147         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18148         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18149         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18150
18151         echo "Migrating to MDT1"
18152         $LFS migrate -m $MDTIDX $mig_dir ||
18153                 error "fails on migrating dir to MDT1"
18154
18155         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18156         echo "Checking xattrs"
18157         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18158         [ "$val" = $longstr ] ||
18159                 error "expecting xattr1 $longstr on dir, found $val"
18160         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18161         [ "$val" = $shortstr ] ||
18162                 error "expecting xattr2 $shortstr on dir, found $val"
18163         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18164         [ "$val" = $longstr ] ||
18165                 error "expecting xattr1 $longstr on file, found $val"
18166         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18167         [ "$val" = $shortstr ] ||
18168                 error "expecting xattr2 $shortstr on file, found $val"
18169 }
18170 run_test 230m "xattrs not changed after dir migration"
18171
18172 test_230n() {
18173         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18174         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18175                 skip "Need MDS version at least 2.13.53"
18176
18177         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18178         cat /etc/hosts > $DIR/$tdir/$tfile
18179         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18180         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18181
18182         cmp /etc/hosts $DIR/$tdir/$tfile ||
18183                 error "File data mismatch after migration"
18184 }
18185 run_test 230n "Dir migration with mirrored file"
18186
18187 test_230o() {
18188         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18189         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18190                 skip "Need MDS version at least 2.13.52"
18191
18192         local mdts=$(comma_list $(mdts_nodes))
18193         local timeout=100
18194
18195         local restripe_status
18196         local delta
18197         local i
18198         local j
18199
18200         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18201
18202         # in case "crush" hash type is not set
18203         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18204
18205         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18206                            mdt.*MDT0000.enable_dir_restripe)
18207         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18208         stack_trap "do_nodes $mdts $LCTL set_param \
18209                     mdt.*.enable_dir_restripe=$restripe_status"
18210
18211         mkdir $DIR/$tdir
18212         createmany -m $DIR/$tdir/f 100 ||
18213                 error "create files under remote dir failed $i"
18214         createmany -d $DIR/$tdir/d 100 ||
18215                 error "create dirs under remote dir failed $i"
18216
18217         for i in $(seq 2 $MDSCOUNT); do
18218                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18219                 $LFS setdirstripe -c $i $DIR/$tdir ||
18220                         error "split -c $i $tdir failed"
18221                 wait_update $HOSTNAME \
18222                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18223                         error "dir split not finished"
18224                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18225                         awk '/migrate/ {sum += $2} END { print sum }')
18226                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18227                 # delta is around total_files/stripe_count
18228                 [ $delta -lt $((200 /(i - 1))) ] ||
18229                         error "$delta files migrated"
18230         done
18231 }
18232 run_test 230o "dir split"
18233
18234 test_230p() {
18235         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18236         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18237                 skip "Need MDS version at least 2.13.52"
18238
18239         local mdts=$(comma_list $(mdts_nodes))
18240         local timeout=100
18241
18242         local restripe_status
18243         local delta
18244         local i
18245         local j
18246
18247         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18248
18249         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18250
18251         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18252                            mdt.*MDT0000.enable_dir_restripe)
18253         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18254         stack_trap "do_nodes $mdts $LCTL set_param \
18255                     mdt.*.enable_dir_restripe=$restripe_status"
18256
18257         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18258         createmany -m $DIR/$tdir/f 100 ||
18259                 error "create files under remote dir failed $i"
18260         createmany -d $DIR/$tdir/d 100 ||
18261                 error "create dirs under remote dir failed $i"
18262
18263         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18264                 local mdt_hash="crush"
18265
18266                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18267                 $LFS setdirstripe -c $i $DIR/$tdir ||
18268                         error "split -c $i $tdir failed"
18269                 [ $i -eq 1 ] && mdt_hash="none"
18270                 wait_update $HOSTNAME \
18271                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18272                         error "dir merge not finished"
18273                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18274                         awk '/migrate/ {sum += $2} END { print sum }')
18275                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18276                 # delta is around total_files/stripe_count
18277                 [ $delta -lt $((200 / i)) ] ||
18278                         error "$delta files migrated"
18279         done
18280 }
18281 run_test 230p "dir merge"
18282
18283 test_230q() {
18284         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18285         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18286                 skip "Need MDS version at least 2.13.52"
18287
18288         local mdts=$(comma_list $(mdts_nodes))
18289         local saved_threshold=$(do_facet mds1 \
18290                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18291         local saved_delta=$(do_facet mds1 \
18292                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18293         local threshold=100
18294         local delta=2
18295         local total=0
18296         local stripe_count=0
18297         local stripe_index
18298         local nr_files
18299
18300         stack_trap "do_nodes $mdts $LCTL set_param \
18301                     mdt.*.dir_split_count=$saved_threshold"
18302         stack_trap "do_nodes $mdts $LCTL set_param \
18303                     mdt.*.dir_split_delta=$saved_delta"
18304         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18305         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18306         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18307         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18308         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18309         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18310
18311         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18312         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18313
18314         while [ $stripe_count -lt $MDSCOUNT ]; do
18315                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18316                         error "create sub files failed"
18317                 stat $DIR/$tdir > /dev/null
18318                 total=$((total + threshold * 3 / 2))
18319                 stripe_count=$((stripe_count + delta))
18320                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18321
18322                 wait_update $HOSTNAME \
18323                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18324                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18325
18326                 wait_update $HOSTNAME \
18327                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18328                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18329
18330                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18331                            grep -w $stripe_index | wc -l)
18332                 echo "$nr_files files on MDT$stripe_index after split"
18333                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18334                         error "$nr_files files on MDT$stripe_index after split"
18335
18336                 nr_files=$(ls $DIR/$tdir | wc -w)
18337                 [ $nr_files -eq $total ] ||
18338                         error "total sub files $nr_files != $total"
18339         done
18340 }
18341 run_test 230q "dir auto split"
18342
18343 test_230r() {
18344         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18345         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18346         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18347                 skip "Need MDS version at least 2.13.54"
18348
18349         # maximum amount of local locks:
18350         # parent striped dir - 2 locks
18351         # new stripe in parent to migrate to - 1 lock
18352         # source and target - 2 locks
18353         # Total 5 locks for regular file
18354         mkdir -p $DIR/$tdir
18355         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18356         touch $DIR/$tdir/dir1/eee
18357
18358         # create 4 hardlink for 4 more locks
18359         # Total: 9 locks > RS_MAX_LOCKS (8)
18360         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18361         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18362         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18363         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18364         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18365         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18366         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18367         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18368
18369         cancel_lru_locks mdc
18370
18371         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18372                 error "migrate dir fails"
18373
18374         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18375 }
18376 run_test 230r "migrate with too many local locks"
18377
18378 test_231a()
18379 {
18380         # For simplicity this test assumes that max_pages_per_rpc
18381         # is the same across all OSCs
18382         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18383         local bulk_size=$((max_pages * PAGE_SIZE))
18384         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18385                                        head -n 1)
18386
18387         mkdir -p $DIR/$tdir
18388         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18389                 error "failed to set stripe with -S ${brw_size}M option"
18390
18391         # clear the OSC stats
18392         $LCTL set_param osc.*.stats=0 &>/dev/null
18393         stop_writeback
18394
18395         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18396         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18397                 oflag=direct &>/dev/null || error "dd failed"
18398
18399         sync; sleep 1; sync # just to be safe
18400         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18401         if [ x$nrpcs != "x1" ]; then
18402                 $LCTL get_param osc.*.stats
18403                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18404         fi
18405
18406         start_writeback
18407         # Drop the OSC cache, otherwise we will read from it
18408         cancel_lru_locks osc
18409
18410         # clear the OSC stats
18411         $LCTL set_param osc.*.stats=0 &>/dev/null
18412
18413         # Client reads $bulk_size.
18414         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18415                 iflag=direct &>/dev/null || error "dd failed"
18416
18417         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18418         if [ x$nrpcs != "x1" ]; then
18419                 $LCTL get_param osc.*.stats
18420                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18421         fi
18422 }
18423 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18424
18425 test_231b() {
18426         mkdir -p $DIR/$tdir
18427         local i
18428         for i in {0..1023}; do
18429                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18430                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18431                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18432         done
18433         sync
18434 }
18435 run_test 231b "must not assert on fully utilized OST request buffer"
18436
18437 test_232a() {
18438         mkdir -p $DIR/$tdir
18439         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18440
18441         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18442         do_facet ost1 $LCTL set_param fail_loc=0x31c
18443
18444         # ignore dd failure
18445         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18446
18447         do_facet ost1 $LCTL set_param fail_loc=0
18448         umount_client $MOUNT || error "umount failed"
18449         mount_client $MOUNT || error "mount failed"
18450         stop ost1 || error "cannot stop ost1"
18451         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18452 }
18453 run_test 232a "failed lock should not block umount"
18454
18455 test_232b() {
18456         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18457                 skip "Need MDS version at least 2.10.58"
18458
18459         mkdir -p $DIR/$tdir
18460         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18461         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18462         sync
18463         cancel_lru_locks osc
18464
18465         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18466         do_facet ost1 $LCTL set_param fail_loc=0x31c
18467
18468         # ignore failure
18469         $LFS data_version $DIR/$tdir/$tfile || true
18470
18471         do_facet ost1 $LCTL set_param fail_loc=0
18472         umount_client $MOUNT || error "umount failed"
18473         mount_client $MOUNT || error "mount failed"
18474         stop ost1 || error "cannot stop ost1"
18475         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18476 }
18477 run_test 232b "failed data version lock should not block umount"
18478
18479 test_233a() {
18480         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18481                 skip "Need MDS version at least 2.3.64"
18482         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18483
18484         local fid=$($LFS path2fid $MOUNT)
18485
18486         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18487                 error "cannot access $MOUNT using its FID '$fid'"
18488 }
18489 run_test 233a "checking that OBF of the FS root succeeds"
18490
18491 test_233b() {
18492         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18493                 skip "Need MDS version at least 2.5.90"
18494         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18495
18496         local fid=$($LFS path2fid $MOUNT/.lustre)
18497
18498         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18499                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18500
18501         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18502         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18503                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18504 }
18505 run_test 233b "checking that OBF of the FS .lustre succeeds"
18506
18507 test_234() {
18508         local p="$TMP/sanityN-$TESTNAME.parameters"
18509         save_lustre_params client "llite.*.xattr_cache" > $p
18510         lctl set_param llite.*.xattr_cache 1 ||
18511                 skip_env "xattr cache is not supported"
18512
18513         mkdir -p $DIR/$tdir || error "mkdir failed"
18514         touch $DIR/$tdir/$tfile || error "touch failed"
18515         # OBD_FAIL_LLITE_XATTR_ENOMEM
18516         $LCTL set_param fail_loc=0x1405
18517         getfattr -n user.attr $DIR/$tdir/$tfile &&
18518                 error "getfattr should have failed with ENOMEM"
18519         $LCTL set_param fail_loc=0x0
18520         rm -rf $DIR/$tdir
18521
18522         restore_lustre_params < $p
18523         rm -f $p
18524 }
18525 run_test 234 "xattr cache should not crash on ENOMEM"
18526
18527 test_235() {
18528         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18529                 skip "Need MDS version at least 2.4.52"
18530
18531         flock_deadlock $DIR/$tfile
18532         local RC=$?
18533         case $RC in
18534                 0)
18535                 ;;
18536                 124) error "process hangs on a deadlock"
18537                 ;;
18538                 *) error "error executing flock_deadlock $DIR/$tfile"
18539                 ;;
18540         esac
18541 }
18542 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18543
18544 #LU-2935
18545 test_236() {
18546         check_swap_layouts_support
18547
18548         local ref1=/etc/passwd
18549         local ref2=/etc/group
18550         local file1=$DIR/$tdir/f1
18551         local file2=$DIR/$tdir/f2
18552
18553         test_mkdir -c1 $DIR/$tdir
18554         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18555         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18556         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18557         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18558         local fd=$(free_fd)
18559         local cmd="exec $fd<>$file2"
18560         eval $cmd
18561         rm $file2
18562         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18563                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18564         cmd="exec $fd>&-"
18565         eval $cmd
18566         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18567
18568         #cleanup
18569         rm -rf $DIR/$tdir
18570 }
18571 run_test 236 "Layout swap on open unlinked file"
18572
18573 # LU-4659 linkea consistency
18574 test_238() {
18575         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18576                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18577                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18578                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18579
18580         touch $DIR/$tfile
18581         ln $DIR/$tfile $DIR/$tfile.lnk
18582         touch $DIR/$tfile.new
18583         mv $DIR/$tfile.new $DIR/$tfile
18584         local fid1=$($LFS path2fid $DIR/$tfile)
18585         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18586         local path1=$($LFS fid2path $FSNAME "$fid1")
18587         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18588         local path2=$($LFS fid2path $FSNAME "$fid2")
18589         [ $tfile.lnk == $path2 ] ||
18590                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18591         rm -f $DIR/$tfile*
18592 }
18593 run_test 238 "Verify linkea consistency"
18594
18595 test_239A() { # was test_239
18596         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18597                 skip "Need MDS version at least 2.5.60"
18598
18599         local list=$(comma_list $(mdts_nodes))
18600
18601         mkdir -p $DIR/$tdir
18602         createmany -o $DIR/$tdir/f- 5000
18603         unlinkmany $DIR/$tdir/f- 5000
18604         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18605                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18606         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18607                         osp.*MDT*.sync_in_flight" | calc_sum)
18608         [ "$changes" -eq 0 ] || error "$changes not synced"
18609 }
18610 run_test 239A "osp_sync test"
18611
18612 test_239a() { #LU-5297
18613         remote_mds_nodsh && skip "remote MDS with nodsh"
18614
18615         touch $DIR/$tfile
18616         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18617         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18618         chgrp $RUNAS_GID $DIR/$tfile
18619         wait_delete_completed
18620 }
18621 run_test 239a "process invalid osp sync record correctly"
18622
18623 test_239b() { #LU-5297
18624         remote_mds_nodsh && skip "remote MDS with nodsh"
18625
18626         touch $DIR/$tfile1
18627         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18628         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18629         chgrp $RUNAS_GID $DIR/$tfile1
18630         wait_delete_completed
18631         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18632         touch $DIR/$tfile2
18633         chgrp $RUNAS_GID $DIR/$tfile2
18634         wait_delete_completed
18635 }
18636 run_test 239b "process osp sync record with ENOMEM error correctly"
18637
18638 test_240() {
18639         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18640         remote_mds_nodsh && skip "remote MDS with nodsh"
18641
18642         mkdir -p $DIR/$tdir
18643
18644         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18645                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18646         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18647                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18648
18649         umount_client $MOUNT || error "umount failed"
18650         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18651         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18652         mount_client $MOUNT || error "failed to mount client"
18653
18654         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18655         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18656 }
18657 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18658
18659 test_241_bio() {
18660         local count=$1
18661         local bsize=$2
18662
18663         for LOOP in $(seq $count); do
18664                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18665                 cancel_lru_locks $OSC || true
18666         done
18667 }
18668
18669 test_241_dio() {
18670         local count=$1
18671         local bsize=$2
18672
18673         for LOOP in $(seq $1); do
18674                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18675                         2>/dev/null
18676         done
18677 }
18678
18679 test_241a() { # was test_241
18680         local bsize=$PAGE_SIZE
18681
18682         (( bsize < 40960 )) && bsize=40960
18683         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18684         ls -la $DIR/$tfile
18685         cancel_lru_locks $OSC
18686         test_241_bio 1000 $bsize &
18687         PID=$!
18688         test_241_dio 1000 $bsize
18689         wait $PID
18690 }
18691 run_test 241a "bio vs dio"
18692
18693 test_241b() {
18694         local bsize=$PAGE_SIZE
18695
18696         (( bsize < 40960 )) && bsize=40960
18697         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18698         ls -la $DIR/$tfile
18699         test_241_dio 1000 $bsize &
18700         PID=$!
18701         test_241_dio 1000 $bsize
18702         wait $PID
18703 }
18704 run_test 241b "dio vs dio"
18705
18706 test_242() {
18707         remote_mds_nodsh && skip "remote MDS with nodsh"
18708
18709         mkdir -p $DIR/$tdir
18710         touch $DIR/$tdir/$tfile
18711
18712         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18713         do_facet mds1 lctl set_param fail_loc=0x105
18714         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18715
18716         do_facet mds1 lctl set_param fail_loc=0
18717         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18718 }
18719 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18720
18721 test_243()
18722 {
18723         test_mkdir $DIR/$tdir
18724         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18725 }
18726 run_test 243 "various group lock tests"
18727
18728 test_244a()
18729 {
18730         test_mkdir $DIR/$tdir
18731         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18732         sendfile_grouplock $DIR/$tdir/$tfile || \
18733                 error "sendfile+grouplock failed"
18734         rm -rf $DIR/$tdir
18735 }
18736 run_test 244a "sendfile with group lock tests"
18737
18738 test_244b()
18739 {
18740         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18741
18742         local threads=50
18743         local size=$((1024*1024))
18744
18745         test_mkdir $DIR/$tdir
18746         for i in $(seq 1 $threads); do
18747                 local file=$DIR/$tdir/file_$((i / 10))
18748                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18749                 local pids[$i]=$!
18750         done
18751         for i in $(seq 1 $threads); do
18752                 wait ${pids[$i]}
18753         done
18754 }
18755 run_test 244b "multi-threaded write with group lock"
18756
18757 test_245() {
18758         local flagname="multi_mod_rpcs"
18759         local connect_data_name="max_mod_rpcs"
18760         local out
18761
18762         # check if multiple modify RPCs flag is set
18763         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18764                 grep "connect_flags:")
18765         echo "$out"
18766
18767         echo "$out" | grep -qw $flagname
18768         if [ $? -ne 0 ]; then
18769                 echo "connect flag $flagname is not set"
18770                 return
18771         fi
18772
18773         # check if multiple modify RPCs data is set
18774         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18775         echo "$out"
18776
18777         echo "$out" | grep -qw $connect_data_name ||
18778                 error "import should have connect data $connect_data_name"
18779 }
18780 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18781
18782 cleanup_247() {
18783         local submount=$1
18784
18785         trap 0
18786         umount_client $submount
18787         rmdir $submount
18788 }
18789
18790 test_247a() {
18791         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18792                 grep -q subtree ||
18793                 skip_env "Fileset feature is not supported"
18794
18795         local submount=${MOUNT}_$tdir
18796
18797         mkdir $MOUNT/$tdir
18798         mkdir -p $submount || error "mkdir $submount failed"
18799         FILESET="$FILESET/$tdir" mount_client $submount ||
18800                 error "mount $submount failed"
18801         trap "cleanup_247 $submount" EXIT
18802         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18803         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18804                 error "read $MOUNT/$tdir/$tfile failed"
18805         cleanup_247 $submount
18806 }
18807 run_test 247a "mount subdir as fileset"
18808
18809 test_247b() {
18810         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18811                 skip_env "Fileset feature is not supported"
18812
18813         local submount=${MOUNT}_$tdir
18814
18815         rm -rf $MOUNT/$tdir
18816         mkdir -p $submount || error "mkdir $submount failed"
18817         SKIP_FILESET=1
18818         FILESET="$FILESET/$tdir" mount_client $submount &&
18819                 error "mount $submount should fail"
18820         rmdir $submount
18821 }
18822 run_test 247b "mount subdir that dose not exist"
18823
18824 test_247c() {
18825         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18826                 skip_env "Fileset feature is not supported"
18827
18828         local submount=${MOUNT}_$tdir
18829
18830         mkdir -p $MOUNT/$tdir/dir1
18831         mkdir -p $submount || error "mkdir $submount failed"
18832         trap "cleanup_247 $submount" EXIT
18833         FILESET="$FILESET/$tdir" mount_client $submount ||
18834                 error "mount $submount failed"
18835         local fid=$($LFS path2fid $MOUNT/)
18836         $LFS fid2path $submount $fid && error "fid2path should fail"
18837         cleanup_247 $submount
18838 }
18839 run_test 247c "running fid2path outside subdirectory root"
18840
18841 test_247d() {
18842         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18843                 skip "Fileset feature is not supported"
18844
18845         local submount=${MOUNT}_$tdir
18846
18847         mkdir -p $MOUNT/$tdir/dir1
18848         mkdir -p $submount || error "mkdir $submount failed"
18849         FILESET="$FILESET/$tdir" mount_client $submount ||
18850                 error "mount $submount failed"
18851         trap "cleanup_247 $submount" EXIT
18852
18853         local td=$submount/dir1
18854         local fid=$($LFS path2fid $td)
18855         [ -z "$fid" ] && error "path2fid unable to get $td FID"
18856
18857         # check that we get the same pathname back
18858         local rootpath
18859         local found
18860         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
18861                 echo "$rootpath $fid"
18862                 found=$($LFS fid2path $rootpath "$fid")
18863                 [ -n "found" ] || error "fid2path should succeed"
18864                 [ "$found" == "$td" ] || error "fid2path $found != $td"
18865         done
18866         # check wrong root path format
18867         rootpath=$submount"_wrong"
18868         found=$($LFS fid2path $rootpath "$fid")
18869         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
18870
18871         cleanup_247 $submount
18872 }
18873 run_test 247d "running fid2path inside subdirectory root"
18874
18875 # LU-8037
18876 test_247e() {
18877         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18878                 grep -q subtree ||
18879                 skip "Fileset feature is not supported"
18880
18881         local submount=${MOUNT}_$tdir
18882
18883         mkdir $MOUNT/$tdir
18884         mkdir -p $submount || error "mkdir $submount failed"
18885         FILESET="$FILESET/.." mount_client $submount &&
18886                 error "mount $submount should fail"
18887         rmdir $submount
18888 }
18889 run_test 247e "mount .. as fileset"
18890
18891 test_247f() {
18892         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18893         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18894                 skip "Need at least version 2.13.52"
18895         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18896                 grep -q subtree ||
18897                 skip "Fileset feature is not supported"
18898
18899         mkdir $DIR/$tdir || error "mkdir $tdir failed"
18900         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
18901                 error "mkdir remote failed"
18902         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
18903         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
18904                 error "mkdir striped failed"
18905         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
18906
18907         local submount=${MOUNT}_$tdir
18908
18909         mkdir -p $submount || error "mkdir $submount failed"
18910
18911         local dir
18912         local fileset=$FILESET
18913
18914         for dir in $tdir/remote $tdir/remote/subdir \
18915                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
18916                 FILESET="$fileset/$dir" mount_client $submount ||
18917                         error "mount $dir failed"
18918                 umount_client $submount
18919         done
18920 }
18921 run_test 247f "mount striped or remote directory as fileset"
18922
18923 test_248a() {
18924         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
18925         [ -z "$fast_read_sav" ] && skip "no fast read support"
18926
18927         # create a large file for fast read verification
18928         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
18929
18930         # make sure the file is created correctly
18931         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
18932                 { rm -f $DIR/$tfile; skip "file creation error"; }
18933
18934         echo "Test 1: verify that fast read is 4 times faster on cache read"
18935
18936         # small read with fast read enabled
18937         $LCTL set_param -n llite.*.fast_read=1
18938         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18939                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18940                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18941         # small read with fast read disabled
18942         $LCTL set_param -n llite.*.fast_read=0
18943         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18944                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18945                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18946
18947         # verify that fast read is 4 times faster for cache read
18948         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
18949                 error_not_in_vm "fast read was not 4 times faster: " \
18950                            "$t_fast vs $t_slow"
18951
18952         echo "Test 2: verify the performance between big and small read"
18953         $LCTL set_param -n llite.*.fast_read=1
18954
18955         # 1k non-cache read
18956         cancel_lru_locks osc
18957         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18958                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18959                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18960
18961         # 1M non-cache read
18962         cancel_lru_locks osc
18963         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18964                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18965                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18966
18967         # verify that big IO is not 4 times faster than small IO
18968         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
18969                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
18970
18971         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
18972         rm -f $DIR/$tfile
18973 }
18974 run_test 248a "fast read verification"
18975
18976 test_248b() {
18977         # Default short_io_bytes=16384, try both smaller and larger sizes.
18978         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
18979         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
18980         echo "bs=53248 count=113 normal buffered write"
18981         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
18982                 error "dd of initial data file failed"
18983         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
18984
18985         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
18986         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
18987                 error "dd with sync normal writes failed"
18988         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
18989
18990         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
18991         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
18992                 error "dd with sync small writes failed"
18993         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
18994
18995         cancel_lru_locks osc
18996
18997         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
18998         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
18999         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19000         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19001                 iflag=direct || error "dd with O_DIRECT small read failed"
19002         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19003         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19004                 error "compare $TMP/$tfile.1 failed"
19005
19006         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19007         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19008
19009         # just to see what the maximum tunable value is, and test parsing
19010         echo "test invalid parameter 2MB"
19011         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19012                 error "too-large short_io_bytes allowed"
19013         echo "test maximum parameter 512KB"
19014         # if we can set a larger short_io_bytes, run test regardless of version
19015         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19016                 # older clients may not allow setting it this large, that's OK
19017                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19018                         skip "Need at least client version 2.13.50"
19019                 error "medium short_io_bytes failed"
19020         fi
19021         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19022         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19023
19024         echo "test large parameter 64KB"
19025         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19026         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19027
19028         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19029         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19030                 error "dd with sync large writes failed"
19031         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19032
19033         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19034         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19035         num=$((113 * 4096 / PAGE_SIZE))
19036         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19037         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19038                 error "dd with O_DIRECT large writes failed"
19039         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19040                 error "compare $DIR/$tfile.3 failed"
19041
19042         cancel_lru_locks osc
19043
19044         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19045         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19046                 error "dd with O_DIRECT large read failed"
19047         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19048                 error "compare $TMP/$tfile.2 failed"
19049
19050         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19051         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19052                 error "dd with O_DIRECT large read failed"
19053         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19054                 error "compare $TMP/$tfile.3 failed"
19055 }
19056 run_test 248b "test short_io read and write for both small and large sizes"
19057
19058 test_249() { # LU-7890
19059         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19060                 skip "Need at least version 2.8.54"
19061
19062         rm -f $DIR/$tfile
19063         $LFS setstripe -c 1 $DIR/$tfile
19064         # Offset 2T == 4k * 512M
19065         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19066                 error "dd to 2T offset failed"
19067 }
19068 run_test 249 "Write above 2T file size"
19069
19070 test_250() {
19071         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19072          && skip "no 16TB file size limit on ZFS"
19073
19074         $LFS setstripe -c 1 $DIR/$tfile
19075         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19076         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19077         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19078         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19079                 conv=notrunc,fsync && error "append succeeded"
19080         return 0
19081 }
19082 run_test 250 "Write above 16T limit"
19083
19084 test_251() {
19085         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19086
19087         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19088         #Skip once - writing the first stripe will succeed
19089         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19090         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19091                 error "short write happened"
19092
19093         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19094         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19095                 error "short read happened"
19096
19097         rm -f $DIR/$tfile
19098 }
19099 run_test 251 "Handling short read and write correctly"
19100
19101 test_252() {
19102         remote_mds_nodsh && skip "remote MDS with nodsh"
19103         remote_ost_nodsh && skip "remote OST with nodsh"
19104         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19105                 skip_env "ldiskfs only test"
19106         fi
19107
19108         local tgt
19109         local dev
19110         local out
19111         local uuid
19112         local num
19113         local gen
19114
19115         # check lr_reader on OST0000
19116         tgt=ost1
19117         dev=$(facet_device $tgt)
19118         out=$(do_facet $tgt $LR_READER $dev)
19119         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19120         echo "$out"
19121         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19122         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19123                 error "Invalid uuid returned by $LR_READER on target $tgt"
19124         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19125
19126         # check lr_reader -c on MDT0000
19127         tgt=mds1
19128         dev=$(facet_device $tgt)
19129         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19130                 skip "$LR_READER does not support additional options"
19131         fi
19132         out=$(do_facet $tgt $LR_READER -c $dev)
19133         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19134         echo "$out"
19135         num=$(echo "$out" | grep -c "mdtlov")
19136         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19137                 error "Invalid number of mdtlov clients returned by $LR_READER"
19138         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19139
19140         # check lr_reader -cr on MDT0000
19141         out=$(do_facet $tgt $LR_READER -cr $dev)
19142         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19143         echo "$out"
19144         echo "$out" | grep -q "^reply_data:$" ||
19145                 error "$LR_READER should have returned 'reply_data' section"
19146         num=$(echo "$out" | grep -c "client_generation")
19147         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19148 }
19149 run_test 252 "check lr_reader tool"
19150
19151 test_253() {
19152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19153         remote_mds_nodsh && skip "remote MDS with nodsh"
19154         remote_mgs_nodsh && skip "remote MGS with nodsh"
19155
19156         local ostidx=0
19157         local rc=0
19158         local ost_name=$(ostname_from_index $ostidx)
19159
19160         # on the mdt's osc
19161         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19162         do_facet $SINGLEMDS $LCTL get_param -n \
19163                 osp.$mdtosc_proc1.reserved_mb_high ||
19164                 skip  "remote MDS does not support reserved_mb_high"
19165
19166         rm -rf $DIR/$tdir
19167         wait_mds_ost_sync
19168         wait_delete_completed
19169         mkdir $DIR/$tdir
19170
19171         pool_add $TESTNAME || error "Pool creation failed"
19172         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19173
19174         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19175                 error "Setstripe failed"
19176
19177         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19178
19179         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19180                     grep "watermarks")
19181         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19182
19183         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19184                         osp.$mdtosc_proc1.prealloc_status)
19185         echo "prealloc_status $oa_status"
19186
19187         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19188                 error "File creation should fail"
19189
19190         #object allocation was stopped, but we still able to append files
19191         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19192                 oflag=append || error "Append failed"
19193
19194         rm -f $DIR/$tdir/$tfile.0
19195
19196         # For this test, we want to delete the files we created to go out of
19197         # space but leave the watermark, so we remain nearly out of space
19198         ost_watermarks_enospc_delete_files $tfile $ostidx
19199
19200         wait_delete_completed
19201
19202         sleep_maxage
19203
19204         for i in $(seq 10 12); do
19205                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19206                         2>/dev/null || error "File creation failed after rm"
19207         done
19208
19209         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19210                         osp.$mdtosc_proc1.prealloc_status)
19211         echo "prealloc_status $oa_status"
19212
19213         if (( oa_status != 0 )); then
19214                 error "Object allocation still disable after rm"
19215         fi
19216 }
19217 run_test 253 "Check object allocation limit"
19218
19219 test_254() {
19220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19221         remote_mds_nodsh && skip "remote MDS with nodsh"
19222         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19223                 skip "MDS does not support changelog_size"
19224
19225         local cl_user
19226         local MDT0=$(facet_svc $SINGLEMDS)
19227
19228         changelog_register || error "changelog_register failed"
19229
19230         changelog_clear 0 || error "changelog_clear failed"
19231
19232         local size1=$(do_facet $SINGLEMDS \
19233                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19234         echo "Changelog size $size1"
19235
19236         rm -rf $DIR/$tdir
19237         $LFS mkdir -i 0 $DIR/$tdir
19238         # change something
19239         mkdir -p $DIR/$tdir/pics/2008/zachy
19240         touch $DIR/$tdir/pics/2008/zachy/timestamp
19241         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19242         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19243         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19244         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19245         rm $DIR/$tdir/pics/desktop.jpg
19246
19247         local size2=$(do_facet $SINGLEMDS \
19248                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19249         echo "Changelog size after work $size2"
19250
19251         (( $size2 > $size1 )) ||
19252                 error "new Changelog size=$size2 less than old size=$size1"
19253 }
19254 run_test 254 "Check changelog size"
19255
19256 ladvise_no_type()
19257 {
19258         local type=$1
19259         local file=$2
19260
19261         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19262                 awk -F: '{print $2}' | grep $type > /dev/null
19263         if [ $? -ne 0 ]; then
19264                 return 0
19265         fi
19266         return 1
19267 }
19268
19269 ladvise_no_ioctl()
19270 {
19271         local file=$1
19272
19273         lfs ladvise -a willread $file > /dev/null 2>&1
19274         if [ $? -eq 0 ]; then
19275                 return 1
19276         fi
19277
19278         lfs ladvise -a willread $file 2>&1 |
19279                 grep "Inappropriate ioctl for device" > /dev/null
19280         if [ $? -eq 0 ]; then
19281                 return 0
19282         fi
19283         return 1
19284 }
19285
19286 percent() {
19287         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19288 }
19289
19290 # run a random read IO workload
19291 # usage: random_read_iops <filename> <filesize> <iosize>
19292 random_read_iops() {
19293         local file=$1
19294         local fsize=$2
19295         local iosize=${3:-4096}
19296
19297         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19298                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19299 }
19300
19301 drop_file_oss_cache() {
19302         local file="$1"
19303         local nodes="$2"
19304
19305         $LFS ladvise -a dontneed $file 2>/dev/null ||
19306                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19307 }
19308
19309 ladvise_willread_performance()
19310 {
19311         local repeat=10
19312         local average_origin=0
19313         local average_cache=0
19314         local average_ladvise=0
19315
19316         for ((i = 1; i <= $repeat; i++)); do
19317                 echo "Iter $i/$repeat: reading without willread hint"
19318                 cancel_lru_locks osc
19319                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19320                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19321                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19322                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19323
19324                 cancel_lru_locks osc
19325                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19326                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19327                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19328
19329                 cancel_lru_locks osc
19330                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19331                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19332                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19333                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19334                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19335         done
19336         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19337         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19338         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19339
19340         speedup_cache=$(percent $average_cache $average_origin)
19341         speedup_ladvise=$(percent $average_ladvise $average_origin)
19342
19343         echo "Average uncached read: $average_origin"
19344         echo "Average speedup with OSS cached read: " \
19345                 "$average_cache = +$speedup_cache%"
19346         echo "Average speedup with ladvise willread: " \
19347                 "$average_ladvise = +$speedup_ladvise%"
19348
19349         local lowest_speedup=20
19350         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19351                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19352                         "got $average_cache%. Skipping ladvise willread check."
19353                 return 0
19354         fi
19355
19356         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19357         # it is still good to run until then to exercise 'ladvise willread'
19358         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19359                 [ "$ost1_FSTYPE" = "zfs" ] &&
19360                 echo "osd-zfs does not support dontneed or drop_caches" &&
19361                 return 0
19362
19363         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19364         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
19365                 error_not_in_vm "Speedup with willread is less than " \
19366                         "$lowest_speedup%, got $average_ladvise%"
19367 }
19368
19369 test_255a() {
19370         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19371                 skip "lustre < 2.8.54 does not support ladvise "
19372         remote_ost_nodsh && skip "remote OST with nodsh"
19373
19374         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19375
19376         ladvise_no_type willread $DIR/$tfile &&
19377                 skip "willread ladvise is not supported"
19378
19379         ladvise_no_ioctl $DIR/$tfile &&
19380                 skip "ladvise ioctl is not supported"
19381
19382         local size_mb=100
19383         local size=$((size_mb * 1048576))
19384         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19385                 error "dd to $DIR/$tfile failed"
19386
19387         lfs ladvise -a willread $DIR/$tfile ||
19388                 error "Ladvise failed with no range argument"
19389
19390         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19391                 error "Ladvise failed with no -l or -e argument"
19392
19393         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19394                 error "Ladvise failed with only -e argument"
19395
19396         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19397                 error "Ladvise failed with only -l argument"
19398
19399         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19400                 error "End offset should not be smaller than start offset"
19401
19402         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19403                 error "End offset should not be equal to start offset"
19404
19405         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19406                 error "Ladvise failed with overflowing -s argument"
19407
19408         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19409                 error "Ladvise failed with overflowing -e argument"
19410
19411         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19412                 error "Ladvise failed with overflowing -l argument"
19413
19414         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19415                 error "Ladvise succeeded with conflicting -l and -e arguments"
19416
19417         echo "Synchronous ladvise should wait"
19418         local delay=4
19419 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19420         do_nodes $(comma_list $(osts_nodes)) \
19421                 $LCTL set_param fail_val=$delay fail_loc=0x237
19422
19423         local start_ts=$SECONDS
19424         lfs ladvise -a willread $DIR/$tfile ||
19425                 error "Ladvise failed with no range argument"
19426         local end_ts=$SECONDS
19427         local inteval_ts=$((end_ts - start_ts))
19428
19429         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19430                 error "Synchronous advice didn't wait reply"
19431         fi
19432
19433         echo "Asynchronous ladvise shouldn't wait"
19434         local start_ts=$SECONDS
19435         lfs ladvise -a willread -b $DIR/$tfile ||
19436                 error "Ladvise failed with no range argument"
19437         local end_ts=$SECONDS
19438         local inteval_ts=$((end_ts - start_ts))
19439
19440         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19441                 error "Asynchronous advice blocked"
19442         fi
19443
19444         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19445         ladvise_willread_performance
19446 }
19447 run_test 255a "check 'lfs ladvise -a willread'"
19448
19449 facet_meminfo() {
19450         local facet=$1
19451         local info=$2
19452
19453         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19454 }
19455
19456 test_255b() {
19457         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19458                 skip "lustre < 2.8.54 does not support ladvise "
19459         remote_ost_nodsh && skip "remote OST with nodsh"
19460
19461         lfs setstripe -c 1 -i 0 $DIR/$tfile
19462
19463         ladvise_no_type dontneed $DIR/$tfile &&
19464                 skip "dontneed ladvise is not supported"
19465
19466         ladvise_no_ioctl $DIR/$tfile &&
19467                 skip "ladvise ioctl is not supported"
19468
19469         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19470                 [ "$ost1_FSTYPE" = "zfs" ] &&
19471                 skip "zfs-osd does not support 'ladvise dontneed'"
19472
19473         local size_mb=100
19474         local size=$((size_mb * 1048576))
19475         # In order to prevent disturbance of other processes, only check 3/4
19476         # of the memory usage
19477         local kibibytes=$((size_mb * 1024 * 3 / 4))
19478
19479         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19480                 error "dd to $DIR/$tfile failed"
19481
19482         #force write to complete before dropping OST cache & checking memory
19483         sync
19484
19485         local total=$(facet_meminfo ost1 MemTotal)
19486         echo "Total memory: $total KiB"
19487
19488         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19489         local before_read=$(facet_meminfo ost1 Cached)
19490         echo "Cache used before read: $before_read KiB"
19491
19492         lfs ladvise -a willread $DIR/$tfile ||
19493                 error "Ladvise willread failed"
19494         local after_read=$(facet_meminfo ost1 Cached)
19495         echo "Cache used after read: $after_read KiB"
19496
19497         lfs ladvise -a dontneed $DIR/$tfile ||
19498                 error "Ladvise dontneed again failed"
19499         local no_read=$(facet_meminfo ost1 Cached)
19500         echo "Cache used after dontneed ladvise: $no_read KiB"
19501
19502         if [ $total -lt $((before_read + kibibytes)) ]; then
19503                 echo "Memory is too small, abort checking"
19504                 return 0
19505         fi
19506
19507         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19508                 error "Ladvise willread should use more memory" \
19509                         "than $kibibytes KiB"
19510         fi
19511
19512         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19513                 error "Ladvise dontneed should release more memory" \
19514                         "than $kibibytes KiB"
19515         fi
19516 }
19517 run_test 255b "check 'lfs ladvise -a dontneed'"
19518
19519 test_255c() {
19520         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19521                 skip "lustre < 2.10.50 does not support lockahead"
19522
19523         local count
19524         local new_count
19525         local difference
19526         local i
19527         local rc
19528
19529         test_mkdir -p $DIR/$tdir
19530         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19531
19532         #test 10 returns only success/failure
19533         i=10
19534         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19535         rc=$?
19536         if [ $rc -eq 255 ]; then
19537                 error "Ladvise test${i} failed, ${rc}"
19538         fi
19539
19540         #test 11 counts lock enqueue requests, all others count new locks
19541         i=11
19542         count=$(do_facet ost1 \
19543                 $LCTL get_param -n ost.OSS.ost.stats)
19544         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19545
19546         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19547         rc=$?
19548         if [ $rc -eq 255 ]; then
19549                 error "Ladvise test${i} failed, ${rc}"
19550         fi
19551
19552         new_count=$(do_facet ost1 \
19553                 $LCTL get_param -n ost.OSS.ost.stats)
19554         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19555                    awk '{ print $2 }')
19556
19557         difference="$((new_count - count))"
19558         if [ $difference -ne $rc ]; then
19559                 error "Ladvise test${i}, bad enqueue count, returned " \
19560                       "${rc}, actual ${difference}"
19561         fi
19562
19563         for i in $(seq 12 21); do
19564                 # If we do not do this, we run the risk of having too many
19565                 # locks and starting lock cancellation while we are checking
19566                 # lock counts.
19567                 cancel_lru_locks osc
19568
19569                 count=$($LCTL get_param -n \
19570                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19571
19572                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19573                 rc=$?
19574                 if [ $rc -eq 255 ]; then
19575                         error "Ladvise test ${i} failed, ${rc}"
19576                 fi
19577
19578                 new_count=$($LCTL get_param -n \
19579                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19580                 difference="$((new_count - count))"
19581
19582                 # Test 15 output is divided by 100 to map down to valid return
19583                 if [ $i -eq 15 ]; then
19584                         rc="$((rc * 100))"
19585                 fi
19586
19587                 if [ $difference -ne $rc ]; then
19588                         error "Ladvise test ${i}, bad lock count, returned " \
19589                               "${rc}, actual ${difference}"
19590                 fi
19591         done
19592
19593         #test 22 returns only success/failure
19594         i=22
19595         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19596         rc=$?
19597         if [ $rc -eq 255 ]; then
19598                 error "Ladvise test${i} failed, ${rc}"
19599         fi
19600 }
19601 run_test 255c "suite of ladvise lockahead tests"
19602
19603 test_256() {
19604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19605         remote_mds_nodsh && skip "remote MDS with nodsh"
19606         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19607         changelog_users $SINGLEMDS | grep "^cl" &&
19608                 skip "active changelog user"
19609
19610         local cl_user
19611         local cat_sl
19612         local mdt_dev
19613
19614         mdt_dev=$(mdsdevname 1)
19615         echo $mdt_dev
19616
19617         changelog_register || error "changelog_register failed"
19618
19619         rm -rf $DIR/$tdir
19620         mkdir -p $DIR/$tdir
19621
19622         changelog_clear 0 || error "changelog_clear failed"
19623
19624         # change something
19625         touch $DIR/$tdir/{1..10}
19626
19627         # stop the MDT
19628         stop $SINGLEMDS || error "Fail to stop MDT"
19629
19630         # remount the MDT
19631
19632         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19633
19634         #after mount new plainllog is used
19635         touch $DIR/$tdir/{11..19}
19636         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19637         stack_trap "rm -f $tmpfile"
19638         cat_sl=$(do_facet $SINGLEMDS "sync; \
19639                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19640                  llog_reader $tmpfile | grep -c type=1064553b")
19641         do_facet $SINGLEMDS llog_reader $tmpfile
19642
19643         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19644
19645         changelog_clear 0 || error "changelog_clear failed"
19646
19647         cat_sl=$(do_facet $SINGLEMDS "sync; \
19648                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19649                  llog_reader $tmpfile | grep -c type=1064553b")
19650
19651         if (( cat_sl == 2 )); then
19652                 error "Empty plain llog was not deleted from changelog catalog"
19653         elif (( cat_sl != 1 )); then
19654                 error "Active plain llog shouldn't be deleted from catalog"
19655         fi
19656 }
19657 run_test 256 "Check llog delete for empty and not full state"
19658
19659 test_257() {
19660         remote_mds_nodsh && skip "remote MDS with nodsh"
19661         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19662                 skip "Need MDS version at least 2.8.55"
19663
19664         test_mkdir $DIR/$tdir
19665
19666         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19667                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19668         stat $DIR/$tdir
19669
19670 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19671         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19672         local facet=mds$((mdtidx + 1))
19673         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19674         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19675
19676         stop $facet || error "stop MDS failed"
19677         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19678                 error "start MDS fail"
19679         wait_recovery_complete $facet
19680 }
19681 run_test 257 "xattr locks are not lost"
19682
19683 # Verify we take the i_mutex when security requires it
19684 test_258a() {
19685 #define OBD_FAIL_IMUTEX_SEC 0x141c
19686         $LCTL set_param fail_loc=0x141c
19687         touch $DIR/$tfile
19688         chmod u+s $DIR/$tfile
19689         chmod a+rwx $DIR/$tfile
19690         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19691         RC=$?
19692         if [ $RC -ne 0 ]; then
19693                 error "error, failed to take i_mutex, rc=$?"
19694         fi
19695         rm -f $DIR/$tfile
19696 }
19697 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19698
19699 # Verify we do NOT take the i_mutex in the normal case
19700 test_258b() {
19701 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19702         $LCTL set_param fail_loc=0x141d
19703         touch $DIR/$tfile
19704         chmod a+rwx $DIR
19705         chmod a+rw $DIR/$tfile
19706         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19707         RC=$?
19708         if [ $RC -ne 0 ]; then
19709                 error "error, took i_mutex unnecessarily, rc=$?"
19710         fi
19711         rm -f $DIR/$tfile
19712
19713 }
19714 run_test 258b "verify i_mutex security behavior"
19715
19716 test_259() {
19717         local file=$DIR/$tfile
19718         local before
19719         local after
19720
19721         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19722
19723         stack_trap "rm -f $file" EXIT
19724
19725         wait_delete_completed
19726         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19727         echo "before: $before"
19728
19729         $LFS setstripe -i 0 -c 1 $file
19730         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19731         sync_all_data
19732         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19733         echo "after write: $after"
19734
19735 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19736         do_facet ost1 $LCTL set_param fail_loc=0x2301
19737         $TRUNCATE $file 0
19738         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19739         echo "after truncate: $after"
19740
19741         stop ost1
19742         do_facet ost1 $LCTL set_param fail_loc=0
19743         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19744         sleep 2
19745         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19746         echo "after restart: $after"
19747         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19748                 error "missing truncate?"
19749
19750         return 0
19751 }
19752 run_test 259 "crash at delayed truncate"
19753
19754 test_260() {
19755 #define OBD_FAIL_MDC_CLOSE               0x806
19756         $LCTL set_param fail_loc=0x80000806
19757         touch $DIR/$tfile
19758
19759 }
19760 run_test 260 "Check mdc_close fail"
19761
19762 ### Data-on-MDT sanity tests ###
19763 test_270a() {
19764         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19765                 skip "Need MDS version at least 2.10.55 for DoM"
19766
19767         # create DoM file
19768         local dom=$DIR/$tdir/dom_file
19769         local tmp=$DIR/$tdir/tmp_file
19770
19771         mkdir -p $DIR/$tdir
19772
19773         # basic checks for DoM component creation
19774         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19775                 error "Can set MDT layout to non-first entry"
19776
19777         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19778                 error "Can define multiple entries as MDT layout"
19779
19780         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19781
19782         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19783         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19784         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19785
19786         local mdtidx=$($LFS getstripe -m $dom)
19787         local mdtname=MDT$(printf %04x $mdtidx)
19788         local facet=mds$((mdtidx + 1))
19789         local space_check=1
19790
19791         # Skip free space checks with ZFS
19792         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19793
19794         # write
19795         sync
19796         local size_tmp=$((65536 * 3))
19797         local mdtfree1=$(do_facet $facet \
19798                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19799
19800         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19801         # check also direct IO along write
19802         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19803         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19804         sync
19805         cmp $tmp $dom || error "file data is different"
19806         [ $(stat -c%s $dom) == $size_tmp ] ||
19807                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19808         if [ $space_check == 1 ]; then
19809                 local mdtfree2=$(do_facet $facet \
19810                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19811
19812                 # increase in usage from by $size_tmp
19813                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19814                         error "MDT free space wrong after write: " \
19815                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19816         fi
19817
19818         # truncate
19819         local size_dom=10000
19820
19821         $TRUNCATE $dom $size_dom
19822         [ $(stat -c%s $dom) == $size_dom ] ||
19823                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19824         if [ $space_check == 1 ]; then
19825                 mdtfree1=$(do_facet $facet \
19826                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19827                 # decrease in usage from $size_tmp to new $size_dom
19828                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19829                   $(((size_tmp - size_dom) / 1024)) ] ||
19830                         error "MDT free space is wrong after truncate: " \
19831                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19832         fi
19833
19834         # append
19835         cat $tmp >> $dom
19836         sync
19837         size_dom=$((size_dom + size_tmp))
19838         [ $(stat -c%s $dom) == $size_dom ] ||
19839                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19840         if [ $space_check == 1 ]; then
19841                 mdtfree2=$(do_facet $facet \
19842                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19843                 # increase in usage by $size_tmp from previous
19844                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19845                         error "MDT free space is wrong after append: " \
19846                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19847         fi
19848
19849         # delete
19850         rm $dom
19851         if [ $space_check == 1 ]; then
19852                 mdtfree1=$(do_facet $facet \
19853                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19854                 # decrease in usage by $size_dom from previous
19855                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
19856                         error "MDT free space is wrong after removal: " \
19857                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
19858         fi
19859
19860         # combined striping
19861         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
19862                 error "Can't create DoM + OST striping"
19863
19864         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
19865         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19866         # check also direct IO along write
19867         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19868         sync
19869         cmp $tmp $dom || error "file data is different"
19870         [ $(stat -c%s $dom) == $size_tmp ] ||
19871                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19872         rm $dom $tmp
19873
19874         return 0
19875 }
19876 run_test 270a "DoM: basic functionality tests"
19877
19878 test_270b() {
19879         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19880                 skip "Need MDS version at least 2.10.55"
19881
19882         local dom=$DIR/$tdir/dom_file
19883         local max_size=1048576
19884
19885         mkdir -p $DIR/$tdir
19886         $LFS setstripe -E $max_size -L mdt $dom
19887
19888         # truncate over the limit
19889         $TRUNCATE $dom $(($max_size + 1)) &&
19890                 error "successful truncate over the maximum size"
19891         # write over the limit
19892         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
19893                 error "successful write over the maximum size"
19894         # append over the limit
19895         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
19896         echo "12345" >> $dom && error "successful append over the maximum size"
19897         rm $dom
19898
19899         return 0
19900 }
19901 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
19902
19903 test_270c() {
19904         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19905                 skip "Need MDS version at least 2.10.55"
19906
19907         mkdir -p $DIR/$tdir
19908         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19909
19910         # check files inherit DoM EA
19911         touch $DIR/$tdir/first
19912         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
19913                 error "bad pattern"
19914         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
19915                 error "bad stripe count"
19916         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
19917                 error "bad stripe size"
19918
19919         # check directory inherits DoM EA and uses it as default
19920         mkdir $DIR/$tdir/subdir
19921         touch $DIR/$tdir/subdir/second
19922         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
19923                 error "bad pattern in sub-directory"
19924         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
19925                 error "bad stripe count in sub-directory"
19926         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
19927                 error "bad stripe size in sub-directory"
19928         return 0
19929 }
19930 run_test 270c "DoM: DoM EA inheritance tests"
19931
19932 test_270d() {
19933         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19934                 skip "Need MDS version at least 2.10.55"
19935
19936         mkdir -p $DIR/$tdir
19937         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19938
19939         # inherit default DoM striping
19940         mkdir $DIR/$tdir/subdir
19941         touch $DIR/$tdir/subdir/f1
19942
19943         # change default directory striping
19944         $LFS setstripe -c 1 $DIR/$tdir/subdir
19945         touch $DIR/$tdir/subdir/f2
19946         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
19947                 error "wrong default striping in file 2"
19948         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
19949                 error "bad pattern in file 2"
19950         return 0
19951 }
19952 run_test 270d "DoM: change striping from DoM to RAID0"
19953
19954 test_270e() {
19955         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19956                 skip "Need MDS version at least 2.10.55"
19957
19958         mkdir -p $DIR/$tdir/dom
19959         mkdir -p $DIR/$tdir/norm
19960         DOMFILES=20
19961         NORMFILES=10
19962         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
19963         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
19964
19965         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
19966         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
19967
19968         # find DoM files by layout
19969         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
19970         [ $NUM -eq  $DOMFILES ] ||
19971                 error "lfs find -L: found $NUM, expected $DOMFILES"
19972         echo "Test 1: lfs find 20 DOM files by layout: OK"
19973
19974         # there should be 1 dir with default DOM striping
19975         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
19976         [ $NUM -eq  1 ] ||
19977                 error "lfs find -L: found $NUM, expected 1 dir"
19978         echo "Test 2: lfs find 1 DOM dir by layout: OK"
19979
19980         # find DoM files by stripe size
19981         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
19982         [ $NUM -eq  $DOMFILES ] ||
19983                 error "lfs find -S: found $NUM, expected $DOMFILES"
19984         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
19985
19986         # find files by stripe offset except DoM files
19987         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
19988         [ $NUM -eq  $NORMFILES ] ||
19989                 error "lfs find -i: found $NUM, expected $NORMFILES"
19990         echo "Test 5: lfs find no DOM files by stripe index: OK"
19991         return 0
19992 }
19993 run_test 270e "DoM: lfs find with DoM files test"
19994
19995 test_270f() {
19996         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19997                 skip "Need MDS version at least 2.10.55"
19998
19999         local mdtname=${FSNAME}-MDT0000-mdtlov
20000         local dom=$DIR/$tdir/dom_file
20001         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20002                                                 lod.$mdtname.dom_stripesize)
20003         local dom_limit=131072
20004
20005         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20006         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20007                                                 lod.$mdtname.dom_stripesize)
20008         [ ${dom_limit} -eq ${dom_current} ] ||
20009                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20010
20011         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20012         $LFS setstripe -d $DIR/$tdir
20013         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20014                 error "Can't set directory default striping"
20015
20016         # exceed maximum stripe size
20017         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20018                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20019         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20020                 error "Able to create DoM component size more than LOD limit"
20021
20022         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20023         dom_current=$(do_facet mds1 $LCTL get_param -n \
20024                                                 lod.$mdtname.dom_stripesize)
20025         [ 0 -eq ${dom_current} ] ||
20026                 error "Can't set zero DoM stripe limit"
20027         rm $dom
20028
20029         # attempt to create DoM file on server with disabled DoM should
20030         # remove DoM entry from layout and be succeed
20031         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20032                 error "Can't create DoM file (DoM is disabled)"
20033         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20034                 error "File has DoM component while DoM is disabled"
20035         rm $dom
20036
20037         # attempt to create DoM file with only DoM stripe should return error
20038         $LFS setstripe -E $dom_limit -L mdt $dom &&
20039                 error "Able to create DoM-only file while DoM is disabled"
20040
20041         # too low values to be aligned with smallest stripe size 64K
20042         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20043         dom_current=$(do_facet mds1 $LCTL get_param -n \
20044                                                 lod.$mdtname.dom_stripesize)
20045         [ 30000 -eq ${dom_current} ] &&
20046                 error "Can set too small DoM stripe limit"
20047
20048         # 64K is a minimal stripe size in Lustre, expect limit of that size
20049         [ 65536 -eq ${dom_current} ] ||
20050                 error "Limit is not set to 64K but ${dom_current}"
20051
20052         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20053         dom_current=$(do_facet mds1 $LCTL get_param -n \
20054                                                 lod.$mdtname.dom_stripesize)
20055         echo $dom_current
20056         [ 2147483648 -eq ${dom_current} ] &&
20057                 error "Can set too large DoM stripe limit"
20058
20059         do_facet mds1 $LCTL set_param -n \
20060                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20061         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20062                 error "Can't create DoM component size after limit change"
20063         do_facet mds1 $LCTL set_param -n \
20064                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20065         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20066                 error "Can't create DoM file after limit decrease"
20067         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20068                 error "Can create big DoM component after limit decrease"
20069         touch ${dom}_def ||
20070                 error "Can't create file with old default layout"
20071
20072         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20073         return 0
20074 }
20075 run_test 270f "DoM: maximum DoM stripe size checks"
20076
20077 test_270g() {
20078         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20079                 skip "Need MDS version at least 2.13.52"
20080         local dom=$DIR/$tdir/$tfile
20081
20082         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20083         local lodname=${FSNAME}-MDT0000-mdtlov
20084
20085         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20086         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20087         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20088         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20089
20090         local dom_limit=1024
20091         local dom_threshold="50%"
20092
20093         $LFS setstripe -d $DIR/$tdir
20094         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20095                 error "Can't set directory default striping"
20096
20097         do_facet mds1 $LCTL set_param -n \
20098                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20099         # set 0 threshold and create DOM file to change tunable stripesize
20100         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20101         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20102                 error "Failed to create $dom file"
20103         # now tunable dom_cur_stripesize should reach maximum
20104         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20105                                         lod.${lodname}.dom_stripesize_cur_kb)
20106         [[ $dom_current == $dom_limit ]] ||
20107                 error "Current DOM stripesize is not maximum"
20108         rm $dom
20109
20110         # set threshold for further tests
20111         do_facet mds1 $LCTL set_param -n \
20112                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20113         echo "DOM threshold is $dom_threshold free space"
20114         local dom_def
20115         local dom_set
20116         # Spoof bfree to exceed threshold
20117         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20118         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20119         for spfree in 40 20 0 15 30 55; do
20120                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20121                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20122                         error "Failed to create $dom file"
20123                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20124                                         lod.${lodname}.dom_stripesize_cur_kb)
20125                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20126                 [[ $dom_def != $dom_current ]] ||
20127                         error "Default stripe size was not changed"
20128                 if [[ $spfree > 0 ]] ; then
20129                         dom_set=$($LFS getstripe -S $dom)
20130                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20131                                 error "DOM component size is still old"
20132                 else
20133                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20134                                 error "DoM component is set with no free space"
20135                 fi
20136                 rm $dom
20137                 dom_current=$dom_def
20138         done
20139 }
20140 run_test 270g "DoM: default DoM stripe size depends on free space"
20141
20142 test_270h() {
20143         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20144                 skip "Need MDS version at least 2.13.53"
20145
20146         local mdtname=${FSNAME}-MDT0000-mdtlov
20147         local dom=$DIR/$tdir/$tfile
20148         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20149
20150         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20151         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20152
20153         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20154         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20155                 error "can't create OST file"
20156         # mirrored file with DOM entry in the second mirror
20157         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20158                 error "can't create mirror with DoM component"
20159
20160         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20161
20162         # DOM component in the middle and has other enries in the same mirror,
20163         # should succeed but lost DoM component
20164         $LFS setstripe --copy=${dom}_1 $dom ||
20165                 error "Can't create file from OST|DOM mirror layout"
20166         # check new file has no DoM layout after all
20167         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20168                 error "File has DoM component while DoM is disabled"
20169 }
20170 run_test 270h "DoM: DoM stripe removal when disabled on server"
20171
20172 test_271a() {
20173         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20174                 skip "Need MDS version at least 2.10.55"
20175
20176         local dom=$DIR/$tdir/dom
20177
20178         mkdir -p $DIR/$tdir
20179
20180         $LFS setstripe -E 1024K -L mdt $dom
20181
20182         lctl set_param -n mdc.*.stats=clear
20183         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20184         cat $dom > /dev/null
20185         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20186         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20187         ls $dom
20188         rm -f $dom
20189 }
20190 run_test 271a "DoM: data is cached for read after write"
20191
20192 test_271b() {
20193         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20194                 skip "Need MDS version at least 2.10.55"
20195
20196         local dom=$DIR/$tdir/dom
20197
20198         mkdir -p $DIR/$tdir
20199
20200         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20201
20202         lctl set_param -n mdc.*.stats=clear
20203         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20204         cancel_lru_locks mdc
20205         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20206         # second stat to check size is cached on client
20207         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20208         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20209         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20210         rm -f $dom
20211 }
20212 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20213
20214 test_271ba() {
20215         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20216                 skip "Need MDS version at least 2.10.55"
20217
20218         local dom=$DIR/$tdir/dom
20219
20220         mkdir -p $DIR/$tdir
20221
20222         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20223
20224         lctl set_param -n mdc.*.stats=clear
20225         lctl set_param -n osc.*.stats=clear
20226         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20227         cancel_lru_locks mdc
20228         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20229         # second stat to check size is cached on client
20230         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20231         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20232         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20233         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20234         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20235         rm -f $dom
20236 }
20237 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20238
20239
20240 get_mdc_stats() {
20241         local mdtidx=$1
20242         local param=$2
20243         local mdt=MDT$(printf %04x $mdtidx)
20244
20245         if [ -z $param ]; then
20246                 lctl get_param -n mdc.*$mdt*.stats
20247         else
20248                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20249         fi
20250 }
20251
20252 test_271c() {
20253         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20254                 skip "Need MDS version at least 2.10.55"
20255
20256         local dom=$DIR/$tdir/dom
20257
20258         mkdir -p $DIR/$tdir
20259
20260         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20261
20262         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20263         local facet=mds$((mdtidx + 1))
20264
20265         cancel_lru_locks mdc
20266         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20267         createmany -o $dom 1000
20268         lctl set_param -n mdc.*.stats=clear
20269         smalliomany -w $dom 1000 200
20270         get_mdc_stats $mdtidx
20271         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20272         # Each file has 1 open, 1 IO enqueues, total 2000
20273         # but now we have also +1 getxattr for security.capability, total 3000
20274         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20275         unlinkmany $dom 1000
20276
20277         cancel_lru_locks mdc
20278         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20279         createmany -o $dom 1000
20280         lctl set_param -n mdc.*.stats=clear
20281         smalliomany -w $dom 1000 200
20282         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20283         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20284         # for OPEN and IO lock.
20285         [ $((enq - enq_2)) -ge 1000 ] ||
20286                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20287         unlinkmany $dom 1000
20288         return 0
20289 }
20290 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20291
20292 cleanup_271def_tests() {
20293         trap 0
20294         rm -f $1
20295 }
20296
20297 test_271d() {
20298         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20299                 skip "Need MDS version at least 2.10.57"
20300
20301         local dom=$DIR/$tdir/dom
20302         local tmp=$TMP/$tfile
20303         trap "cleanup_271def_tests $tmp" EXIT
20304
20305         mkdir -p $DIR/$tdir
20306
20307         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20308
20309         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20310
20311         cancel_lru_locks mdc
20312         dd if=/dev/urandom of=$tmp bs=1000 count=1
20313         dd if=$tmp of=$dom bs=1000 count=1
20314         cancel_lru_locks mdc
20315
20316         cat /etc/hosts >> $tmp
20317         lctl set_param -n mdc.*.stats=clear
20318
20319         # append data to the same file it should update local page
20320         echo "Append to the same page"
20321         cat /etc/hosts >> $dom
20322         local num=$(get_mdc_stats $mdtidx ost_read)
20323         local ra=$(get_mdc_stats $mdtidx req_active)
20324         local rw=$(get_mdc_stats $mdtidx req_waittime)
20325
20326         [ -z $num ] || error "$num READ RPC occured"
20327         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20328         echo "... DONE"
20329
20330         # compare content
20331         cmp $tmp $dom || error "file miscompare"
20332
20333         cancel_lru_locks mdc
20334         lctl set_param -n mdc.*.stats=clear
20335
20336         echo "Open and read file"
20337         cat $dom > /dev/null
20338         local num=$(get_mdc_stats $mdtidx ost_read)
20339         local ra=$(get_mdc_stats $mdtidx req_active)
20340         local rw=$(get_mdc_stats $mdtidx req_waittime)
20341
20342         [ -z $num ] || error "$num READ RPC occured"
20343         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20344         echo "... DONE"
20345
20346         # compare content
20347         cmp $tmp $dom || error "file miscompare"
20348
20349         return 0
20350 }
20351 run_test 271d "DoM: read on open (1K file in reply buffer)"
20352
20353 test_271f() {
20354         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20355                 skip "Need MDS version at least 2.10.57"
20356
20357         local dom=$DIR/$tdir/dom
20358         local tmp=$TMP/$tfile
20359         trap "cleanup_271def_tests $tmp" EXIT
20360
20361         mkdir -p $DIR/$tdir
20362
20363         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20364
20365         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20366
20367         cancel_lru_locks mdc
20368         dd if=/dev/urandom of=$tmp bs=265000 count=1
20369         dd if=$tmp of=$dom bs=265000 count=1
20370         cancel_lru_locks mdc
20371         cat /etc/hosts >> $tmp
20372         lctl set_param -n mdc.*.stats=clear
20373
20374         echo "Append to the same page"
20375         cat /etc/hosts >> $dom
20376         local num=$(get_mdc_stats $mdtidx ost_read)
20377         local ra=$(get_mdc_stats $mdtidx req_active)
20378         local rw=$(get_mdc_stats $mdtidx req_waittime)
20379
20380         [ -z $num ] || error "$num READ RPC occured"
20381         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20382         echo "... DONE"
20383
20384         # compare content
20385         cmp $tmp $dom || error "file miscompare"
20386
20387         cancel_lru_locks mdc
20388         lctl set_param -n mdc.*.stats=clear
20389
20390         echo "Open and read file"
20391         cat $dom > /dev/null
20392         local num=$(get_mdc_stats $mdtidx ost_read)
20393         local ra=$(get_mdc_stats $mdtidx req_active)
20394         local rw=$(get_mdc_stats $mdtidx req_waittime)
20395
20396         [ -z $num ] && num=0
20397         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20398         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20399         echo "... DONE"
20400
20401         # compare content
20402         cmp $tmp $dom || error "file miscompare"
20403
20404         return 0
20405 }
20406 run_test 271f "DoM: read on open (200K file and read tail)"
20407
20408 test_271g() {
20409         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20410                 skip "Skipping due to old client or server version"
20411
20412         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20413         # to get layout
20414         $CHECKSTAT -t file $DIR1/$tfile
20415
20416         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20417         MULTIOP_PID=$!
20418         sleep 1
20419         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20420         $LCTL set_param fail_loc=0x80000314
20421         rm $DIR1/$tfile || error "Unlink fails"
20422         RC=$?
20423         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20424         [ $RC -eq 0 ] || error "Failed write to stale object"
20425 }
20426 run_test 271g "Discard DoM data vs client flush race"
20427
20428 test_272a() {
20429         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20430                 skip "Need MDS version at least 2.11.50"
20431
20432         local dom=$DIR/$tdir/dom
20433         mkdir -p $DIR/$tdir
20434
20435         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20436         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20437                 error "failed to write data into $dom"
20438         local old_md5=$(md5sum $dom)
20439
20440         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20441                 error "failed to migrate to the same DoM component"
20442
20443         local new_md5=$(md5sum $dom)
20444
20445         [ "$old_md5" == "$new_md5" ] ||
20446                 error "md5sum differ: $old_md5, $new_md5"
20447
20448         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20449                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20450 }
20451 run_test 272a "DoM migration: new layout with the same DOM component"
20452
20453 test_272b() {
20454         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20455                 skip "Need MDS version at least 2.11.50"
20456
20457         local dom=$DIR/$tdir/dom
20458         mkdir -p $DIR/$tdir
20459         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20460
20461         local mdtidx=$($LFS getstripe -m $dom)
20462         local mdtname=MDT$(printf %04x $mdtidx)
20463         local facet=mds$((mdtidx + 1))
20464
20465         local mdtfree1=$(do_facet $facet \
20466                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20467         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20468                 error "failed to write data into $dom"
20469         local old_md5=$(md5sum $dom)
20470         cancel_lru_locks mdc
20471         local mdtfree1=$(do_facet $facet \
20472                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20473
20474         $LFS migrate -c2 $dom ||
20475                 error "failed to migrate to the new composite layout"
20476         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20477                 error "MDT stripe was not removed"
20478
20479         cancel_lru_locks mdc
20480         local new_md5=$(md5sum $dom)
20481         [ "$old_md5" == "$new_md5" ] ||
20482                 error "$old_md5 != $new_md5"
20483
20484         # Skip free space checks with ZFS
20485         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20486                 local mdtfree2=$(do_facet $facet \
20487                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20488                 [ $mdtfree2 -gt $mdtfree1 ] ||
20489                         error "MDT space is not freed after migration"
20490         fi
20491         return 0
20492 }
20493 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20494
20495 test_272c() {
20496         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20497                 skip "Need MDS version at least 2.11.50"
20498
20499         local dom=$DIR/$tdir/$tfile
20500         mkdir -p $DIR/$tdir
20501         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20502
20503         local mdtidx=$($LFS getstripe -m $dom)
20504         local mdtname=MDT$(printf %04x $mdtidx)
20505         local facet=mds$((mdtidx + 1))
20506
20507         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20508                 error "failed to write data into $dom"
20509         local old_md5=$(md5sum $dom)
20510         cancel_lru_locks mdc
20511         local mdtfree1=$(do_facet $facet \
20512                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20513
20514         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20515                 error "failed to migrate to the new composite layout"
20516         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20517                 error "MDT stripe was not removed"
20518
20519         cancel_lru_locks mdc
20520         local new_md5=$(md5sum $dom)
20521         [ "$old_md5" == "$new_md5" ] ||
20522                 error "$old_md5 != $new_md5"
20523
20524         # Skip free space checks with ZFS
20525         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20526                 local mdtfree2=$(do_facet $facet \
20527                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20528                 [ $mdtfree2 -gt $mdtfree1 ] ||
20529                         error "MDS space is not freed after migration"
20530         fi
20531         return 0
20532 }
20533 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20534
20535 test_272d() {
20536         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20537                 skip "Need MDS version at least 2.12.55"
20538
20539         local dom=$DIR/$tdir/$tfile
20540         mkdir -p $DIR/$tdir
20541         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20542
20543         local mdtidx=$($LFS getstripe -m $dom)
20544         local mdtname=MDT$(printf %04x $mdtidx)
20545         local facet=mds$((mdtidx + 1))
20546
20547         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20548                 error "failed to write data into $dom"
20549         local old_md5=$(md5sum $dom)
20550         cancel_lru_locks mdc
20551         local mdtfree1=$(do_facet $facet \
20552                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20553
20554         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20555                 error "failed mirroring to the new composite layout"
20556         $LFS mirror resync $dom ||
20557                 error "failed mirror resync"
20558         $LFS mirror split --mirror-id 1 -d $dom ||
20559                 error "failed mirror split"
20560
20561         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20562                 error "MDT stripe was not removed"
20563
20564         cancel_lru_locks mdc
20565         local new_md5=$(md5sum $dom)
20566         [ "$old_md5" == "$new_md5" ] ||
20567                 error "$old_md5 != $new_md5"
20568
20569         # Skip free space checks with ZFS
20570         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20571                 local mdtfree2=$(do_facet $facet \
20572                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20573                 [ $mdtfree2 -gt $mdtfree1 ] ||
20574                         error "MDS space is not freed after DOM mirror deletion"
20575         fi
20576         return 0
20577 }
20578 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20579
20580 test_272e() {
20581         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20582                 skip "Need MDS version at least 2.12.55"
20583
20584         local dom=$DIR/$tdir/$tfile
20585         mkdir -p $DIR/$tdir
20586         $LFS setstripe -c 2 $dom
20587
20588         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20589                 error "failed to write data into $dom"
20590         local old_md5=$(md5sum $dom)
20591         cancel_lru_locks mdc
20592
20593         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20594                 error "failed mirroring to the DOM layout"
20595         $LFS mirror resync $dom ||
20596                 error "failed mirror resync"
20597         $LFS mirror split --mirror-id 1 -d $dom ||
20598                 error "failed mirror split"
20599
20600         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20601                 error "MDT stripe was not removed"
20602
20603         cancel_lru_locks mdc
20604         local new_md5=$(md5sum $dom)
20605         [ "$old_md5" == "$new_md5" ] ||
20606                 error "$old_md5 != $new_md5"
20607
20608         return 0
20609 }
20610 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20611
20612 test_272f() {
20613         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20614                 skip "Need MDS version at least 2.12.55"
20615
20616         local dom=$DIR/$tdir/$tfile
20617         mkdir -p $DIR/$tdir
20618         $LFS setstripe -c 2 $dom
20619
20620         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20621                 error "failed to write data into $dom"
20622         local old_md5=$(md5sum $dom)
20623         cancel_lru_locks mdc
20624
20625         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20626                 error "failed migrating to the DOM file"
20627
20628         cancel_lru_locks mdc
20629         local new_md5=$(md5sum $dom)
20630         [ "$old_md5" != "$new_md5" ] &&
20631                 error "$old_md5 != $new_md5"
20632
20633         return 0
20634 }
20635 run_test 272f "DoM migration: OST-striped file to DOM file"
20636
20637 test_273a() {
20638         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20639                 skip "Need MDS version at least 2.11.50"
20640
20641         # Layout swap cannot be done if either file has DOM component,
20642         # this will never be supported, migration should be used instead
20643
20644         local dom=$DIR/$tdir/$tfile
20645         mkdir -p $DIR/$tdir
20646
20647         $LFS setstripe -c2 ${dom}_plain
20648         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20649         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20650                 error "can swap layout with DoM component"
20651         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20652                 error "can swap layout with DoM component"
20653
20654         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20655         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20656                 error "can swap layout with DoM component"
20657         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20658                 error "can swap layout with DoM component"
20659         return 0
20660 }
20661 run_test 273a "DoM: layout swapping should fail with DOM"
20662
20663 test_275() {
20664         remote_ost_nodsh && skip "remote OST with nodsh"
20665         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20666                 skip "Need OST version >= 2.10.57"
20667
20668         local file=$DIR/$tfile
20669         local oss
20670
20671         oss=$(comma_list $(osts_nodes))
20672
20673         dd if=/dev/urandom of=$file bs=1M count=2 ||
20674                 error "failed to create a file"
20675         cancel_lru_locks osc
20676
20677         #lock 1
20678         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20679                 error "failed to read a file"
20680
20681 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20682         $LCTL set_param fail_loc=0x8000031f
20683
20684         cancel_lru_locks osc &
20685         sleep 1
20686
20687 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20688         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20689         #IO takes another lock, but matches the PENDING one
20690         #and places it to the IO RPC
20691         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20692                 error "failed to read a file with PENDING lock"
20693 }
20694 run_test 275 "Read on a canceled duplicate lock"
20695
20696 test_276() {
20697         remote_ost_nodsh && skip "remote OST with nodsh"
20698         local pid
20699
20700         do_facet ost1 "(while true; do \
20701                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20702                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20703         pid=$!
20704
20705         for LOOP in $(seq 20); do
20706                 stop ost1
20707                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20708         done
20709         kill -9 $pid
20710         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20711                 rm $TMP/sanity_276_pid"
20712 }
20713 run_test 276 "Race between mount and obd_statfs"
20714
20715 test_277() {
20716         $LCTL set_param ldlm.namespaces.*.lru_size=0
20717         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20718         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20719                         grep ^used_mb | awk '{print $2}')
20720         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20721         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20722                 oflag=direct conv=notrunc
20723         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20724                         grep ^used_mb | awk '{print $2}')
20725         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20726 }
20727 run_test 277 "Direct IO shall drop page cache"
20728
20729 test_278() {
20730         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20731         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20732         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20733                 skip "needs the same host for mdt1 mdt2" && return
20734
20735         local pid1
20736         local pid2
20737
20738 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20739         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20740         stop mds2 &
20741         pid2=$!
20742
20743         stop mds1
20744
20745         echo "Starting MDTs"
20746         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20747         wait $pid2
20748 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20749 #will return NULL
20750         do_facet mds2 $LCTL set_param fail_loc=0
20751
20752         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20753         wait_recovery_complete mds2
20754 }
20755 run_test 278 "Race starting MDS between MDTs stop/start"
20756
20757 test_280() {
20758         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20759                 skip "Need MGS version at least 2.13.52"
20760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20761         combined_mgs_mds || skip "needs combined MGS/MDT"
20762
20763         umount_client $MOUNT
20764 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20765         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20766
20767         mount_client $MOUNT &
20768         sleep 1
20769         stop mgs || error "stop mgs failed"
20770         #for a race mgs would crash
20771         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20772         mount_client $MOUNT || error "mount client failed"
20773 }
20774 run_test 280 "Race between MGS umount and client llog processing"
20775
20776 cleanup_test_300() {
20777         trap 0
20778         umask $SAVE_UMASK
20779 }
20780 test_striped_dir() {
20781         local mdt_index=$1
20782         local stripe_count
20783         local stripe_index
20784
20785         mkdir -p $DIR/$tdir
20786
20787         SAVE_UMASK=$(umask)
20788         trap cleanup_test_300 RETURN EXIT
20789
20790         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20791                                                 $DIR/$tdir/striped_dir ||
20792                 error "set striped dir error"
20793
20794         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20795         [ "$mode" = "755" ] || error "expect 755 got $mode"
20796
20797         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20798                 error "getdirstripe failed"
20799         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20800         if [ "$stripe_count" != "2" ]; then
20801                 error "1:stripe_count is $stripe_count, expect 2"
20802         fi
20803         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20804         if [ "$stripe_count" != "2" ]; then
20805                 error "2:stripe_count is $stripe_count, expect 2"
20806         fi
20807
20808         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20809         if [ "$stripe_index" != "$mdt_index" ]; then
20810                 error "stripe_index is $stripe_index, expect $mdt_index"
20811         fi
20812
20813         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20814                 error "nlink error after create striped dir"
20815
20816         mkdir $DIR/$tdir/striped_dir/a
20817         mkdir $DIR/$tdir/striped_dir/b
20818
20819         stat $DIR/$tdir/striped_dir/a ||
20820                 error "create dir under striped dir failed"
20821         stat $DIR/$tdir/striped_dir/b ||
20822                 error "create dir under striped dir failed"
20823
20824         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20825                 error "nlink error after mkdir"
20826
20827         rmdir $DIR/$tdir/striped_dir/a
20828         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20829                 error "nlink error after rmdir"
20830
20831         rmdir $DIR/$tdir/striped_dir/b
20832         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20833                 error "nlink error after rmdir"
20834
20835         chattr +i $DIR/$tdir/striped_dir
20836         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20837                 error "immutable flags not working under striped dir!"
20838         chattr -i $DIR/$tdir/striped_dir
20839
20840         rmdir $DIR/$tdir/striped_dir ||
20841                 error "rmdir striped dir error"
20842
20843         cleanup_test_300
20844
20845         true
20846 }
20847
20848 test_300a() {
20849         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20850                 skip "skipped for lustre < 2.7.0"
20851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20852         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20853
20854         test_striped_dir 0 || error "failed on striped dir on MDT0"
20855         test_striped_dir 1 || error "failed on striped dir on MDT0"
20856 }
20857 run_test 300a "basic striped dir sanity test"
20858
20859 test_300b() {
20860         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20861                 skip "skipped for lustre < 2.7.0"
20862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20863         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20864
20865         local i
20866         local mtime1
20867         local mtime2
20868         local mtime3
20869
20870         test_mkdir $DIR/$tdir || error "mkdir fail"
20871         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20872                 error "set striped dir error"
20873         for i in {0..9}; do
20874                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
20875                 sleep 1
20876                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
20877                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
20878                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
20879                 sleep 1
20880                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
20881                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
20882                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
20883         done
20884         true
20885 }
20886 run_test 300b "check ctime/mtime for striped dir"
20887
20888 test_300c() {
20889         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20890                 skip "skipped for lustre < 2.7.0"
20891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20892         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20893
20894         local file_count
20895
20896         mkdir -p $DIR/$tdir
20897         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
20898                 error "set striped dir error"
20899
20900         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
20901                 error "chown striped dir failed"
20902
20903         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
20904                 error "create 5k files failed"
20905
20906         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
20907
20908         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
20909
20910         rm -rf $DIR/$tdir
20911 }
20912 run_test 300c "chown && check ls under striped directory"
20913
20914 test_300d() {
20915         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20916                 skip "skipped for lustre < 2.7.0"
20917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20918         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20919
20920         local stripe_count
20921         local file
20922
20923         mkdir -p $DIR/$tdir
20924         $LFS setstripe -c 2 $DIR/$tdir
20925
20926         #local striped directory
20927         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20928                 error "set striped dir error"
20929         #look at the directories for debug purposes
20930         ls -l $DIR/$tdir
20931         $LFS getdirstripe $DIR/$tdir
20932         ls -l $DIR/$tdir/striped_dir
20933         $LFS getdirstripe $DIR/$tdir/striped_dir
20934         createmany -o $DIR/$tdir/striped_dir/f 10 ||
20935                 error "create 10 files failed"
20936
20937         #remote striped directory
20938         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
20939                 error "set striped dir error"
20940         #look at the directories for debug purposes
20941         ls -l $DIR/$tdir
20942         $LFS getdirstripe $DIR/$tdir
20943         ls -l $DIR/$tdir/remote_striped_dir
20944         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
20945         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
20946                 error "create 10 files failed"
20947
20948         for file in $(find $DIR/$tdir); do
20949                 stripe_count=$($LFS getstripe -c $file)
20950                 [ $stripe_count -eq 2 ] ||
20951                         error "wrong stripe $stripe_count for $file"
20952         done
20953
20954         rm -rf $DIR/$tdir
20955 }
20956 run_test 300d "check default stripe under striped directory"
20957
20958 test_300e() {
20959         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20960                 skip "Need MDS version at least 2.7.55"
20961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20962         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20963
20964         local stripe_count
20965         local file
20966
20967         mkdir -p $DIR/$tdir
20968
20969         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20970                 error "set striped dir error"
20971
20972         touch $DIR/$tdir/striped_dir/a
20973         touch $DIR/$tdir/striped_dir/b
20974         touch $DIR/$tdir/striped_dir/c
20975
20976         mkdir $DIR/$tdir/striped_dir/dir_a
20977         mkdir $DIR/$tdir/striped_dir/dir_b
20978         mkdir $DIR/$tdir/striped_dir/dir_c
20979
20980         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
20981                 error "set striped adir under striped dir error"
20982
20983         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
20984                 error "set striped bdir under striped dir error"
20985
20986         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
20987                 error "set striped cdir under striped dir error"
20988
20989         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
20990                 error "rename dir under striped dir fails"
20991
20992         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
20993                 error "rename dir under different stripes fails"
20994
20995         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
20996                 error "rename file under striped dir should succeed"
20997
20998         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
20999                 error "rename dir under striped dir should succeed"
21000
21001         rm -rf $DIR/$tdir
21002 }
21003 run_test 300e "check rename under striped directory"
21004
21005 test_300f() {
21006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21007         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21008         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21009                 skip "Need MDS version at least 2.7.55"
21010
21011         local stripe_count
21012         local file
21013
21014         rm -rf $DIR/$tdir
21015         mkdir -p $DIR/$tdir
21016
21017         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21018                 error "set striped dir error"
21019
21020         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21021                 error "set striped dir error"
21022
21023         touch $DIR/$tdir/striped_dir/a
21024         mkdir $DIR/$tdir/striped_dir/dir_a
21025         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21026                 error "create striped dir under striped dir fails"
21027
21028         touch $DIR/$tdir/striped_dir1/b
21029         mkdir $DIR/$tdir/striped_dir1/dir_b
21030         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21031                 error "create striped dir under striped dir fails"
21032
21033         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21034                 error "rename dir under different striped dir should fail"
21035
21036         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21037                 error "rename striped dir under diff striped dir should fail"
21038
21039         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21040                 error "rename file under diff striped dirs fails"
21041
21042         rm -rf $DIR/$tdir
21043 }
21044 run_test 300f "check rename cross striped directory"
21045
21046 test_300_check_default_striped_dir()
21047 {
21048         local dirname=$1
21049         local default_count=$2
21050         local default_index=$3
21051         local stripe_count
21052         local stripe_index
21053         local dir_stripe_index
21054         local dir
21055
21056         echo "checking $dirname $default_count $default_index"
21057         $LFS setdirstripe -D -c $default_count -i $default_index \
21058                                 -t all_char $DIR/$tdir/$dirname ||
21059                 error "set default stripe on striped dir error"
21060         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21061         [ $stripe_count -eq $default_count ] ||
21062                 error "expect $default_count get $stripe_count for $dirname"
21063
21064         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21065         [ $stripe_index -eq $default_index ] ||
21066                 error "expect $default_index get $stripe_index for $dirname"
21067
21068         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21069                                                 error "create dirs failed"
21070
21071         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21072         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21073         for dir in $(find $DIR/$tdir/$dirname/*); do
21074                 stripe_count=$($LFS getdirstripe -c $dir)
21075                 [ $stripe_count -eq $default_count ] ||
21076                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21077                 error "stripe count $default_count != $stripe_count for $dir"
21078
21079                 stripe_index=$($LFS getdirstripe -i $dir)
21080                 [ $default_index -eq -1 ] ||
21081                         [ $stripe_index -eq $default_index ] ||
21082                         error "$stripe_index != $default_index for $dir"
21083
21084                 #check default stripe
21085                 stripe_count=$($LFS getdirstripe -D -c $dir)
21086                 [ $stripe_count -eq $default_count ] ||
21087                 error "default count $default_count != $stripe_count for $dir"
21088
21089                 stripe_index=$($LFS getdirstripe -D -i $dir)
21090                 [ $stripe_index -eq $default_index ] ||
21091                 error "default index $default_index != $stripe_index for $dir"
21092         done
21093         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21094 }
21095
21096 test_300g() {
21097         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21098         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21099                 skip "Need MDS version at least 2.7.55"
21100
21101         local dir
21102         local stripe_count
21103         local stripe_index
21104
21105         mkdir $DIR/$tdir
21106         mkdir $DIR/$tdir/normal_dir
21107
21108         #Checking when client cache stripe index
21109         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21110         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21111                 error "create striped_dir failed"
21112
21113         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21114                 error "create dir0 fails"
21115         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21116         [ $stripe_index -eq 0 ] ||
21117                 error "dir0 expect index 0 got $stripe_index"
21118
21119         mkdir $DIR/$tdir/striped_dir/dir1 ||
21120                 error "create dir1 fails"
21121         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21122         [ $stripe_index -eq 1 ] ||
21123                 error "dir1 expect index 1 got $stripe_index"
21124
21125         #check default stripe count/stripe index
21126         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21127         test_300_check_default_striped_dir normal_dir 1 0
21128         test_300_check_default_striped_dir normal_dir 2 1
21129         test_300_check_default_striped_dir normal_dir 2 -1
21130
21131         #delete default stripe information
21132         echo "delete default stripeEA"
21133         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21134                 error "set default stripe on striped dir error"
21135
21136         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21137         for dir in $(find $DIR/$tdir/normal_dir/*); do
21138                 stripe_count=$($LFS getdirstripe -c $dir)
21139                 [ $stripe_count -eq 0 ] ||
21140                         error "expect 1 get $stripe_count for $dir"
21141                 stripe_index=$($LFS getdirstripe -i $dir)
21142                 [ $stripe_index -eq 0 ] ||
21143                         error "expect 0 get $stripe_index for $dir"
21144         done
21145 }
21146 run_test 300g "check default striped directory for normal directory"
21147
21148 test_300h() {
21149         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21150         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21151                 skip "Need MDS version at least 2.7.55"
21152
21153         local dir
21154         local stripe_count
21155
21156         mkdir $DIR/$tdir
21157         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21158                 error "set striped dir error"
21159
21160         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21161         test_300_check_default_striped_dir striped_dir 1 0
21162         test_300_check_default_striped_dir striped_dir 2 1
21163         test_300_check_default_striped_dir striped_dir 2 -1
21164
21165         #delete default stripe information
21166         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21167                 error "set default stripe on striped dir error"
21168
21169         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21170         for dir in $(find $DIR/$tdir/striped_dir/*); do
21171                 stripe_count=$($LFS getdirstripe -c $dir)
21172                 [ $stripe_count -eq 0 ] ||
21173                         error "expect 1 get $stripe_count for $dir"
21174         done
21175 }
21176 run_test 300h "check default striped directory for striped directory"
21177
21178 test_300i() {
21179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21180         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21181         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21182                 skip "Need MDS version at least 2.7.55"
21183
21184         local stripe_count
21185         local file
21186
21187         mkdir $DIR/$tdir
21188
21189         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21190                 error "set striped dir error"
21191
21192         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21193                 error "create files under striped dir failed"
21194
21195         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21196                 error "set striped hashdir error"
21197
21198         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21199                 error "create dir0 under hash dir failed"
21200         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21201                 error "create dir1 under hash dir failed"
21202
21203         # unfortunately, we need to umount to clear dir layout cache for now
21204         # once we fully implement dir layout, we can drop this
21205         umount_client $MOUNT || error "umount failed"
21206         mount_client $MOUNT || error "mount failed"
21207
21208         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21209         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21210         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21211
21212         #set the stripe to be unknown hash type
21213         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21214         $LCTL set_param fail_loc=0x1901
21215         for ((i = 0; i < 10; i++)); do
21216                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21217                         error "stat f-$i failed"
21218                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21219         done
21220
21221         touch $DIR/$tdir/striped_dir/f0 &&
21222                 error "create under striped dir with unknown hash should fail"
21223
21224         $LCTL set_param fail_loc=0
21225
21226         umount_client $MOUNT || error "umount failed"
21227         mount_client $MOUNT || error "mount failed"
21228
21229         return 0
21230 }
21231 run_test 300i "client handle unknown hash type striped directory"
21232
21233 test_300j() {
21234         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21236         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21237                 skip "Need MDS version at least 2.7.55"
21238
21239         local stripe_count
21240         local file
21241
21242         mkdir $DIR/$tdir
21243
21244         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21245         $LCTL set_param fail_loc=0x1702
21246         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21247                 error "set striped dir error"
21248
21249         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21250                 error "create files under striped dir failed"
21251
21252         $LCTL set_param fail_loc=0
21253
21254         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21255
21256         return 0
21257 }
21258 run_test 300j "test large update record"
21259
21260 test_300k() {
21261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21262         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21263         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21264                 skip "Need MDS version at least 2.7.55"
21265
21266         # this test needs a huge transaction
21267         local kb
21268         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21269              osd*.$FSNAME-MDT0000.kbytestotal")
21270         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21271
21272         local stripe_count
21273         local file
21274
21275         mkdir $DIR/$tdir
21276
21277         #define OBD_FAIL_LARGE_STRIPE   0x1703
21278         $LCTL set_param fail_loc=0x1703
21279         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21280                 error "set striped dir error"
21281         $LCTL set_param fail_loc=0
21282
21283         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21284                 error "getstripeddir fails"
21285         rm -rf $DIR/$tdir/striped_dir ||
21286                 error "unlink striped dir fails"
21287
21288         return 0
21289 }
21290 run_test 300k "test large striped directory"
21291
21292 test_300l() {
21293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21294         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21295         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21296                 skip "Need MDS version at least 2.7.55"
21297
21298         local stripe_index
21299
21300         test_mkdir -p $DIR/$tdir/striped_dir
21301         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21302                         error "chown $RUNAS_ID failed"
21303         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21304                 error "set default striped dir failed"
21305
21306         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21307         $LCTL set_param fail_loc=0x80000158
21308         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21309
21310         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21311         [ $stripe_index -eq 1 ] ||
21312                 error "expect 1 get $stripe_index for $dir"
21313 }
21314 run_test 300l "non-root user to create dir under striped dir with stale layout"
21315
21316 test_300m() {
21317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21318         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21319         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21320                 skip "Need MDS version at least 2.7.55"
21321
21322         mkdir -p $DIR/$tdir/striped_dir
21323         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21324                 error "set default stripes dir error"
21325
21326         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21327
21328         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21329         [ $stripe_count -eq 0 ] ||
21330                         error "expect 0 get $stripe_count for a"
21331
21332         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21333                 error "set default stripes dir error"
21334
21335         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21336
21337         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21338         [ $stripe_count -eq 0 ] ||
21339                         error "expect 0 get $stripe_count for b"
21340
21341         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21342                 error "set default stripes dir error"
21343
21344         mkdir $DIR/$tdir/striped_dir/c &&
21345                 error "default stripe_index is invalid, mkdir c should fails"
21346
21347         rm -rf $DIR/$tdir || error "rmdir fails"
21348 }
21349 run_test 300m "setstriped directory on single MDT FS"
21350
21351 cleanup_300n() {
21352         local list=$(comma_list $(mdts_nodes))
21353
21354         trap 0
21355         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21356 }
21357
21358 test_300n() {
21359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21360         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21361         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21362                 skip "Need MDS version at least 2.7.55"
21363         remote_mds_nodsh && skip "remote MDS with nodsh"
21364
21365         local stripe_index
21366         local list=$(comma_list $(mdts_nodes))
21367
21368         trap cleanup_300n RETURN EXIT
21369         mkdir -p $DIR/$tdir
21370         chmod 777 $DIR/$tdir
21371         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21372                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21373                 error "create striped dir succeeds with gid=0"
21374
21375         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21376         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21377                 error "create striped dir fails with gid=-1"
21378
21379         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21380         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21381                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21382                 error "set default striped dir succeeds with gid=0"
21383
21384
21385         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21386         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21387                 error "set default striped dir fails with gid=-1"
21388
21389
21390         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21391         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21392                                         error "create test_dir fails"
21393         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21394                                         error "create test_dir1 fails"
21395         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21396                                         error "create test_dir2 fails"
21397         cleanup_300n
21398 }
21399 run_test 300n "non-root user to create dir under striped dir with default EA"
21400
21401 test_300o() {
21402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21403         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21404         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21405                 skip "Need MDS version at least 2.7.55"
21406
21407         local numfree1
21408         local numfree2
21409
21410         mkdir -p $DIR/$tdir
21411
21412         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21413         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21414         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21415                 skip "not enough free inodes $numfree1 $numfree2"
21416         fi
21417
21418         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21419         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21420         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21421                 skip "not enough free space $numfree1 $numfree2"
21422         fi
21423
21424         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21425                 error "setdirstripe fails"
21426
21427         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21428                 error "create dirs fails"
21429
21430         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21431         ls $DIR/$tdir/striped_dir > /dev/null ||
21432                 error "ls striped dir fails"
21433         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21434                 error "unlink big striped dir fails"
21435 }
21436 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21437
21438 test_300p() {
21439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21440         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21441         remote_mds_nodsh && skip "remote MDS with nodsh"
21442
21443         mkdir -p $DIR/$tdir
21444
21445         #define OBD_FAIL_OUT_ENOSPC     0x1704
21446         do_facet mds2 lctl set_param fail_loc=0x80001704
21447         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21448                  && error "create striped directory should fail"
21449
21450         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21451
21452         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21453         true
21454 }
21455 run_test 300p "create striped directory without space"
21456
21457 test_300q() {
21458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21459         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21460
21461         local fd=$(free_fd)
21462         local cmd="exec $fd<$tdir"
21463         cd $DIR
21464         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21465         eval $cmd
21466         cmd="exec $fd<&-"
21467         trap "eval $cmd" EXIT
21468         cd $tdir || error "cd $tdir fails"
21469         rmdir  ../$tdir || error "rmdir $tdir fails"
21470         mkdir local_dir && error "create dir succeeds"
21471         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21472         eval $cmd
21473         return 0
21474 }
21475 run_test 300q "create remote directory under orphan directory"
21476
21477 test_300r() {
21478         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21479                 skip "Need MDS version at least 2.7.55" && return
21480         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21481
21482         mkdir $DIR/$tdir
21483
21484         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21485                 error "set striped dir error"
21486
21487         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21488                 error "getstripeddir fails"
21489
21490         local stripe_count
21491         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21492                       awk '/lmv_stripe_count:/ { print $2 }')
21493
21494         [ $MDSCOUNT -ne $stripe_count ] &&
21495                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21496
21497         rm -rf $DIR/$tdir/striped_dir ||
21498                 error "unlink striped dir fails"
21499 }
21500 run_test 300r "test -1 striped directory"
21501
21502 prepare_remote_file() {
21503         mkdir $DIR/$tdir/src_dir ||
21504                 error "create remote source failed"
21505
21506         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21507                  error "cp to remote source failed"
21508         touch $DIR/$tdir/src_dir/a
21509
21510         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21511                 error "create remote target dir failed"
21512
21513         touch $DIR/$tdir/tgt_dir/b
21514
21515         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21516                 error "rename dir cross MDT failed!"
21517
21518         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21519                 error "src_child still exists after rename"
21520
21521         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21522                 error "missing file(a) after rename"
21523
21524         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21525                 error "diff after rename"
21526 }
21527
21528 test_310a() {
21529         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21531
21532         local remote_file=$DIR/$tdir/tgt_dir/b
21533
21534         mkdir -p $DIR/$tdir
21535
21536         prepare_remote_file || error "prepare remote file failed"
21537
21538         #open-unlink file
21539         $OPENUNLINK $remote_file $remote_file ||
21540                 error "openunlink $remote_file failed"
21541         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21542 }
21543 run_test 310a "open unlink remote file"
21544
21545 test_310b() {
21546         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21548
21549         local remote_file=$DIR/$tdir/tgt_dir/b
21550
21551         mkdir -p $DIR/$tdir
21552
21553         prepare_remote_file || error "prepare remote file failed"
21554
21555         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21556         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21557         $CHECKSTAT -t file $remote_file || error "check file failed"
21558 }
21559 run_test 310b "unlink remote file with multiple links while open"
21560
21561 test_310c() {
21562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21563         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21564
21565         local remote_file=$DIR/$tdir/tgt_dir/b
21566
21567         mkdir -p $DIR/$tdir
21568
21569         prepare_remote_file || error "prepare remote file failed"
21570
21571         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21572         multiop_bg_pause $remote_file O_uc ||
21573                         error "mulitop failed for remote file"
21574         MULTIPID=$!
21575         $MULTIOP $DIR/$tfile Ouc
21576         kill -USR1 $MULTIPID
21577         wait $MULTIPID
21578 }
21579 run_test 310c "open-unlink remote file with multiple links"
21580
21581 #LU-4825
21582 test_311() {
21583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21584         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21585         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21586                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21587         remote_mds_nodsh && skip "remote MDS with nodsh"
21588
21589         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21590         local mdts=$(comma_list $(mdts_nodes))
21591
21592         mkdir -p $DIR/$tdir
21593         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21594         createmany -o $DIR/$tdir/$tfile. 1000
21595
21596         # statfs data is not real time, let's just calculate it
21597         old_iused=$((old_iused + 1000))
21598
21599         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21600                         osp.*OST0000*MDT0000.create_count")
21601         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21602                                 osp.*OST0000*MDT0000.max_create_count")
21603         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21604
21605         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21606         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21607         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21608
21609         unlinkmany $DIR/$tdir/$tfile. 1000
21610
21611         do_nodes $mdts "$LCTL set_param -n \
21612                         osp.*OST0000*.max_create_count=$max_count"
21613         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21614                 do_nodes $mdts "$LCTL set_param -n \
21615                                 osp.*OST0000*.create_count=$count"
21616         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21617                         grep "=0" && error "create_count is zero"
21618
21619         local new_iused
21620         for i in $(seq 120); do
21621                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21622                 # system may be too busy to destroy all objs in time, use
21623                 # a somewhat small value to not fail autotest
21624                 [ $((old_iused - new_iused)) -gt 400 ] && break
21625                 sleep 1
21626         done
21627
21628         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21629         [ $((old_iused - new_iused)) -gt 400 ] ||
21630                 error "objs not destroyed after unlink"
21631 }
21632 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21633
21634 zfs_oid_to_objid()
21635 {
21636         local ost=$1
21637         local objid=$2
21638
21639         local vdevdir=$(dirname $(facet_vdevice $ost))
21640         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21641         local zfs_zapid=$(do_facet $ost $cmd |
21642                           grep -w "/O/0/d$((objid%32))" -C 5 |
21643                           awk '/Object/{getline; print $1}')
21644         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21645                           awk "/$objid = /"'{printf $3}')
21646
21647         echo $zfs_objid
21648 }
21649
21650 zfs_object_blksz() {
21651         local ost=$1
21652         local objid=$2
21653
21654         local vdevdir=$(dirname $(facet_vdevice $ost))
21655         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21656         local blksz=$(do_facet $ost $cmd $objid |
21657                       awk '/dblk/{getline; printf $4}')
21658
21659         case "${blksz: -1}" in
21660                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21661                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21662                 *) ;;
21663         esac
21664
21665         echo $blksz
21666 }
21667
21668 test_312() { # LU-4856
21669         remote_ost_nodsh && skip "remote OST with nodsh"
21670         [ "$ost1_FSTYPE" = "zfs" ] ||
21671                 skip_env "the test only applies to zfs"
21672
21673         local max_blksz=$(do_facet ost1 \
21674                           $ZFS get -p recordsize $(facet_device ost1) |
21675                           awk '!/VALUE/{print $3}')
21676
21677         # to make life a little bit easier
21678         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21679         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21680
21681         local tf=$DIR/$tdir/$tfile
21682         touch $tf
21683         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21684
21685         # Get ZFS object id
21686         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21687         # block size change by sequential overwrite
21688         local bs
21689
21690         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21691                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21692
21693                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21694                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21695         done
21696         rm -f $tf
21697
21698         # block size change by sequential append write
21699         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21700         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21701         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21702         local count
21703
21704         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21705                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21706                         oflag=sync conv=notrunc
21707
21708                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21709                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21710                         error "blksz error, actual $blksz, " \
21711                                 "expected: 2 * $count * $PAGE_SIZE"
21712         done
21713         rm -f $tf
21714
21715         # random write
21716         touch $tf
21717         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21718         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21719
21720         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21721         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21722         [ $blksz -eq $PAGE_SIZE ] ||
21723                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21724
21725         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21726         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21727         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21728
21729         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21730         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21731         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21732 }
21733 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21734
21735 test_313() {
21736         remote_ost_nodsh && skip "remote OST with nodsh"
21737
21738         local file=$DIR/$tfile
21739
21740         rm -f $file
21741         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21742
21743         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21744         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21745         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21746                 error "write should failed"
21747         do_facet ost1 "$LCTL set_param fail_loc=0"
21748         rm -f $file
21749 }
21750 run_test 313 "io should fail after last_rcvd update fail"
21751
21752 test_314() {
21753         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21754
21755         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21756         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21757         rm -f $DIR/$tfile
21758         wait_delete_completed
21759         do_facet ost1 "$LCTL set_param fail_loc=0"
21760 }
21761 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21762
21763 test_315() { # LU-618
21764         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21765
21766         local file=$DIR/$tfile
21767         rm -f $file
21768
21769         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21770                 error "multiop file write failed"
21771         $MULTIOP $file oO_RDONLY:r4063232_c &
21772         PID=$!
21773
21774         sleep 2
21775
21776         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21777         kill -USR1 $PID
21778
21779         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21780         rm -f $file
21781 }
21782 run_test 315 "read should be accounted"
21783
21784 test_316() {
21785         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21786         large_xattr_enabled || skip_env "ea_inode feature disabled"
21787
21788         rm -rf $DIR/$tdir/d
21789         mkdir -p $DIR/$tdir/d
21790         chown nobody $DIR/$tdir/d
21791         touch $DIR/$tdir/d/file
21792
21793         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21794 }
21795 run_test 316 "lfs mv"
21796
21797 test_317() {
21798         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21799                 skip "Need MDS version at least 2.11.53"
21800         if [ "$ost1_FSTYPE" == "zfs" ]; then
21801                 skip "LU-10370: no implementation for ZFS"
21802         fi
21803
21804         local trunc_sz
21805         local grant_blk_size
21806
21807         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21808                         awk '/grant_block_size:/ { print $2; exit; }')
21809         #
21810         # Create File of size 5M. Truncate it to below size's and verify
21811         # blocks count.
21812         #
21813         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21814                 error "Create file $DIR/$tfile failed"
21815         stack_trap "rm -f $DIR/$tfile" EXIT
21816
21817         for trunc_sz in 2097152 4097 4000 509 0; do
21818                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21819                         error "truncate $tfile to $trunc_sz failed"
21820                 local sz=$(stat --format=%s $DIR/$tfile)
21821                 local blk=$(stat --format=%b $DIR/$tfile)
21822                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21823                                      grant_blk_size) * 8))
21824
21825                 if [[ $blk -ne $trunc_blk ]]; then
21826                         $(which stat) $DIR/$tfile
21827                         error "Expected Block $trunc_blk got $blk for $tfile"
21828                 fi
21829
21830                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21831                         error "Expected Size $trunc_sz got $sz for $tfile"
21832         done
21833
21834         #
21835         # sparse file test
21836         # Create file with a hole and write actual two blocks. Block count
21837         # must be 16.
21838         #
21839         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21840                 conv=fsync || error "Create file : $DIR/$tfile"
21841
21842         # Calculate the final truncate size.
21843         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21844
21845         #
21846         # truncate to size $trunc_sz bytes. Strip the last block
21847         # The block count must drop to 8
21848         #
21849         $TRUNCATE $DIR/$tfile $trunc_sz ||
21850                 error "truncate $tfile to $trunc_sz failed"
21851
21852         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
21853         sz=$(stat --format=%s $DIR/$tfile)
21854         blk=$(stat --format=%b $DIR/$tfile)
21855
21856         if [[ $blk -ne $trunc_bsz ]]; then
21857                 $(which stat) $DIR/$tfile
21858                 error "Expected Block $trunc_bsz got $blk for $tfile"
21859         fi
21860
21861         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21862                 error "Expected Size $trunc_sz got $sz for $tfile"
21863 }
21864 run_test 317 "Verify blocks get correctly update after truncate"
21865
21866 test_318() {
21867         local old_max_active=$($LCTL get_param -n \
21868                             llite.*.max_read_ahead_async_active 2>/dev/null)
21869
21870         $LCTL set_param llite.*.max_read_ahead_async_active=256
21871         local max_active=$($LCTL get_param -n \
21872                            llite.*.max_read_ahead_async_active 2>/dev/null)
21873         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
21874
21875         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
21876                 error "set max_read_ahead_async_active should succeed"
21877
21878         $LCTL set_param llite.*.max_read_ahead_async_active=512
21879         max_active=$($LCTL get_param -n \
21880                      llite.*.max_read_ahead_async_active 2>/dev/null)
21881         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
21882
21883         # restore @max_active
21884         [ $old_max_active -ne 0 ] && $LCTL set_param \
21885                 llite.*.max_read_ahead_async_active=$old_max_active
21886
21887         local old_threshold=$($LCTL get_param -n \
21888                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21889         local max_per_file_mb=$($LCTL get_param -n \
21890                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
21891
21892         local invalid=$(($max_per_file_mb + 1))
21893         $LCTL set_param \
21894                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
21895                         && error "set $invalid should fail"
21896
21897         local valid=$(($invalid - 1))
21898         $LCTL set_param \
21899                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
21900                         error "set $valid should succeed"
21901         local threshold=$($LCTL get_param -n \
21902                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21903         [ $threshold -eq $valid ] || error \
21904                 "expect threshold $valid got $threshold"
21905         $LCTL set_param \
21906                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
21907 }
21908 run_test 318 "Verify async readahead tunables"
21909
21910 test_319() {
21911         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
21912
21913         local before=$(date +%s)
21914         local evict
21915         local mdir=$DIR/$tdir
21916         local file=$mdir/xxx
21917
21918         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
21919         touch $file
21920
21921 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
21922         $LCTL set_param fail_val=5 fail_loc=0x8000032c
21923         $LFS mv -m1 $file &
21924
21925         sleep 1
21926         dd if=$file of=/dev/null
21927         wait
21928         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
21929           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
21930
21931         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
21932 }
21933 run_test 319 "lost lease lock on migrate error"
21934
21935 test_398a() { # LU-4198
21936         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21937         $LCTL set_param ldlm.namespaces.*.lru_size=clear
21938
21939         # request a new lock on client
21940         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21941
21942         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21943         local lock_count=$($LCTL get_param -n \
21944                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21945         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
21946
21947         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
21948
21949         # no lock cached, should use lockless IO and not enqueue new lock
21950         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21951         lock_count=$($LCTL get_param -n \
21952                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21953         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
21954 }
21955 run_test 398a "direct IO should cancel lock otherwise lockless"
21956
21957 test_398b() { # LU-4198
21958         which fio || skip_env "no fio installed"
21959         $LFS setstripe -c -1 $DIR/$tfile
21960
21961         local size=12
21962         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
21963
21964         local njobs=4
21965         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
21966         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21967                 --numjobs=$njobs --fallocate=none \
21968                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21969                 --filename=$DIR/$tfile &
21970         bg_pid=$!
21971
21972         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
21973         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
21974                 --numjobs=$njobs --fallocate=none \
21975                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21976                 --filename=$DIR/$tfile || true
21977         wait $bg_pid
21978
21979         rm -rf $DIR/$tfile
21980 }
21981 run_test 398b "DIO and buffer IO race"
21982
21983 test_398c() { # LU-4198
21984         which fio || skip_env "no fio installed"
21985
21986         saved_debug=$($LCTL get_param -n debug)
21987         $LCTL set_param debug=0
21988
21989         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
21990         ((size /= 1024)) # by megabytes
21991         ((size /= 2)) # write half of the OST at most
21992         [ $size -gt 40 ] && size=40 #reduce test time anyway
21993
21994         $LFS setstripe -c 1 $DIR/$tfile
21995
21996         # it seems like ldiskfs reserves more space than necessary if the
21997         # writing blocks are not mapped, so it extends the file firstly
21998         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
21999         cancel_lru_locks osc
22000
22001         # clear and verify rpc_stats later
22002         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22003
22004         local njobs=4
22005         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22006         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22007                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22008                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22009                 --filename=$DIR/$tfile
22010         [ $? -eq 0 ] || error "fio write error"
22011
22012         [ $($LCTL get_param -n \
22013          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22014                 error "Locks were requested while doing AIO"
22015
22016         # get the percentage of 1-page I/O
22017         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22018                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22019                 awk '{print $7}')
22020         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22021
22022         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22023         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22024                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22025                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22026                 --filename=$DIR/$tfile
22027         [ $? -eq 0 ] || error "fio mixed read write error"
22028
22029         echo "AIO with large block size ${size}M"
22030         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22031                 --numjobs=1 --fallocate=none --ioengine=libaio \
22032                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22033                 --filename=$DIR/$tfile
22034         [ $? -eq 0 ] || error "fio large block size failed"
22035
22036         rm -rf $DIR/$tfile
22037         $LCTL set_param debug="$saved_debug"
22038 }
22039 run_test 398c "run fio to test AIO"
22040
22041 test_398d() { #  LU-13846
22042         test -f aiocp || skip_env "no aiocp installed"
22043         local aio_file=$DIR/aio_file
22044
22045         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22046
22047         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22048         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22049
22050         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22051
22052         # make sure we don't crash and fail properly
22053         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22054                 error "aio not aligned with PAGE SIZE should fail"
22055
22056         rm -rf $DIR/$tfile $aio_file
22057 }
22058 run_test 398d "run aiocp to verify block size > stripe size"
22059
22060 test_fake_rw() {
22061         local read_write=$1
22062         if [ "$read_write" = "write" ]; then
22063                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22064         elif [ "$read_write" = "read" ]; then
22065                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22066         else
22067                 error "argument error"
22068         fi
22069
22070         # turn off debug for performance testing
22071         local saved_debug=$($LCTL get_param -n debug)
22072         $LCTL set_param debug=0
22073
22074         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22075
22076         # get ost1 size - $FSNAME-OST0000
22077         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22078         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22079         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22080
22081         if [ "$read_write" = "read" ]; then
22082                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
22083         fi
22084
22085         local start_time=$(date +%s.%N)
22086         $dd_cmd bs=1M count=$blocks oflag=sync ||
22087                 error "real dd $read_write error"
22088         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22089
22090         if [ "$read_write" = "write" ]; then
22091                 rm -f $DIR/$tfile
22092         fi
22093
22094         # define OBD_FAIL_OST_FAKE_RW           0x238
22095         do_facet ost1 $LCTL set_param fail_loc=0x238
22096
22097         local start_time=$(date +%s.%N)
22098         $dd_cmd bs=1M count=$blocks oflag=sync ||
22099                 error "fake dd $read_write error"
22100         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22101
22102         if [ "$read_write" = "write" ]; then
22103                 # verify file size
22104                 cancel_lru_locks osc
22105                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22106                         error "$tfile size not $blocks MB"
22107         fi
22108         do_facet ost1 $LCTL set_param fail_loc=0
22109
22110         echo "fake $read_write $duration_fake vs. normal $read_write" \
22111                 "$duration in seconds"
22112         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22113                 error_not_in_vm "fake write is slower"
22114
22115         $LCTL set_param -n debug="$saved_debug"
22116         rm -f $DIR/$tfile
22117 }
22118 test_399a() { # LU-7655 for OST fake write
22119         remote_ost_nodsh && skip "remote OST with nodsh"
22120
22121         test_fake_rw write
22122 }
22123 run_test 399a "fake write should not be slower than normal write"
22124
22125 test_399b() { # LU-8726 for OST fake read
22126         remote_ost_nodsh && skip "remote OST with nodsh"
22127         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22128                 skip_env "ldiskfs only test"
22129         fi
22130
22131         test_fake_rw read
22132 }
22133 run_test 399b "fake read should not be slower than normal read"
22134
22135 test_400a() { # LU-1606, was conf-sanity test_74
22136         if ! which $CC > /dev/null 2>&1; then
22137                 skip_env "$CC is not installed"
22138         fi
22139
22140         local extra_flags=''
22141         local out=$TMP/$tfile
22142         local prefix=/usr/include/lustre
22143         local prog
22144
22145         # Oleg removes c files in his test rig so test if any c files exist
22146         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22147                 skip_env "Needed c test files are missing"
22148
22149         if ! [[ -d $prefix ]]; then
22150                 # Assume we're running in tree and fixup the include path.
22151                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22152                 extra_flags+=" -L$LUSTRE/utils/.lib"
22153         fi
22154
22155         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22156                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22157                         error "client api broken"
22158         done
22159         rm -f $out
22160 }
22161 run_test 400a "Lustre client api program can compile and link"
22162
22163 test_400b() { # LU-1606, LU-5011
22164         local header
22165         local out=$TMP/$tfile
22166         local prefix=/usr/include/linux/lustre
22167
22168         # We use a hard coded prefix so that this test will not fail
22169         # when run in tree. There are headers in lustre/include/lustre/
22170         # that are not packaged (like lustre_idl.h) and have more
22171         # complicated include dependencies (like config.h and lnet/types.h).
22172         # Since this test about correct packaging we just skip them when
22173         # they don't exist (see below) rather than try to fixup cppflags.
22174
22175         if ! which $CC > /dev/null 2>&1; then
22176                 skip_env "$CC is not installed"
22177         fi
22178
22179         for header in $prefix/*.h; do
22180                 if ! [[ -f "$header" ]]; then
22181                         continue
22182                 fi
22183
22184                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22185                         continue # lustre_ioctl.h is internal header
22186                 fi
22187
22188                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22189                         error "cannot compile '$header'"
22190         done
22191         rm -f $out
22192 }
22193 run_test 400b "packaged headers can be compiled"
22194
22195 test_401a() { #LU-7437
22196         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22197         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22198
22199         #count the number of parameters by "list_param -R"
22200         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22201         #count the number of parameters by listing proc files
22202         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22203         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22204         echo "proc_dirs='$proc_dirs'"
22205         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22206         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22207                       sort -u | wc -l)
22208
22209         [ $params -eq $procs ] ||
22210                 error "found $params parameters vs. $procs proc files"
22211
22212         # test the list_param -D option only returns directories
22213         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22214         #count the number of parameters by listing proc directories
22215         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22216                 sort -u | wc -l)
22217
22218         [ $params -eq $procs ] ||
22219                 error "found $params parameters vs. $procs proc files"
22220 }
22221 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22222
22223 test_401b() {
22224         local save=$($LCTL get_param -n jobid_var)
22225         local tmp=testing
22226
22227         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
22228                 error "no error returned when setting bad parameters"
22229
22230         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
22231         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22232
22233         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
22234         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
22235         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22236 }
22237 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22238
22239 test_401c() {
22240         local jobid_var_old=$($LCTL get_param -n jobid_var)
22241         local jobid_var_new
22242
22243         $LCTL set_param jobid_var= &&
22244                 error "no error returned for 'set_param a='"
22245
22246         jobid_var_new=$($LCTL get_param -n jobid_var)
22247         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22248                 error "jobid_var was changed by setting without value"
22249
22250         $LCTL set_param jobid_var &&
22251                 error "no error returned for 'set_param a'"
22252
22253         jobid_var_new=$($LCTL get_param -n jobid_var)
22254         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22255                 error "jobid_var was changed by setting without value"
22256 }
22257 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22258
22259 test_401d() {
22260         local jobid_var_old=$($LCTL get_param -n jobid_var)
22261         local jobid_var_new
22262         local new_value="foo=bar"
22263
22264         $LCTL set_param jobid_var=$new_value ||
22265                 error "'set_param a=b' did not accept a value containing '='"
22266
22267         jobid_var_new=$($LCTL get_param -n jobid_var)
22268         [[ "$jobid_var_new" == "$new_value" ]] ||
22269                 error "'set_param a=b' failed on a value containing '='"
22270
22271         # Reset the jobid_var to test the other format
22272         $LCTL set_param jobid_var=$jobid_var_old
22273         jobid_var_new=$($LCTL get_param -n jobid_var)
22274         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22275                 error "failed to reset jobid_var"
22276
22277         $LCTL set_param jobid_var $new_value ||
22278                 error "'set_param a b' did not accept a value containing '='"
22279
22280         jobid_var_new=$($LCTL get_param -n jobid_var)
22281         [[ "$jobid_var_new" == "$new_value" ]] ||
22282                 error "'set_param a b' failed on a value containing '='"
22283
22284         $LCTL set_param jobid_var $jobid_var_old
22285         jobid_var_new=$($LCTL get_param -n jobid_var)
22286         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22287                 error "failed to reset jobid_var"
22288 }
22289 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22290
22291 test_402() {
22292         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22293         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22294                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22295         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22296                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22297                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22298         remote_mds_nodsh && skip "remote MDS with nodsh"
22299
22300         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22301 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22302         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22303         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22304                 echo "Touch failed - OK"
22305 }
22306 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22307
22308 test_403() {
22309         local file1=$DIR/$tfile.1
22310         local file2=$DIR/$tfile.2
22311         local tfile=$TMP/$tfile
22312
22313         rm -f $file1 $file2 $tfile
22314
22315         touch $file1
22316         ln $file1 $file2
22317
22318         # 30 sec OBD_TIMEOUT in ll_getattr()
22319         # right before populating st_nlink
22320         $LCTL set_param fail_loc=0x80001409
22321         stat -c %h $file1 > $tfile &
22322
22323         # create an alias, drop all locks and reclaim the dentry
22324         < $file2
22325         cancel_lru_locks mdc
22326         cancel_lru_locks osc
22327         sysctl -w vm.drop_caches=2
22328
22329         wait
22330
22331         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22332
22333         rm -f $tfile $file1 $file2
22334 }
22335 run_test 403 "i_nlink should not drop to zero due to aliasing"
22336
22337 test_404() { # LU-6601
22338         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22339                 skip "Need server version newer than 2.8.52"
22340         remote_mds_nodsh && skip "remote MDS with nodsh"
22341
22342         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22343                 awk '/osp .*-osc-MDT/ { print $4}')
22344
22345         local osp
22346         for osp in $mosps; do
22347                 echo "Deactivate: " $osp
22348                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22349                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22350                         awk -vp=$osp '$4 == p { print $2 }')
22351                 [ $stat = IN ] || {
22352                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22353                         error "deactivate error"
22354                 }
22355                 echo "Activate: " $osp
22356                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22357                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22358                         awk -vp=$osp '$4 == p { print $2 }')
22359                 [ $stat = UP ] || {
22360                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22361                         error "activate error"
22362                 }
22363         done
22364 }
22365 run_test 404 "validate manual {de}activated works properly for OSPs"
22366
22367 test_405() {
22368         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22369         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22370                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22371                         skip "Layout swap lock is not supported"
22372
22373         check_swap_layouts_support
22374         check_swap_layout_no_dom $DIR
22375
22376         test_mkdir $DIR/$tdir
22377         swap_lock_test -d $DIR/$tdir ||
22378                 error "One layout swap locked test failed"
22379 }
22380 run_test 405 "Various layout swap lock tests"
22381
22382 test_406() {
22383         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22384         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22385         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22387         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22388                 skip "Need MDS version at least 2.8.50"
22389
22390         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22391         local test_pool=$TESTNAME
22392
22393         pool_add $test_pool || error "pool_add failed"
22394         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22395                 error "pool_add_targets failed"
22396
22397         save_layout_restore_at_exit $MOUNT
22398
22399         # parent set default stripe count only, child will stripe from both
22400         # parent and fs default
22401         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22402                 error "setstripe $MOUNT failed"
22403         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22404         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22405         for i in $(seq 10); do
22406                 local f=$DIR/$tdir/$tfile.$i
22407                 touch $f || error "touch failed"
22408                 local count=$($LFS getstripe -c $f)
22409                 [ $count -eq $OSTCOUNT ] ||
22410                         error "$f stripe count $count != $OSTCOUNT"
22411                 local offset=$($LFS getstripe -i $f)
22412                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22413                 local size=$($LFS getstripe -S $f)
22414                 [ $size -eq $((def_stripe_size * 2)) ] ||
22415                         error "$f stripe size $size != $((def_stripe_size * 2))"
22416                 local pool=$($LFS getstripe -p $f)
22417                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22418         done
22419
22420         # change fs default striping, delete parent default striping, now child
22421         # will stripe from new fs default striping only
22422         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22423                 error "change $MOUNT default stripe failed"
22424         $LFS setstripe -c 0 $DIR/$tdir ||
22425                 error "delete $tdir default stripe failed"
22426         for i in $(seq 11 20); do
22427                 local f=$DIR/$tdir/$tfile.$i
22428                 touch $f || error "touch $f failed"
22429                 local count=$($LFS getstripe -c $f)
22430                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22431                 local offset=$($LFS getstripe -i $f)
22432                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22433                 local size=$($LFS getstripe -S $f)
22434                 [ $size -eq $def_stripe_size ] ||
22435                         error "$f stripe size $size != $def_stripe_size"
22436                 local pool=$($LFS getstripe -p $f)
22437                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22438         done
22439
22440         unlinkmany $DIR/$tdir/$tfile. 1 20
22441
22442         local f=$DIR/$tdir/$tfile
22443         pool_remove_all_targets $test_pool $f
22444         pool_remove $test_pool $f
22445 }
22446 run_test 406 "DNE support fs default striping"
22447
22448 test_407() {
22449         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22450         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22451                 skip "Need MDS version at least 2.8.55"
22452         remote_mds_nodsh && skip "remote MDS with nodsh"
22453
22454         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22455                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22456         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22457                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22458         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22459
22460         #define OBD_FAIL_DT_TXN_STOP    0x2019
22461         for idx in $(seq $MDSCOUNT); do
22462                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22463         done
22464         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22465         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22466                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22467         true
22468 }
22469 run_test 407 "transaction fail should cause operation fail"
22470
22471 test_408() {
22472         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22473
22474         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22475         lctl set_param fail_loc=0x8000040a
22476         # let ll_prepare_partial_page() fail
22477         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22478
22479         rm -f $DIR/$tfile
22480
22481         # create at least 100 unused inodes so that
22482         # shrink_icache_memory(0) should not return 0
22483         touch $DIR/$tfile-{0..100}
22484         rm -f $DIR/$tfile-{0..100}
22485         sync
22486
22487         echo 2 > /proc/sys/vm/drop_caches
22488 }
22489 run_test 408 "drop_caches should not hang due to page leaks"
22490
22491 test_409()
22492 {
22493         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22494
22495         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22496         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22497         touch $DIR/$tdir/guard || error "(2) Fail to create"
22498
22499         local PREFIX=$(str_repeat 'A' 128)
22500         echo "Create 1K hard links start at $(date)"
22501         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22502                 error "(3) Fail to hard link"
22503
22504         echo "Links count should be right although linkEA overflow"
22505         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22506         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22507         [ $linkcount -eq 1001 ] ||
22508                 error "(5) Unexpected hard links count: $linkcount"
22509
22510         echo "List all links start at $(date)"
22511         ls -l $DIR/$tdir/foo > /dev/null ||
22512                 error "(6) Fail to list $DIR/$tdir/foo"
22513
22514         echo "Unlink hard links start at $(date)"
22515         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22516                 error "(7) Fail to unlink"
22517         echo "Unlink hard links finished at $(date)"
22518 }
22519 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22520
22521 test_410()
22522 {
22523         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22524                 skip "Need client version at least 2.9.59"
22525         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22526                 skip "Need MODULES build"
22527
22528         # Create a file, and stat it from the kernel
22529         local testfile=$DIR/$tfile
22530         touch $testfile
22531
22532         local run_id=$RANDOM
22533         local my_ino=$(stat --format "%i" $testfile)
22534
22535         # Try to insert the module. This will always fail as the
22536         # module is designed to not be inserted.
22537         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22538             &> /dev/null
22539
22540         # Anything but success is a test failure
22541         dmesg | grep -q \
22542             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22543             error "no inode match"
22544 }
22545 run_test 410 "Test inode number returned from kernel thread"
22546
22547 cleanup_test411_cgroup() {
22548         trap 0
22549         rmdir "$1"
22550 }
22551
22552 test_411() {
22553         local cg_basedir=/sys/fs/cgroup/memory
22554         # LU-9966
22555         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22556                 skip "no setup for cgroup"
22557
22558         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22559                 error "test file creation failed"
22560         cancel_lru_locks osc
22561
22562         # Create a very small memory cgroup to force a slab allocation error
22563         local cgdir=$cg_basedir/osc_slab_alloc
22564         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22565         trap "cleanup_test411_cgroup $cgdir" EXIT
22566         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22567         echo 1M > $cgdir/memory.limit_in_bytes
22568
22569         # Should not LBUG, just be killed by oom-killer
22570         # dd will return 0 even allocation failure in some environment.
22571         # So don't check return value
22572         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22573         cleanup_test411_cgroup $cgdir
22574
22575         return 0
22576 }
22577 run_test 411 "Slab allocation error with cgroup does not LBUG"
22578
22579 test_412() {
22580         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22581         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22582                 skip "Need server version at least 2.10.55"
22583         fi
22584
22585         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22586                 error "mkdir failed"
22587         $LFS getdirstripe $DIR/$tdir
22588         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22589         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22590                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22591         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22592         [ $stripe_count -eq 2 ] ||
22593                 error "expect 2 get $stripe_count"
22594 }
22595 run_test 412 "mkdir on specific MDTs"
22596
22597 test_qos_mkdir() {
22598         local mkdir_cmd=$1
22599         local stripe_count=$2
22600         local mdts=$(comma_list $(mdts_nodes))
22601
22602         local testdir
22603         local lmv_qos_prio_free
22604         local lmv_qos_threshold_rr
22605         local lmv_qos_maxage
22606         local lod_qos_prio_free
22607         local lod_qos_threshold_rr
22608         local lod_qos_maxage
22609         local count
22610         local i
22611
22612         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22613         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22614         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22615                 head -n1)
22616         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22617         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22618         stack_trap "$LCTL set_param \
22619                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22620         stack_trap "$LCTL set_param \
22621                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22622         stack_trap "$LCTL set_param \
22623                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22624
22625         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22626                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22627         lod_qos_prio_free=${lod_qos_prio_free%%%}
22628         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22629                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22630         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22631         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22632                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22633         stack_trap "do_nodes $mdts $LCTL set_param \
22634                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22635         stack_trap "do_nodes $mdts $LCTL set_param \
22636                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22637                 EXIT
22638         stack_trap "do_nodes $mdts $LCTL set_param \
22639                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22640
22641         echo
22642         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22643
22644         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22645         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22646
22647         testdir=$DIR/$tdir-s$stripe_count/rr
22648
22649         for i in $(seq $((100 * MDSCOUNT))); do
22650                 eval $mkdir_cmd $testdir/subdir$i ||
22651                         error "$mkdir_cmd subdir$i failed"
22652         done
22653
22654         for i in $(seq $MDSCOUNT); do
22655                 count=$($LFS getdirstripe -i $testdir/* |
22656                                 grep ^$((i - 1))$ | wc -l)
22657                 echo "$count directories created on MDT$((i - 1))"
22658                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22659
22660                 if [ $stripe_count -gt 1 ]; then
22661                         count=$($LFS getdirstripe $testdir/* |
22662                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22663                         echo "$count stripes created on MDT$((i - 1))"
22664                         # deviation should < 5% of average
22665                         [ $count -lt $((95 * stripe_count)) ] ||
22666                         [ $count -gt $((105 * stripe_count)) ] &&
22667                                 error "stripes are not evenly distributed"
22668                 fi
22669         done
22670
22671         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22672         do_nodes $mdts $LCTL set_param \
22673                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22674
22675         echo
22676         echo "Check for uneven MDTs: "
22677
22678         local ffree
22679         local bavail
22680         local max
22681         local min
22682         local max_index
22683         local min_index
22684         local tmp
22685
22686         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22687         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22688         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22689
22690         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22691         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22692         max_index=0
22693         min_index=0
22694         for ((i = 1; i < ${#ffree[@]}; i++)); do
22695                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22696                 if [ $tmp -gt $max ]; then
22697                         max=$tmp
22698                         max_index=$i
22699                 fi
22700                 if [ $tmp -lt $min ]; then
22701                         min=$tmp
22702                         min_index=$i
22703                 fi
22704         done
22705
22706         [ ${ffree[min_index]} -eq 0 ] &&
22707                 skip "no free files in MDT$min_index"
22708         [ ${ffree[min_index]} -gt 100000000 ] &&
22709                 skip "too much free files in MDT$min_index"
22710
22711         # Check if we need to generate uneven MDTs
22712         local threshold=50
22713         local diff=$(((max - min) * 100 / min))
22714         local value="$(generate_string 1024)"
22715
22716         while [ $diff -lt $threshold ]; do
22717                 # generate uneven MDTs, create till $threshold% diff
22718                 echo -n "weight diff=$diff% must be > $threshold% ..."
22719                 count=$((${ffree[min_index]} / 10))
22720                 # 50 sec per 10000 files in vm
22721                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22722                         skip "$count files to create"
22723                 echo "Fill MDT$min_index with $count files"
22724                 [ -d $DIR/$tdir-MDT$min_index ] ||
22725                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22726                         error "mkdir $tdir-MDT$min_index failed"
22727                 for i in $(seq $count); do
22728                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22729                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22730                                 error "create f$j_$i failed"
22731                         setfattr -n user.413b -v $value \
22732                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22733                                 error "setfattr f$j_$i failed"
22734                 done
22735
22736                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22737                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22738                 max=$(((${ffree[max_index]} >> 8) * \
22739                         (${bavail[max_index]} * bsize >> 16)))
22740                 min=$(((${ffree[min_index]} >> 8) * \
22741                         (${bavail[min_index]} * bsize >> 16)))
22742                 diff=$(((max - min) * 100 / min))
22743         done
22744
22745         echo "MDT filesfree available: ${ffree[@]}"
22746         echo "MDT blocks available: ${bavail[@]}"
22747         echo "weight diff=$diff%"
22748
22749         echo
22750         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22751
22752         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22753         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22754         # decrease statfs age, so that it can be updated in time
22755         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22756         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22757
22758         sleep 1
22759
22760         testdir=$DIR/$tdir-s$stripe_count/qos
22761
22762         for i in $(seq $((100 * MDSCOUNT))); do
22763                 eval $mkdir_cmd $testdir/subdir$i ||
22764                         error "$mkdir_cmd subdir$i failed"
22765         done
22766
22767         for i in $(seq $MDSCOUNT); do
22768                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22769                         wc -l)
22770                 echo "$count directories created on MDT$((i - 1))"
22771
22772                 if [ $stripe_count -gt 1 ]; then
22773                         count=$($LFS getdirstripe $testdir/* |
22774                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22775                         echo "$count stripes created on MDT$((i - 1))"
22776                 fi
22777         done
22778
22779         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
22780         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22781
22782         # D-value should > 10% of averge
22783         [ $((max - min)) -lt 10 ] &&
22784                 error "subdirs shouldn't be evenly distributed"
22785
22786         # ditto
22787         if [ $stripe_count -gt 1 ]; then
22788                 max=$($LFS getdirstripe $testdir/* |
22789                         grep -P "^\s+$max_index\t" | wc -l)
22790                 min=$($LFS getdirstripe $testdir/* |
22791                         grep -P "^\s+$min_index\t" | wc -l)
22792                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22793                         error "stripes shouldn't be evenly distributed"|| true
22794         fi
22795 }
22796
22797 test_413a() {
22798         [ $MDSCOUNT -lt 2 ] &&
22799                 skip "We need at least 2 MDTs for this test"
22800
22801         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22802                 skip "Need server version at least 2.12.52"
22803
22804         local stripe_count
22805
22806         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22807                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22808                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22809                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22810                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22811         done
22812 }
22813 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22814
22815 test_413b() {
22816         [ $MDSCOUNT -lt 2 ] &&
22817                 skip "We need at least 2 MDTs for this test"
22818
22819         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22820                 skip "Need server version at least 2.12.52"
22821
22822         local stripe_count
22823
22824         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22825                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22826                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22827                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22828                 $LFS setdirstripe -D -c $stripe_count \
22829                         $DIR/$tdir-s$stripe_count/rr ||
22830                         error "setdirstripe failed"
22831                 $LFS setdirstripe -D -c $stripe_count \
22832                         $DIR/$tdir-s$stripe_count/qos ||
22833                         error "setdirstripe failed"
22834                 test_qos_mkdir "mkdir" $stripe_count
22835         done
22836 }
22837 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
22838
22839 test_414() {
22840 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
22841         $LCTL set_param fail_loc=0x80000521
22842         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
22843         rm -f $DIR/$tfile
22844 }
22845 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
22846
22847 test_415() {
22848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22849         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22850                 skip "Need server version at least 2.11.52"
22851
22852         # LU-11102
22853         local total
22854         local setattr_pid
22855         local start_time
22856         local end_time
22857         local duration
22858
22859         total=500
22860         # this test may be slow on ZFS
22861         [ "$mds1_FSTYPE" == "zfs" ] && total=100
22862
22863         # though this test is designed for striped directory, let's test normal
22864         # directory too since lock is always saved as CoS lock.
22865         test_mkdir $DIR/$tdir || error "mkdir $tdir"
22866         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
22867
22868         (
22869                 while true; do
22870                         touch $DIR/$tdir
22871                 done
22872         ) &
22873         setattr_pid=$!
22874
22875         start_time=$(date +%s)
22876         for i in $(seq $total); do
22877                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
22878                         > /dev/null
22879         done
22880         end_time=$(date +%s)
22881         duration=$((end_time - start_time))
22882
22883         kill -9 $setattr_pid
22884
22885         echo "rename $total files took $duration sec"
22886         [ $duration -lt 100 ] || error "rename took $duration sec"
22887 }
22888 run_test 415 "lock revoke is not missing"
22889
22890 test_416() {
22891         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22892                 skip "Need server version at least 2.11.55"
22893
22894         # define OBD_FAIL_OSD_TXN_START    0x19a
22895         do_facet mds1 lctl set_param fail_loc=0x19a
22896
22897         lfs mkdir -c $MDSCOUNT $DIR/$tdir
22898
22899         true
22900 }
22901 run_test 416 "transaction start failure won't cause system hung"
22902
22903 cleanup_417() {
22904         trap 0
22905         do_nodes $(comma_list $(mdts_nodes)) \
22906                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
22907         do_nodes $(comma_list $(mdts_nodes)) \
22908                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
22909         do_nodes $(comma_list $(mdts_nodes)) \
22910                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
22911 }
22912
22913 test_417() {
22914         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22915         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
22916                 skip "Need MDS version at least 2.11.56"
22917
22918         trap cleanup_417 RETURN EXIT
22919
22920         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
22921         do_nodes $(comma_list $(mdts_nodes)) \
22922                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
22923         $LFS migrate -m 0 $DIR/$tdir.1 &&
22924                 error "migrate dir $tdir.1 should fail"
22925
22926         do_nodes $(comma_list $(mdts_nodes)) \
22927                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
22928         $LFS mkdir -i 1 $DIR/$tdir.2 &&
22929                 error "create remote dir $tdir.2 should fail"
22930
22931         do_nodes $(comma_list $(mdts_nodes)) \
22932                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
22933         $LFS mkdir -c 2 $DIR/$tdir.3 &&
22934                 error "create striped dir $tdir.3 should fail"
22935         true
22936 }
22937 run_test 417 "disable remote dir, striped dir and dir migration"
22938
22939 # Checks that the outputs of df [-i] and lfs df [-i] match
22940 #
22941 # usage: check_lfs_df <blocks | inodes> <mountpoint>
22942 check_lfs_df() {
22943         local dir=$2
22944         local inodes
22945         local df_out
22946         local lfs_df_out
22947         local count
22948         local passed=false
22949
22950         # blocks or inodes
22951         [ "$1" == "blocks" ] && inodes= || inodes="-i"
22952
22953         for count in {1..100}; do
22954                 cancel_lru_locks
22955                 sync; sleep 0.2
22956
22957                 # read the lines of interest
22958                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
22959                         error "df $inodes $dir | tail -n +2 failed"
22960                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
22961                         error "lfs df $inodes $dir | grep summary: failed"
22962
22963                 # skip first substrings of each output as they are different
22964                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
22965                 # compare the two outputs
22966                 passed=true
22967                 for i in {1..5}; do
22968                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
22969                 done
22970                 $passed && break
22971         done
22972
22973         if ! $passed; then
22974                 df -P $inodes $dir
22975                 echo
22976                 lfs df $inodes $dir
22977                 error "df and lfs df $1 output mismatch: "      \
22978                       "df ${inodes}: ${df_out[*]}, "            \
22979                       "lfs df ${inodes}: ${lfs_df_out[*]}"
22980         fi
22981 }
22982
22983 test_418() {
22984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22985
22986         local dir=$DIR/$tdir
22987         local numfiles=$((RANDOM % 4096 + 2))
22988         local numblocks=$((RANDOM % 256 + 1))
22989
22990         wait_delete_completed
22991         test_mkdir $dir
22992
22993         # check block output
22994         check_lfs_df blocks $dir
22995         # check inode output
22996         check_lfs_df inodes $dir
22997
22998         # create a single file and retest
22999         echo "Creating a single file and testing"
23000         createmany -o $dir/$tfile- 1 &>/dev/null ||
23001                 error "creating 1 file in $dir failed"
23002         check_lfs_df blocks $dir
23003         check_lfs_df inodes $dir
23004
23005         # create a random number of files
23006         echo "Creating $((numfiles - 1)) files and testing"
23007         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23008                 error "creating $((numfiles - 1)) files in $dir failed"
23009
23010         # write a random number of blocks to the first test file
23011         echo "Writing $numblocks 4K blocks and testing"
23012         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23013                 count=$numblocks &>/dev/null ||
23014                 error "dd to $dir/${tfile}-0 failed"
23015
23016         # retest
23017         check_lfs_df blocks $dir
23018         check_lfs_df inodes $dir
23019
23020         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23021                 error "unlinking $numfiles files in $dir failed"
23022 }
23023 run_test 418 "df and lfs df outputs match"
23024
23025 test_419()
23026 {
23027         local dir=$DIR/$tdir
23028
23029         mkdir -p $dir
23030         touch $dir/file
23031
23032         cancel_lru_locks mdc
23033
23034         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23035         $LCTL set_param fail_loc=0x1410
23036         cat $dir/file
23037         $LCTL set_param fail_loc=0
23038         rm -rf $dir
23039 }
23040 run_test 419 "Verify open file by name doesn't crash kernel"
23041
23042 test_420()
23043 {
23044         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23045                 skip "Need MDS version at least 2.12.53"
23046
23047         local SAVE_UMASK=$(umask)
23048         local dir=$DIR/$tdir
23049         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23050
23051         mkdir -p $dir
23052         umask 0000
23053         mkdir -m03777 $dir/testdir
23054         ls -dn $dir/testdir
23055         # Need to remove trailing '.' when SELinux is enabled
23056         local dirperms=$(ls -dn $dir/testdir |
23057                          awk '{ sub(/\.$/, "", $1); print $1}')
23058         [ $dirperms == "drwxrwsrwt" ] ||
23059                 error "incorrect perms on $dir/testdir"
23060
23061         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23062                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23063         ls -n $dir/testdir/testfile
23064         local fileperms=$(ls -n $dir/testdir/testfile |
23065                           awk '{ sub(/\.$/, "", $1); print $1}')
23066         [ $fileperms == "-rwxr-xr-x" ] ||
23067                 error "incorrect perms on $dir/testdir/testfile"
23068
23069         umask $SAVE_UMASK
23070 }
23071 run_test 420 "clear SGID bit on non-directories for non-members"
23072
23073 test_421a() {
23074         local cnt
23075         local fid1
23076         local fid2
23077
23078         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23079                 skip "Need MDS version at least 2.12.54"
23080
23081         test_mkdir $DIR/$tdir
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         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23089
23090         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23091         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23092
23093         cnt=$(ls -1 $DIR/$tdir | wc -l)
23094         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23095
23096         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23097         createmany -o $DIR/$tdir/f 3
23098         cnt=$(ls -1 $DIR/$tdir | wc -l)
23099         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23100
23101         fid1=$(lfs path2fid $DIR/$tdir/f1)
23102         fid2=$(lfs path2fid $DIR/$tdir/f2)
23103         echo "remove using fsname $FSNAME"
23104         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23105
23106         cnt=$(ls -1 $DIR/$tdir | wc -l)
23107         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23108 }
23109 run_test 421a "simple rm by fid"
23110
23111 test_421b() {
23112         local cnt
23113         local FID1
23114         local FID2
23115
23116         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23117                 skip "Need MDS version at least 2.12.54"
23118
23119         test_mkdir $DIR/$tdir
23120         createmany -o $DIR/$tdir/f 3
23121         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23122         MULTIPID=$!
23123
23124         FID1=$(lfs path2fid $DIR/$tdir/f1)
23125         FID2=$(lfs path2fid $DIR/$tdir/f2)
23126         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23127
23128         kill -USR1 $MULTIPID
23129         wait
23130
23131         cnt=$(ls $DIR/$tdir | wc -l)
23132         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23133 }
23134 run_test 421b "rm by fid on open file"
23135
23136 test_421c() {
23137         local cnt
23138         local FIDS
23139
23140         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23141                 skip "Need MDS version at least 2.12.54"
23142
23143         test_mkdir $DIR/$tdir
23144         createmany -o $DIR/$tdir/f 3
23145         touch $DIR/$tdir/$tfile
23146         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23147         cnt=$(ls -1 $DIR/$tdir | wc -l)
23148         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23149
23150         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23151         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23152
23153         cnt=$(ls $DIR/$tdir | wc -l)
23154         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23155 }
23156 run_test 421c "rm by fid against hardlinked files"
23157
23158 test_421d() {
23159         local cnt
23160         local FIDS
23161
23162         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23163                 skip "Need MDS version at least 2.12.54"
23164
23165         test_mkdir $DIR/$tdir
23166         createmany -o $DIR/$tdir/f 4097
23167         cnt=$(ls -1 $DIR/$tdir | wc -l)
23168         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23169
23170         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23171         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23172
23173         cnt=$(ls $DIR/$tdir | wc -l)
23174         rm -rf $DIR/$tdir
23175         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23176 }
23177 run_test 421d "rmfid en masse"
23178
23179 test_421e() {
23180         local cnt
23181         local FID
23182
23183         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23184         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23185                 skip "Need MDS version at least 2.12.54"
23186
23187         mkdir -p $DIR/$tdir
23188         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23189         createmany -o $DIR/$tdir/striped_dir/f 512
23190         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23191         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23192
23193         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23194                 sed "s/[/][^:]*://g")
23195         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23196
23197         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23198         rm -rf $DIR/$tdir
23199         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23200 }
23201 run_test 421e "rmfid in DNE"
23202
23203 test_421f() {
23204         local cnt
23205         local FID
23206
23207         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23208                 skip "Need MDS version at least 2.12.54"
23209
23210         test_mkdir $DIR/$tdir
23211         touch $DIR/$tdir/f
23212         cnt=$(ls -1 $DIR/$tdir | wc -l)
23213         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23214
23215         FID=$(lfs path2fid $DIR/$tdir/f)
23216         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23217         # rmfid should fail
23218         cnt=$(ls -1 $DIR/$tdir | wc -l)
23219         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23220
23221         chmod a+rw $DIR/$tdir
23222         ls -la $DIR/$tdir
23223         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23224         # rmfid should fail
23225         cnt=$(ls -1 $DIR/$tdir | wc -l)
23226         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23227
23228         rm -f $DIR/$tdir/f
23229         $RUNAS touch $DIR/$tdir/f
23230         FID=$(lfs path2fid $DIR/$tdir/f)
23231         echo "rmfid as root"
23232         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23233         cnt=$(ls -1 $DIR/$tdir | wc -l)
23234         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23235
23236         rm -f $DIR/$tdir/f
23237         $RUNAS touch $DIR/$tdir/f
23238         cnt=$(ls -1 $DIR/$tdir | wc -l)
23239         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23240         FID=$(lfs path2fid $DIR/$tdir/f)
23241         # rmfid w/o user_fid2path mount option should fail
23242         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23243         cnt=$(ls -1 $DIR/$tdir | wc -l)
23244         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23245
23246         umount_client $MOUNT || error "failed to umount client"
23247         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23248                 error "failed to mount client'"
23249
23250         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23251         # rmfid should succeed
23252         cnt=$(ls -1 $DIR/$tdir | wc -l)
23253         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23254
23255         # rmfid shouldn't allow to remove files due to dir's permission
23256         chmod a+rwx $DIR/$tdir
23257         touch $DIR/$tdir/f
23258         ls -la $DIR/$tdir
23259         FID=$(lfs path2fid $DIR/$tdir/f)
23260         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23261
23262         umount_client $MOUNT || error "failed to umount client"
23263         mount_client $MOUNT "$MOUNT_OPTS" ||
23264                 error "failed to mount client'"
23265
23266 }
23267 run_test 421f "rmfid checks permissions"
23268
23269 test_421g() {
23270         local cnt
23271         local FIDS
23272
23273         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23274         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23275                 skip "Need MDS version at least 2.12.54"
23276
23277         mkdir -p $DIR/$tdir
23278         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23279         createmany -o $DIR/$tdir/striped_dir/f 512
23280         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23281         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23282
23283         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23284                 sed "s/[/][^:]*://g")
23285
23286         rm -f $DIR/$tdir/striped_dir/f1*
23287         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23288         removed=$((512 - cnt))
23289
23290         # few files have been just removed, so we expect
23291         # rmfid to fail on their fids
23292         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23293         [ $removed != $errors ] && error "$errors != $removed"
23294
23295         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23296         rm -rf $DIR/$tdir
23297         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23298 }
23299 run_test 421g "rmfid to return errors properly"
23300
23301 test_422() {
23302         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23303         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23304         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23305         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23306         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23307
23308         local amc=$(at_max_get client)
23309         local amo=$(at_max_get mds1)
23310         local timeout=`lctl get_param -n timeout`
23311
23312         at_max_set 0 client
23313         at_max_set 0 mds1
23314
23315 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23316         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23317                         fail_val=$(((2*timeout + 10)*1000))
23318         touch $DIR/$tdir/d3/file &
23319         sleep 2
23320 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23321         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23322                         fail_val=$((2*timeout + 5))
23323         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23324         local pid=$!
23325         sleep 1
23326         kill -9 $pid
23327         sleep $((2 * timeout))
23328         echo kill $pid
23329         kill -9 $pid
23330         lctl mark touch
23331         touch $DIR/$tdir/d2/file3
23332         touch $DIR/$tdir/d2/file4
23333         touch $DIR/$tdir/d2/file5
23334
23335         wait
23336         at_max_set $amc client
23337         at_max_set $amo mds1
23338
23339         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23340         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23341                 error "Watchdog is always throttled"
23342 }
23343 run_test 422 "kill a process with RPC in progress"
23344
23345 stat_test() {
23346     df -h $MOUNT &
23347     df -h $MOUNT &
23348     df -h $MOUNT &
23349     df -h $MOUNT &
23350     df -h $MOUNT &
23351     df -h $MOUNT &
23352 }
23353
23354 test_423() {
23355     local _stats
23356     # ensure statfs cache is expired
23357     sleep 2;
23358
23359     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23360     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23361
23362     return 0
23363 }
23364 run_test 423 "statfs should return a right data"
23365
23366 test_424() {
23367 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23368         $LCTL set_param fail_loc=0x80000522
23369         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23370         rm -f $DIR/$tfile
23371 }
23372 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23373
23374 prep_801() {
23375         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23376         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23377                 skip "Need server version at least 2.9.55"
23378
23379         start_full_debug_logging
23380 }
23381
23382 post_801() {
23383         stop_full_debug_logging
23384 }
23385
23386 barrier_stat() {
23387         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23388                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23389                            awk '/The barrier for/ { print $7 }')
23390                 echo $st
23391         else
23392                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23393                 echo \'$st\'
23394         fi
23395 }
23396
23397 barrier_expired() {
23398         local expired
23399
23400         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23401                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23402                           awk '/will be expired/ { print $7 }')
23403         else
23404                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23405         fi
23406
23407         echo $expired
23408 }
23409
23410 test_801a() {
23411         prep_801
23412
23413         echo "Start barrier_freeze at: $(date)"
23414         #define OBD_FAIL_BARRIER_DELAY          0x2202
23415         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23416         # Do not reduce barrier time - See LU-11873
23417         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23418
23419         sleep 2
23420         local b_status=$(barrier_stat)
23421         echo "Got barrier status at: $(date)"
23422         [ "$b_status" = "'freezing_p1'" ] ||
23423                 error "(1) unexpected barrier status $b_status"
23424
23425         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23426         wait
23427         b_status=$(barrier_stat)
23428         [ "$b_status" = "'frozen'" ] ||
23429                 error "(2) unexpected barrier status $b_status"
23430
23431         local expired=$(barrier_expired)
23432         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23433         sleep $((expired + 3))
23434
23435         b_status=$(barrier_stat)
23436         [ "$b_status" = "'expired'" ] ||
23437                 error "(3) unexpected barrier status $b_status"
23438
23439         # Do not reduce barrier time - See LU-11873
23440         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23441                 error "(4) fail to freeze barrier"
23442
23443         b_status=$(barrier_stat)
23444         [ "$b_status" = "'frozen'" ] ||
23445                 error "(5) unexpected barrier status $b_status"
23446
23447         echo "Start barrier_thaw at: $(date)"
23448         #define OBD_FAIL_BARRIER_DELAY          0x2202
23449         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23450         do_facet mgs $LCTL barrier_thaw $FSNAME &
23451
23452         sleep 2
23453         b_status=$(barrier_stat)
23454         echo "Got barrier status at: $(date)"
23455         [ "$b_status" = "'thawing'" ] ||
23456                 error "(6) unexpected barrier status $b_status"
23457
23458         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23459         wait
23460         b_status=$(barrier_stat)
23461         [ "$b_status" = "'thawed'" ] ||
23462                 error "(7) unexpected barrier status $b_status"
23463
23464         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23465         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23466         do_facet mgs $LCTL barrier_freeze $FSNAME
23467
23468         b_status=$(barrier_stat)
23469         [ "$b_status" = "'failed'" ] ||
23470                 error "(8) unexpected barrier status $b_status"
23471
23472         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23473         do_facet mgs $LCTL barrier_thaw $FSNAME
23474
23475         post_801
23476 }
23477 run_test 801a "write barrier user interfaces and stat machine"
23478
23479 test_801b() {
23480         prep_801
23481
23482         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23483         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23484         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23485         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23486         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23487
23488         cancel_lru_locks mdc
23489
23490         # 180 seconds should be long enough
23491         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23492
23493         local b_status=$(barrier_stat)
23494         [ "$b_status" = "'frozen'" ] ||
23495                 error "(6) unexpected barrier status $b_status"
23496
23497         mkdir $DIR/$tdir/d0/d10 &
23498         mkdir_pid=$!
23499
23500         touch $DIR/$tdir/d1/f13 &
23501         touch_pid=$!
23502
23503         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23504         ln_pid=$!
23505
23506         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23507         mv_pid=$!
23508
23509         rm -f $DIR/$tdir/d4/f12 &
23510         rm_pid=$!
23511
23512         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
23513
23514         # To guarantee taht the 'stat' is not blocked
23515         b_status=$(barrier_stat)
23516         [ "$b_status" = "'frozen'" ] ||
23517                 error "(8) unexpected barrier status $b_status"
23518
23519         # let above commands to run at background
23520         sleep 5
23521
23522         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
23523         ps -p $touch_pid || error "(10) touch should be blocked"
23524         ps -p $ln_pid || error "(11) link should be blocked"
23525         ps -p $mv_pid || error "(12) rename should be blocked"
23526         ps -p $rm_pid || error "(13) unlink should be blocked"
23527
23528         b_status=$(barrier_stat)
23529         [ "$b_status" = "'frozen'" ] ||
23530                 error "(14) unexpected barrier status $b_status"
23531
23532         do_facet mgs $LCTL barrier_thaw $FSNAME
23533         b_status=$(barrier_stat)
23534         [ "$b_status" = "'thawed'" ] ||
23535                 error "(15) unexpected barrier status $b_status"
23536
23537         wait $mkdir_pid || error "(16) mkdir should succeed"
23538         wait $touch_pid || error "(17) touch should succeed"
23539         wait $ln_pid || error "(18) link should succeed"
23540         wait $mv_pid || error "(19) rename should succeed"
23541         wait $rm_pid || error "(20) unlink should succeed"
23542
23543         post_801
23544 }
23545 run_test 801b "modification will be blocked by write barrier"
23546
23547 test_801c() {
23548         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23549
23550         prep_801
23551
23552         stop mds2 || error "(1) Fail to stop mds2"
23553
23554         do_facet mgs $LCTL barrier_freeze $FSNAME 30
23555
23556         local b_status=$(barrier_stat)
23557         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
23558                 do_facet mgs $LCTL barrier_thaw $FSNAME
23559                 error "(2) unexpected barrier status $b_status"
23560         }
23561
23562         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23563                 error "(3) Fail to rescan barrier bitmap"
23564
23565         # Do not reduce barrier time - See LU-11873
23566         do_facet mgs $LCTL barrier_freeze $FSNAME 20
23567
23568         b_status=$(barrier_stat)
23569         [ "$b_status" = "'frozen'" ] ||
23570                 error "(4) unexpected barrier status $b_status"
23571
23572         do_facet mgs $LCTL barrier_thaw $FSNAME
23573         b_status=$(barrier_stat)
23574         [ "$b_status" = "'thawed'" ] ||
23575                 error "(5) unexpected barrier status $b_status"
23576
23577         local devname=$(mdsdevname 2)
23578
23579         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
23580
23581         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23582                 error "(7) Fail to rescan barrier bitmap"
23583
23584         post_801
23585 }
23586 run_test 801c "rescan barrier bitmap"
23587
23588 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
23589 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
23590 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
23591 saved_MOUNT_OPTS=$MOUNT_OPTS
23592
23593 cleanup_802a() {
23594         trap 0
23595
23596         stopall
23597         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
23598         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
23599         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
23600         MOUNT_OPTS=$saved_MOUNT_OPTS
23601         setupall
23602 }
23603
23604 test_802a() {
23605         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
23606         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23607         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23608                 skip "Need server version at least 2.9.55"
23609
23610         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
23611
23612         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23613
23614         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23615                 error "(2) Fail to copy"
23616
23617         trap cleanup_802a EXIT
23618
23619         # sync by force before remount as readonly
23620         sync; sync_all_data; sleep 3; sync_all_data
23621
23622         stopall
23623
23624         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
23625         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
23626         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
23627
23628         echo "Mount the server as read only"
23629         setupall server_only || error "(3) Fail to start servers"
23630
23631         echo "Mount client without ro should fail"
23632         mount_client $MOUNT &&
23633                 error "(4) Mount client without 'ro' should fail"
23634
23635         echo "Mount client with ro should succeed"
23636         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
23637         mount_client $MOUNT ||
23638                 error "(5) Mount client with 'ro' should succeed"
23639
23640         echo "Modify should be refused"
23641         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23642
23643         echo "Read should be allowed"
23644         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23645                 error "(7) Read should succeed under ro mode"
23646
23647         cleanup_802a
23648 }
23649 run_test 802a "simulate readonly device"
23650
23651 test_802b() {
23652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23653         remote_mds_nodsh && skip "remote MDS with nodsh"
23654
23655         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
23656                 skip "readonly option not available"
23657
23658         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
23659
23660         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23661                 error "(2) Fail to copy"
23662
23663         # write back all cached data before setting MDT to readonly
23664         cancel_lru_locks
23665         sync_all_data
23666
23667         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
23668         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
23669
23670         echo "Modify should be refused"
23671         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23672
23673         echo "Read should be allowed"
23674         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23675                 error "(7) Read should succeed under ro mode"
23676
23677         # disable readonly
23678         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
23679 }
23680 run_test 802b "be able to set MDTs to readonly"
23681
23682 test_803() {
23683         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23684         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23685                 skip "MDS needs to be newer than 2.10.54"
23686
23687         mkdir -p $DIR/$tdir
23688         # Create some objects on all MDTs to trigger related logs objects
23689         for idx in $(seq $MDSCOUNT); do
23690                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
23691                         $DIR/$tdir/dir${idx} ||
23692                         error "Fail to create $DIR/$tdir/dir${idx}"
23693         done
23694
23695         sync; sleep 3
23696         wait_delete_completed # ensure old test cleanups are finished
23697         echo "before create:"
23698         $LFS df -i $MOUNT
23699         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23700
23701         for i in {1..10}; do
23702                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
23703                         error "Fail to create $DIR/$tdir/foo$i"
23704         done
23705
23706         sync; sleep 3
23707         echo "after create:"
23708         $LFS df -i $MOUNT
23709         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23710
23711         # allow for an llog to be cleaned up during the test
23712         [ $after_used -ge $((before_used + 10 - 1)) ] ||
23713                 error "before ($before_used) + 10 > after ($after_used)"
23714
23715         for i in {1..10}; do
23716                 rm -rf $DIR/$tdir/foo$i ||
23717                         error "Fail to remove $DIR/$tdir/foo$i"
23718         done
23719
23720         sleep 3 # avoid MDT return cached statfs
23721         wait_delete_completed
23722         echo "after unlink:"
23723         $LFS df -i $MOUNT
23724         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23725
23726         # allow for an llog to be created during the test
23727         [ $after_used -le $((before_used + 1)) ] ||
23728                 error "after ($after_used) > before ($before_used) + 1"
23729 }
23730 run_test 803 "verify agent object for remote object"
23731
23732 test_804() {
23733         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23734         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23735                 skip "MDS needs to be newer than 2.10.54"
23736         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
23737
23738         mkdir -p $DIR/$tdir
23739         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
23740                 error "Fail to create $DIR/$tdir/dir0"
23741
23742         local fid=$($LFS path2fid $DIR/$tdir/dir0)
23743         local dev=$(mdsdevname 2)
23744
23745         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23746                 grep ${fid} || error "NOT found agent entry for dir0"
23747
23748         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
23749                 error "Fail to create $DIR/$tdir/dir1"
23750
23751         touch $DIR/$tdir/dir1/foo0 ||
23752                 error "Fail to create $DIR/$tdir/dir1/foo0"
23753         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
23754         local rc=0
23755
23756         for idx in $(seq $MDSCOUNT); do
23757                 dev=$(mdsdevname $idx)
23758                 do_facet mds${idx} \
23759                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23760                         grep ${fid} && rc=$idx
23761         done
23762
23763         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
23764                 error "Fail to rename foo0 to foo1"
23765         if [ $rc -eq 0 ]; then
23766                 for idx in $(seq $MDSCOUNT); do
23767                         dev=$(mdsdevname $idx)
23768                         do_facet mds${idx} \
23769                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23770                         grep ${fid} && rc=$idx
23771                 done
23772         fi
23773
23774         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
23775                 error "Fail to rename foo1 to foo2"
23776         if [ $rc -eq 0 ]; then
23777                 for idx in $(seq $MDSCOUNT); do
23778                         dev=$(mdsdevname $idx)
23779                         do_facet mds${idx} \
23780                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23781                         grep ${fid} && rc=$idx
23782                 done
23783         fi
23784
23785         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
23786
23787         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
23788                 error "Fail to link to $DIR/$tdir/dir1/foo2"
23789         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
23790                 error "Fail to rename foo2 to foo0"
23791         unlink $DIR/$tdir/dir1/foo0 ||
23792                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
23793         rm -rf $DIR/$tdir/dir0 ||
23794                 error "Fail to rm $DIR/$tdir/dir0"
23795
23796         for idx in $(seq $MDSCOUNT); do
23797                 dev=$(mdsdevname $idx)
23798                 rc=0
23799
23800                 stop mds${idx}
23801                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
23802                         rc=$?
23803                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
23804                         error "mount mds$idx failed"
23805                 df $MOUNT > /dev/null 2>&1
23806
23807                 # e2fsck should not return error
23808                 [ $rc -eq 0 ] ||
23809                         error "e2fsck detected error on MDT${idx}: rc=$rc"
23810         done
23811 }
23812 run_test 804 "verify agent entry for remote entry"
23813
23814 cleanup_805() {
23815         do_facet $SINGLEMDS zfs set quota=$old $fsset
23816         unlinkmany $DIR/$tdir/f- 1000000
23817         trap 0
23818 }
23819
23820 test_805() {
23821         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
23822         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
23823         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
23824                 skip "netfree not implemented before 0.7"
23825         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
23826                 skip "Need MDS version at least 2.10.57"
23827
23828         local fsset
23829         local freekb
23830         local usedkb
23831         local old
23832         local quota
23833         local pref="osd-zfs.$FSNAME-MDT0000."
23834
23835         # limit available space on MDS dataset to meet nospace issue
23836         # quickly. then ZFS 0.7.2 can use reserved space if asked
23837         # properly (using netfree flag in osd_declare_destroy()
23838         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
23839         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
23840                 gawk '{print $3}')
23841         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
23842         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
23843         let "usedkb=usedkb-freekb"
23844         let "freekb=freekb/2"
23845         if let "freekb > 5000"; then
23846                 let "freekb=5000"
23847         fi
23848         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
23849         trap cleanup_805 EXIT
23850         mkdir $DIR/$tdir
23851         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
23852                 error "Can't set PFL layout"
23853         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
23854         rm -rf $DIR/$tdir || error "not able to remove"
23855         do_facet $SINGLEMDS zfs set quota=$old $fsset
23856         trap 0
23857 }
23858 run_test 805 "ZFS can remove from full fs"
23859
23860 # Size-on-MDS test
23861 check_lsom_data()
23862 {
23863         local file=$1
23864         local size=$($LFS getsom -s $file)
23865         local expect=$(stat -c %s $file)
23866
23867         [[ $size == $expect ]] ||
23868                 error "$file expected size: $expect, got: $size"
23869
23870         local blocks=$($LFS getsom -b $file)
23871         expect=$(stat -c %b $file)
23872         [[ $blocks == $expect ]] ||
23873                 error "$file expected blocks: $expect, got: $blocks"
23874 }
23875
23876 check_lsom_size()
23877 {
23878         local size=$($LFS getsom -s $1)
23879         local expect=$2
23880
23881         [[ $size == $expect ]] ||
23882                 error "$file expected size: $expect, got: $size"
23883 }
23884
23885 test_806() {
23886         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23887                 skip "Need MDS version at least 2.11.52"
23888
23889         local bs=1048576
23890
23891         touch $DIR/$tfile || error "touch $tfile failed"
23892
23893         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23894         save_lustre_params client "llite.*.xattr_cache" > $save
23895         lctl set_param llite.*.xattr_cache=0
23896         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23897
23898         # single-threaded write
23899         echo "Test SOM for single-threaded write"
23900         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
23901                 error "write $tfile failed"
23902         check_lsom_size $DIR/$tfile $bs
23903
23904         local num=32
23905         local size=$(($num * $bs))
23906         local offset=0
23907         local i
23908
23909         echo "Test SOM for single client multi-threaded($num) write"
23910         $TRUNCATE $DIR/$tfile 0
23911         for ((i = 0; i < $num; i++)); do
23912                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23913                 local pids[$i]=$!
23914                 offset=$((offset + $bs))
23915         done
23916         for (( i=0; i < $num; i++ )); do
23917                 wait ${pids[$i]}
23918         done
23919         check_lsom_size $DIR/$tfile $size
23920
23921         $TRUNCATE $DIR/$tfile 0
23922         for ((i = 0; i < $num; i++)); do
23923                 offset=$((offset - $bs))
23924                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23925                 local pids[$i]=$!
23926         done
23927         for (( i=0; i < $num; i++ )); do
23928                 wait ${pids[$i]}
23929         done
23930         check_lsom_size $DIR/$tfile $size
23931
23932         # multi-client writes
23933         num=$(get_node_count ${CLIENTS//,/ })
23934         size=$(($num * $bs))
23935         offset=0
23936         i=0
23937
23938         echo "Test SOM for multi-client ($num) writes"
23939         $TRUNCATE $DIR/$tfile 0
23940         for client in ${CLIENTS//,/ }; do
23941                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23942                 local pids[$i]=$!
23943                 i=$((i + 1))
23944                 offset=$((offset + $bs))
23945         done
23946         for (( i=0; i < $num; i++ )); do
23947                 wait ${pids[$i]}
23948         done
23949         check_lsom_size $DIR/$tfile $offset
23950
23951         i=0
23952         $TRUNCATE $DIR/$tfile 0
23953         for client in ${CLIENTS//,/ }; do
23954                 offset=$((offset - $bs))
23955                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23956                 local pids[$i]=$!
23957                 i=$((i + 1))
23958         done
23959         for (( i=0; i < $num; i++ )); do
23960                 wait ${pids[$i]}
23961         done
23962         check_lsom_size $DIR/$tfile $size
23963
23964         # verify truncate
23965         echo "Test SOM for truncate"
23966         $TRUNCATE $DIR/$tfile 1048576
23967         check_lsom_size $DIR/$tfile 1048576
23968         $TRUNCATE $DIR/$tfile 1234
23969         check_lsom_size $DIR/$tfile 1234
23970
23971         # verify SOM blocks count
23972         echo "Verify SOM block count"
23973         $TRUNCATE $DIR/$tfile 0
23974         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
23975                 error "failed to write file $tfile"
23976         check_lsom_data $DIR/$tfile
23977 }
23978 run_test 806 "Verify Lazy Size on MDS"
23979
23980 test_807() {
23981         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23982         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23983                 skip "Need MDS version at least 2.11.52"
23984
23985         # Registration step
23986         changelog_register || error "changelog_register failed"
23987         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
23988         changelog_users $SINGLEMDS | grep -q $cl_user ||
23989                 error "User $cl_user not found in changelog_users"
23990
23991         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23992         save_lustre_params client "llite.*.xattr_cache" > $save
23993         lctl set_param llite.*.xattr_cache=0
23994         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23995
23996         rm -rf $DIR/$tdir || error "rm $tdir failed"
23997         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23998         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
23999         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24000         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24001                 error "truncate $tdir/trunc failed"
24002
24003         local bs=1048576
24004         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24005                 error "write $tfile failed"
24006
24007         # multi-client wirtes
24008         local num=$(get_node_count ${CLIENTS//,/ })
24009         local offset=0
24010         local i=0
24011
24012         echo "Test SOM for multi-client ($num) writes"
24013         touch $DIR/$tfile || error "touch $tfile failed"
24014         $TRUNCATE $DIR/$tfile 0
24015         for client in ${CLIENTS//,/ }; do
24016                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24017                 local pids[$i]=$!
24018                 i=$((i + 1))
24019                 offset=$((offset + $bs))
24020         done
24021         for (( i=0; i < $num; i++ )); do
24022                 wait ${pids[$i]}
24023         done
24024
24025         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24026         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24027         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24028         check_lsom_data $DIR/$tdir/trunc
24029         check_lsom_data $DIR/$tdir/single_dd
24030         check_lsom_data $DIR/$tfile
24031
24032         rm -rf $DIR/$tdir
24033         # Deregistration step
24034         changelog_deregister || error "changelog_deregister failed"
24035 }
24036 run_test 807 "verify LSOM syncing tool"
24037
24038 check_som_nologged()
24039 {
24040         local lines=$($LFS changelog $FSNAME-MDT0000 |
24041                 grep 'x=trusted.som' | wc -l)
24042         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24043 }
24044
24045 test_808() {
24046         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24047                 skip "Need MDS version at least 2.11.55"
24048
24049         # Registration step
24050         changelog_register || error "changelog_register failed"
24051
24052         touch $DIR/$tfile || error "touch $tfile failed"
24053         check_som_nologged
24054
24055         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24056                 error "write $tfile failed"
24057         check_som_nologged
24058
24059         $TRUNCATE $DIR/$tfile 1234
24060         check_som_nologged
24061
24062         $TRUNCATE $DIR/$tfile 1048576
24063         check_som_nologged
24064
24065         # Deregistration step
24066         changelog_deregister || error "changelog_deregister failed"
24067 }
24068 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24069
24070 check_som_nodata()
24071 {
24072         $LFS getsom $1
24073         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24074 }
24075
24076 test_809() {
24077         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24078                 skip "Need MDS version at least 2.11.56"
24079
24080         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24081                 error "failed to create DoM-only file $DIR/$tfile"
24082         touch $DIR/$tfile || error "touch $tfile failed"
24083         check_som_nodata $DIR/$tfile
24084
24085         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24086                 error "write $tfile failed"
24087         check_som_nodata $DIR/$tfile
24088
24089         $TRUNCATE $DIR/$tfile 1234
24090         check_som_nodata $DIR/$tfile
24091
24092         $TRUNCATE $DIR/$tfile 4097
24093         check_som_nodata $DIR/$file
24094 }
24095 run_test 809 "Verify no SOM xattr store for DoM-only files"
24096
24097 test_810() {
24098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24099         $GSS && skip_env "could not run with gss"
24100         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24101                 skip "OST < 2.12.58 doesn't align checksum"
24102
24103         set_checksums 1
24104         stack_trap "set_checksums $ORIG_CSUM" EXIT
24105         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24106
24107         local csum
24108         local before
24109         local after
24110         for csum in $CKSUM_TYPES; do
24111                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24112                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24113                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24114                         eval set -- $i
24115                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24116                         before=$(md5sum $DIR/$tfile)
24117                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24118                         after=$(md5sum $DIR/$tfile)
24119                         [ "$before" == "$after" ] ||
24120                                 error "$csum: $before != $after bs=$1 seek=$2"
24121                 done
24122         done
24123 }
24124 run_test 810 "partial page writes on ZFS (LU-11663)"
24125
24126 test_812a() {
24127         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24128                 skip "OST < 2.12.51 doesn't support this fail_loc"
24129         [ "$SHARED_KEY" = true ] &&
24130                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24131
24132         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24133         # ensure ost1 is connected
24134         stat $DIR/$tfile >/dev/null || error "can't stat"
24135         wait_osc_import_state client ost1 FULL
24136         # no locks, no reqs to let the connection idle
24137         cancel_lru_locks osc
24138
24139         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24140 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24141         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24142         wait_osc_import_state client ost1 CONNECTING
24143         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24144
24145         stat $DIR/$tfile >/dev/null || error "can't stat file"
24146 }
24147 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24148
24149 test_812b() { # LU-12378
24150         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24151                 skip "OST < 2.12.51 doesn't support this fail_loc"
24152         [ "$SHARED_KEY" = true ] &&
24153                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24154
24155         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24156         # ensure ost1 is connected
24157         stat $DIR/$tfile >/dev/null || error "can't stat"
24158         wait_osc_import_state client ost1 FULL
24159         # no locks, no reqs to let the connection idle
24160         cancel_lru_locks osc
24161
24162         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24163 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24164         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24165         wait_osc_import_state client ost1 CONNECTING
24166         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24167
24168         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24169         wait_osc_import_state client ost1 IDLE
24170 }
24171 run_test 812b "do not drop no resend request for idle connect"
24172
24173 test_813() {
24174         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24175         [ -z "$file_heat_sav" ] && skip "no file heat support"
24176
24177         local readsample
24178         local writesample
24179         local readbyte
24180         local writebyte
24181         local readsample1
24182         local writesample1
24183         local readbyte1
24184         local writebyte1
24185
24186         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24187         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24188
24189         $LCTL set_param -n llite.*.file_heat=1
24190         echo "Turn on file heat"
24191         echo "Period second: $period_second, Decay percentage: $decay_pct"
24192
24193         echo "QQQQ" > $DIR/$tfile
24194         echo "QQQQ" > $DIR/$tfile
24195         echo "QQQQ" > $DIR/$tfile
24196         cat $DIR/$tfile > /dev/null
24197         cat $DIR/$tfile > /dev/null
24198         cat $DIR/$tfile > /dev/null
24199         cat $DIR/$tfile > /dev/null
24200
24201         local out=$($LFS heat_get $DIR/$tfile)
24202
24203         $LFS heat_get $DIR/$tfile
24204         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24205         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24206         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24207         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24208
24209         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24210         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24211         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24212         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24213
24214         sleep $((period_second + 3))
24215         echo "Sleep $((period_second + 3)) seconds..."
24216         # The recursion formula to calculate the heat of the file f is as
24217         # follow:
24218         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24219         # Where Hi is the heat value in the period between time points i*I and
24220         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24221         # to the weight of Ci.
24222         out=$($LFS heat_get $DIR/$tfile)
24223         $LFS heat_get $DIR/$tfile
24224         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24225         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24226         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24227         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24228
24229         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24230                 error "read sample ($readsample) is wrong"
24231         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24232                 error "write sample ($writesample) is wrong"
24233         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24234                 error "read bytes ($readbyte) is wrong"
24235         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24236                 error "write bytes ($writebyte) is wrong"
24237
24238         echo "QQQQ" > $DIR/$tfile
24239         echo "QQQQ" > $DIR/$tfile
24240         echo "QQQQ" > $DIR/$tfile
24241         cat $DIR/$tfile > /dev/null
24242         cat $DIR/$tfile > /dev/null
24243         cat $DIR/$tfile > /dev/null
24244         cat $DIR/$tfile > /dev/null
24245
24246         sleep $((period_second + 3))
24247         echo "Sleep $((period_second + 3)) seconds..."
24248
24249         out=$($LFS heat_get $DIR/$tfile)
24250         $LFS heat_get $DIR/$tfile
24251         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24252         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24253         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24254         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24255
24256         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24257                 4 * $decay_pct) / 100") -eq 1 ] ||
24258                 error "read sample ($readsample1) is wrong"
24259         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24260                 3 * $decay_pct) / 100") -eq 1 ] ||
24261                 error "write sample ($writesample1) is wrong"
24262         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24263                 20 * $decay_pct) / 100") -eq 1 ] ||
24264                 error "read bytes ($readbyte1) is wrong"
24265         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24266                 15 * $decay_pct) / 100") -eq 1 ] ||
24267                 error "write bytes ($writebyte1) is wrong"
24268
24269         echo "Turn off file heat for the file $DIR/$tfile"
24270         $LFS heat_set -o $DIR/$tfile
24271
24272         echo "QQQQ" > $DIR/$tfile
24273         echo "QQQQ" > $DIR/$tfile
24274         echo "QQQQ" > $DIR/$tfile
24275         cat $DIR/$tfile > /dev/null
24276         cat $DIR/$tfile > /dev/null
24277         cat $DIR/$tfile > /dev/null
24278         cat $DIR/$tfile > /dev/null
24279
24280         out=$($LFS heat_get $DIR/$tfile)
24281         $LFS heat_get $DIR/$tfile
24282         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24283         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24284         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24285         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24286
24287         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24288         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24289         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24290         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24291
24292         echo "Trun on file heat for the file $DIR/$tfile"
24293         $LFS heat_set -O $DIR/$tfile
24294
24295         echo "QQQQ" > $DIR/$tfile
24296         echo "QQQQ" > $DIR/$tfile
24297         echo "QQQQ" > $DIR/$tfile
24298         cat $DIR/$tfile > /dev/null
24299         cat $DIR/$tfile > /dev/null
24300         cat $DIR/$tfile > /dev/null
24301         cat $DIR/$tfile > /dev/null
24302
24303         out=$($LFS heat_get $DIR/$tfile)
24304         $LFS heat_get $DIR/$tfile
24305         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24306         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24307         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24308         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24309
24310         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24311         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24312         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24313         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24314
24315         $LFS heat_set -c $DIR/$tfile
24316         $LCTL set_param -n llite.*.file_heat=0
24317         echo "Turn off file heat support for the Lustre filesystem"
24318
24319         echo "QQQQ" > $DIR/$tfile
24320         echo "QQQQ" > $DIR/$tfile
24321         echo "QQQQ" > $DIR/$tfile
24322         cat $DIR/$tfile > /dev/null
24323         cat $DIR/$tfile > /dev/null
24324         cat $DIR/$tfile > /dev/null
24325         cat $DIR/$tfile > /dev/null
24326
24327         out=$($LFS heat_get $DIR/$tfile)
24328         $LFS heat_get $DIR/$tfile
24329         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24330         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24331         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24332         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24333
24334         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24335         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24336         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24337         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24338
24339         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24340         rm -f $DIR/$tfile
24341 }
24342 run_test 813 "File heat verfication"
24343
24344 test_814()
24345 {
24346         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24347         echo -n y >> $DIR/$tfile
24348         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24349         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24350 }
24351 run_test 814 "sparse cp works as expected (LU-12361)"
24352
24353 test_815()
24354 {
24355         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24356         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24357 }
24358 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24359
24360 test_816() {
24361         [ "$SHARED_KEY" = true ] &&
24362                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24363
24364         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24365         # ensure ost1 is connected
24366         stat $DIR/$tfile >/dev/null || error "can't stat"
24367         wait_osc_import_state client ost1 FULL
24368         # no locks, no reqs to let the connection idle
24369         cancel_lru_locks osc
24370         lru_resize_disable osc
24371         local before
24372         local now
24373         before=$($LCTL get_param -n \
24374                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24375
24376         wait_osc_import_state client ost1 IDLE
24377         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24378         now=$($LCTL get_param -n \
24379               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24380         [ $before == $now ] || error "lru_size changed $before != $now"
24381 }
24382 run_test 816 "do not reset lru_resize on idle reconnect"
24383
24384 cleanup_817() {
24385         umount $tmpdir
24386         exportfs -u localhost:$DIR/nfsexp
24387         rm -rf $DIR/nfsexp
24388 }
24389
24390 test_817() {
24391         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24392
24393         mkdir -p $DIR/nfsexp
24394         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24395                 error "failed to export nfs"
24396
24397         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24398         stack_trap cleanup_817 EXIT
24399
24400         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24401                 error "failed to mount nfs to $tmpdir"
24402
24403         cp /bin/true $tmpdir
24404         $DIR/nfsexp/true || error "failed to execute 'true' command"
24405 }
24406 run_test 817 "nfsd won't cache write lock for exec file"
24407
24408 test_818() {
24409         mkdir $DIR/$tdir
24410         $LFS setstripe -c1 -i0 $DIR/$tfile
24411         $LFS setstripe -c1 -i1 $DIR/$tfile
24412         stop $SINGLEMDS
24413         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24414         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24415         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24416                 error "start $SINGLEMDS failed"
24417         rm -rf $DIR/$tdir
24418 }
24419 run_test 818 "unlink with failed llog"
24420
24421 test_819a() {
24422         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24423         cancel_lru_locks osc
24424         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24425         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24426         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24427         rm -f $TDIR/$tfile
24428 }
24429 run_test 819a "too big niobuf in read"
24430
24431 test_819b() {
24432         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24433         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24434         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24435         cancel_lru_locks osc
24436         sleep 1
24437         rm -f $TDIR/$tfile
24438 }
24439 run_test 819b "too big niobuf in write"
24440
24441
24442 function test_820_start_ost() {
24443         sleep 5
24444
24445         for num in $(seq $OSTCOUNT); do
24446                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24447         done
24448 }
24449
24450 test_820() {
24451         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24452
24453         mkdir $DIR/$tdir
24454         umount_client $MOUNT || error "umount failed"
24455         for num in $(seq $OSTCOUNT); do
24456                 stop ost$num
24457         done
24458
24459         # mount client with no active OSTs
24460         # so that the client can't initialize max LOV EA size
24461         # from OSC notifications
24462         mount_client $MOUNT || error "mount failed"
24463         # delay OST starting to keep this 0 max EA size for a while
24464         test_820_start_ost &
24465
24466         # create a directory on MDS2
24467         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24468                 error "Failed to create directory"
24469         # open intent should update default EA size
24470         # see mdc_update_max_ea_from_body()
24471         # notice this is the very first RPC to MDS2
24472         cp /etc/services $DIR/$tdir/mds2 ||
24473                 error "Failed to copy files to mds$n"
24474 }
24475 run_test 820 "update max EA from open intent"
24476
24477 #
24478 # tests that do cleanup/setup should be run at the end
24479 #
24480
24481 test_900() {
24482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24483         local ls
24484
24485         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
24486         $LCTL set_param fail_loc=0x903
24487
24488         cancel_lru_locks MGC
24489
24490         FAIL_ON_ERROR=true cleanup
24491         FAIL_ON_ERROR=true setup
24492 }
24493 run_test 900 "umount should not race with any mgc requeue thread"
24494
24495 # LUS-6253/LU-11185
24496 test_901() {
24497         local oldc
24498         local newc
24499         local olds
24500         local news
24501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24502
24503         # some get_param have a bug to handle dot in param name
24504         cancel_lru_locks MGC
24505         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24506         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24507         umount_client $MOUNT || error "umount failed"
24508         mount_client $MOUNT || error "mount failed"
24509         cancel_lru_locks MGC
24510         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24511         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24512
24513         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
24514         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
24515
24516         return 0
24517 }
24518 run_test 901 "don't leak a mgc lock on client umount"
24519
24520 # LU-13377
24521 test_902() {
24522         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
24523                 skip "client does not have LU-13377 fix"
24524         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
24525         $LCTL set_param fail_loc=0x1415
24526         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24527         cancel_lru_locks osc
24528         rm -f $DIR/$tfile
24529 }
24530 run_test 902 "test short write doesn't hang lustre"
24531
24532 complete $SECONDS
24533 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
24534 check_and_cleanup_lustre
24535 if [ "$I_MOUNTED" != "yes" ]; then
24536         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
24537 fi
24538 exit_status