Whamcloud - gitweb
LU-12661 tests: skip sanity 817 if kernel version >= 4.14
[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_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 LUSTRE=${LUSTRE:-$(dirname $0)/..}
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 LU-12781
49         ALWAYS_EXCEPT+=" 17n     60a     133g    300f    272a"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64 fi
65
66 # skip nfs tests on kernels >= 4.14.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.14.0) ];then
68         # bug number:   LU-12661
69         ALWAYS_EXCEPT+=" 817"
70 fi
71
72 #                                  5          12          (min)"
73 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 300o"
74
75 if [ "$mds1_FSTYPE" = "zfs" ]; then
76         # bug number for skipped test:
77         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
78         #                                               13    (min)"
79         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
80 fi
81
82 # Get the SLES distro version
83 #
84 # Returns a version string that should only be used in comparing
85 # strings returned by version_code()
86 sles_version_code()
87 {
88         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
89
90         # All SuSE Linux versions have one decimal. version_code expects two
91         local sles_version=$version.0
92         version_code $sles_version
93 }
94
95 # Check if we are running on Ubuntu or SLES so we can make decisions on
96 # what tests to run
97 if [ -r /etc/SuSE-release ]; then
98         sles_version=$(sles_version_code)
99         [ $sles_version -lt $(version_code 11.4.0) ] &&
100                 # bug number for skipped test: LU-4341
101                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
102         [ $sles_version -lt $(version_code 12.0.0) ] &&
103                 # bug number for skipped test: LU-3703
104                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
105 elif [ -r /etc/os-release ]; then
106         if grep -qi ubuntu /etc/os-release; then
107                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
108                                                 -e 's/^VERSION=//p' \
109                                                 /etc/os-release |
110                                                 awk '{ print $1 }'))
111
112                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
113                         # bug number for skipped test:
114                         #                LU-10334 LU-10366
115                         ALWAYS_EXCEPT+=" 103a     410"
116                 fi
117         fi
118 fi
119
120 build_test_filter
121 FAIL_ON_ERROR=false
122
123 cleanup() {
124         echo -n "cln.."
125         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
126         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
127 }
128 setup() {
129         echo -n "mnt.."
130         load_modules
131         setupall || exit 10
132         echo "done"
133 }
134
135 check_swap_layouts_support()
136 {
137         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
138                 skip "Does not support layout lock."
139 }
140
141 check_and_setup_lustre
142 DIR=${DIR:-$MOUNT}
143 assert_DIR
144
145 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
146
147 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
148 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
149 rm -rf $DIR/[Rdfs][0-9]*
150
151 # $RUNAS_ID may get set incorrectly somewhere else
152 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
153         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
154
155 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
156
157 if [ "${ONLY}" = "MOUNT" ] ; then
158         echo "Lustre is up, please go on"
159         exit
160 fi
161
162 echo "preparing for tests involving mounts"
163 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
164 touch $EXT2_DEV
165 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
166 echo # add a newline after mke2fs.
167
168 umask 077
169
170 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
171 lctl set_param debug=-1 2> /dev/null || true
172 test_0a() {
173         touch $DIR/$tfile
174         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
175         rm $DIR/$tfile
176         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
177 }
178 run_test 0a "touch; rm ====================="
179
180 test_0b() {
181         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
182         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
183 }
184 run_test 0b "chmod 0755 $DIR ============================="
185
186 test_0c() {
187         $LCTL get_param mdc.*.import | grep "state: FULL" ||
188                 error "import not FULL"
189         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
190                 error "bad target"
191 }
192 run_test 0c "check import proc"
193
194 test_0d() { # LU-3397
195         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
196                 skip "proc exports not supported before 2.10.57"
197
198         local mgs_exp="mgs.MGS.exports"
199         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
200         local exp_client_nid
201         local exp_client_version
202         local exp_val
203         local imp_val
204         local temp_imp=$DIR/$tfile.import
205         local temp_exp=$DIR/$tfile.export
206
207         # save mgc import file to $temp_imp
208         $LCTL get_param mgc.*.import | tee $temp_imp
209         # Check if client uuid is found in MGS export
210         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
211                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
212                         $client_uuid ] &&
213                         break;
214         done
215         # save mgs export file to $temp_exp
216         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
217
218         # Compare the value of field "connect_flags"
219         imp_val=$(grep "connect_flags" $temp_imp)
220         exp_val=$(grep "connect_flags" $temp_exp)
221         [ "$exp_val" == "$imp_val" ] ||
222                 error "export flags '$exp_val' != import flags '$imp_val'"
223
224         # Compare the value of client version
225         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
226         exp_val=$(version_code $exp_client_version)
227         imp_val=$CLIENT_VERSION
228         [ "$exp_val" == "$imp_val" ] ||
229                 error "export client version '$exp_val' != '$imp_val'"
230 }
231 run_test 0d "check export proc ============================="
232
233 test_1() {
234         test_mkdir $DIR/$tdir
235         test_mkdir $DIR/$tdir/d2
236         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
237         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
238         rmdir $DIR/$tdir/d2
239         rmdir $DIR/$tdir
240         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
241 }
242 run_test 1 "mkdir; remkdir; rmdir"
243
244 test_2() {
245         test_mkdir $DIR/$tdir
246         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
247         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
248         rm -r $DIR/$tdir
249         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
250 }
251 run_test 2 "mkdir; touch; rmdir; check file"
252
253 test_3() {
254         test_mkdir $DIR/$tdir
255         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
256         touch $DIR/$tdir/$tfile
257         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
258         rm -r $DIR/$tdir
259         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
260 }
261 run_test 3 "mkdir; touch; rmdir; check dir"
262
263 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
264 test_4() {
265         test_mkdir -i 1 $DIR/$tdir
266
267         touch $DIR/$tdir/$tfile ||
268                 error "Create file under remote directory failed"
269
270         rmdir $DIR/$tdir &&
271                 error "Expect error removing in-use dir $DIR/$tdir"
272
273         test -d $DIR/$tdir || error "Remote directory disappeared"
274
275         rm -rf $DIR/$tdir || error "remove remote dir error"
276 }
277 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
278
279 test_5() {
280         test_mkdir $DIR/$tdir
281         test_mkdir $DIR/$tdir/d2
282         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
283         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
284         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
285 }
286 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
287
288 test_6a() {
289         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
290         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
291         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
292                 error "$tfile does not have perm 0666 or UID $UID"
293         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
294         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
295                 error "$tfile should be 0666 and owned by UID $UID"
296 }
297 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
298
299 test_6c() {
300         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
301
302         touch $DIR/$tfile
303         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
304         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
305                 error "$tfile should be owned by UID $RUNAS_ID"
306         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
307         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
308                 error "$tfile should be owned by UID $RUNAS_ID"
309 }
310 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
311
312 test_6e() {
313         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
314
315         touch $DIR/$tfile
316         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
317         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
318                 error "$tfile should be owned by GID $UID"
319         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
320         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
321                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
322 }
323 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
324
325 test_6g() {
326         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
327
328         test_mkdir $DIR/$tdir
329         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
330         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
331         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
332         test_mkdir $DIR/$tdir/d/subdir
333         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
334                 error "$tdir/d/subdir should be GID $RUNAS_GID"
335         if [[ $MDSCOUNT -gt 1 ]]; then
336                 # check remote dir sgid inherite
337                 $LFS mkdir -i 0 $DIR/$tdir.local ||
338                         error "mkdir $tdir.local failed"
339                 chmod g+s $DIR/$tdir.local ||
340                         error "chmod $tdir.local failed"
341                 chgrp $RUNAS_GID $DIR/$tdir.local ||
342                         error "chgrp $tdir.local failed"
343                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
344                         error "mkdir $tdir.remote failed"
345                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
346                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
347                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
348                         error "$tdir.remote should be mode 02755"
349         fi
350 }
351 run_test 6g "verify new dir in sgid dir inherits group"
352
353 test_6h() { # bug 7331
354         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
355
356         touch $DIR/$tfile || error "touch failed"
357         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
358         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
359                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
360         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
361                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
362 }
363 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
364
365 test_7a() {
366         test_mkdir $DIR/$tdir
367         $MCREATE $DIR/$tdir/$tfile
368         chmod 0666 $DIR/$tdir/$tfile
369         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
370                 error "$tdir/$tfile should be mode 0666"
371 }
372 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
373
374 test_7b() {
375         if [ ! -d $DIR/$tdir ]; then
376                 test_mkdir $DIR/$tdir
377         fi
378         $MCREATE $DIR/$tdir/$tfile
379         echo -n foo > $DIR/$tdir/$tfile
380         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
381         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
382 }
383 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
384
385 test_8() {
386         test_mkdir $DIR/$tdir
387         touch $DIR/$tdir/$tfile
388         chmod 0666 $DIR/$tdir/$tfile
389         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
390                 error "$tfile mode not 0666"
391 }
392 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
393
394 test_9() {
395         test_mkdir $DIR/$tdir
396         test_mkdir $DIR/$tdir/d2
397         test_mkdir $DIR/$tdir/d2/d3
398         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
399 }
400 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
401
402 test_10() {
403         test_mkdir $DIR/$tdir
404         test_mkdir $DIR/$tdir/d2
405         touch $DIR/$tdir/d2/$tfile
406         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
407                 error "$tdir/d2/$tfile not a file"
408 }
409 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
410
411 test_11() {
412         test_mkdir $DIR/$tdir
413         test_mkdir $DIR/$tdir/d2
414         chmod 0666 $DIR/$tdir/d2
415         chmod 0705 $DIR/$tdir/d2
416         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
417                 error "$tdir/d2 mode not 0705"
418 }
419 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
420
421 test_12() {
422         test_mkdir $DIR/$tdir
423         touch $DIR/$tdir/$tfile
424         chmod 0666 $DIR/$tdir/$tfile
425         chmod 0654 $DIR/$tdir/$tfile
426         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
427                 error "$tdir/d2 mode not 0654"
428 }
429 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
430
431 test_13() {
432         test_mkdir $DIR/$tdir
433         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
434         >  $DIR/$tdir/$tfile
435         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
436                 error "$tdir/$tfile size not 0 after truncate"
437 }
438 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
439
440 test_14() {
441         test_mkdir $DIR/$tdir
442         touch $DIR/$tdir/$tfile
443         rm $DIR/$tdir/$tfile
444         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
445 }
446 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
447
448 test_15() {
449         test_mkdir $DIR/$tdir
450         touch $DIR/$tdir/$tfile
451         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
452         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
453                 error "$tdir/${tfile_2} not a file after rename"
454         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
455 }
456 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
457
458 test_16() {
459         test_mkdir $DIR/$tdir
460         touch $DIR/$tdir/$tfile
461         rm -rf $DIR/$tdir/$tfile
462         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
463 }
464 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
465
466 test_17a() {
467         test_mkdir $DIR/$tdir
468         touch $DIR/$tdir/$tfile
469         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
470         ls -l $DIR/$tdir
471         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
472                 error "$tdir/l-exist not a symlink"
473         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
474                 error "$tdir/l-exist not referencing a file"
475         rm -f $DIR/$tdir/l-exist
476         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
477 }
478 run_test 17a "symlinks: create, remove (real)"
479
480 test_17b() {
481         test_mkdir $DIR/$tdir
482         ln -s no-such-file $DIR/$tdir/l-dangle
483         ls -l $DIR/$tdir
484         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
485                 error "$tdir/l-dangle not referencing no-such-file"
486         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
487                 error "$tdir/l-dangle not referencing non-existent file"
488         rm -f $DIR/$tdir/l-dangle
489         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
490 }
491 run_test 17b "symlinks: create, remove (dangling)"
492
493 test_17c() { # bug 3440 - don't save failed open RPC for replay
494         test_mkdir $DIR/$tdir
495         ln -s foo $DIR/$tdir/$tfile
496         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
497 }
498 run_test 17c "symlinks: open dangling (should return error)"
499
500 test_17d() {
501         test_mkdir $DIR/$tdir
502         ln -s foo $DIR/$tdir/$tfile
503         touch $DIR/$tdir/$tfile || error "creating to new symlink"
504 }
505 run_test 17d "symlinks: create dangling"
506
507 test_17e() {
508         test_mkdir $DIR/$tdir
509         local foo=$DIR/$tdir/$tfile
510         ln -s $foo $foo || error "create symlink failed"
511         ls -l $foo || error "ls -l failed"
512         ls $foo && error "ls not failed" || true
513 }
514 run_test 17e "symlinks: create recursive symlink (should return error)"
515
516 test_17f() {
517         test_mkdir $DIR/$tdir
518         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
519         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
520         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
521         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
522         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
523         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
524         ls -l  $DIR/$tdir
525 }
526 run_test 17f "symlinks: long and very long symlink name"
527
528 # str_repeat(S, N) generate a string that is string S repeated N times
529 str_repeat() {
530         local s=$1
531         local n=$2
532         local ret=''
533         while [ $((n -= 1)) -ge 0 ]; do
534                 ret=$ret$s
535         done
536         echo $ret
537 }
538
539 # Long symlinks and LU-2241
540 test_17g() {
541         test_mkdir $DIR/$tdir
542         local TESTS="59 60 61 4094 4095"
543
544         # Fix for inode size boundary in 2.1.4
545         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
546                 TESTS="4094 4095"
547
548         # Patch not applied to 2.2 or 2.3 branches
549         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
550         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
551                 TESTS="4094 4095"
552
553         # skip long symlink name for rhel6.5.
554         # rhel6.5 has a limit (PATH_MAX - sizeof(struct filename))
555         grep -q '6.5' /etc/redhat-release &>/dev/null &&
556                 TESTS="59 60 61 4062 4063"
557
558         for i in $TESTS; do
559                 local SYMNAME=$(str_repeat 'x' $i)
560                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
561                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
562         done
563 }
564 run_test 17g "symlinks: really long symlink name and inode boundaries"
565
566 test_17h() { #bug 17378
567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
568         remote_mds_nodsh && skip "remote MDS with nodsh"
569
570         local mdt_idx
571
572         test_mkdir $DIR/$tdir
573         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
574         $LFS setstripe -c -1 $DIR/$tdir
575         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
576         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
577         touch $DIR/$tdir/$tfile || true
578 }
579 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
580
581 test_17i() { #bug 20018
582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
583         remote_mds_nodsh && skip "remote MDS with nodsh"
584
585         local foo=$DIR/$tdir/$tfile
586         local mdt_idx
587
588         test_mkdir -c1 $DIR/$tdir
589         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
590         ln -s $foo $foo || error "create symlink failed"
591 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
592         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
593         ls -l $foo && error "error not detected"
594         return 0
595 }
596 run_test 17i "don't panic on short symlink (should return error)"
597
598 test_17k() { #bug 22301
599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
600         [[ -z "$(which rsync 2>/dev/null)" ]] &&
601                 skip "no rsync command"
602         rsync --help | grep -q xattr ||
603                 skip_env "$(rsync --version | head -n1) does not support xattrs"
604         test_mkdir $DIR/$tdir
605         test_mkdir $DIR/$tdir.new
606         touch $DIR/$tdir/$tfile
607         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
608         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
609                 error "rsync failed with xattrs enabled"
610 }
611 run_test 17k "symlinks: rsync with xattrs enabled"
612
613 test_17l() { # LU-279
614         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
615                 skip "no getfattr command"
616
617         test_mkdir $DIR/$tdir
618         touch $DIR/$tdir/$tfile
619         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
620         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
621                 # -h to not follow symlinks. -m '' to list all the xattrs.
622                 # grep to remove first line: '# file: $path'.
623                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
624                 do
625                         lgetxattr_size_check $path $xattr ||
626                                 error "lgetxattr_size_check $path $xattr failed"
627                 done
628         done
629 }
630 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
631
632 # LU-1540
633 test_17m() {
634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
635         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
636         remote_mds_nodsh && skip "remote MDS with nodsh"
637         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
638         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
639                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
640
641         local short_sym="0123456789"
642         local wdir=$DIR/$tdir
643         local i
644
645         test_mkdir $wdir
646         long_sym=$short_sym
647         # create a long symlink file
648         for ((i = 0; i < 4; ++i)); do
649                 long_sym=${long_sym}${long_sym}
650         done
651
652         echo "create 512 short and long symlink files under $wdir"
653         for ((i = 0; i < 256; ++i)); do
654                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
655                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
656         done
657
658         echo "erase them"
659         rm -f $wdir/*
660         sync
661         wait_delete_completed
662
663         echo "recreate the 512 symlink files with a shorter string"
664         for ((i = 0; i < 512; ++i)); do
665                 # rewrite the symlink file with a shorter string
666                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
667                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
668         done
669
670         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
671         local devname=$(mdsdevname $mds_index)
672
673         echo "stop and checking mds${mds_index}:"
674         # e2fsck should not return error
675         stop mds${mds_index}
676         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
677         rc=$?
678
679         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
680                 error "start mds${mds_index} failed"
681         df $MOUNT > /dev/null 2>&1
682         [ $rc -eq 0 ] ||
683                 error "e2fsck detected error for short/long symlink: rc=$rc"
684         rm -f $wdir/*
685 }
686 run_test 17m "run e2fsck against MDT which contains short/long symlink"
687
688 check_fs_consistency_17n() {
689         local mdt_index
690         local rc=0
691
692         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
693         # so it only check MDT1/MDT2 instead of all of MDTs.
694         for mdt_index in 1 2; do
695                 local devname=$(mdsdevname $mdt_index)
696                 # e2fsck should not return error
697                 stop mds${mdt_index}
698                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
699                         rc=$((rc + $?))
700
701                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
702                         error "mount mds$mdt_index failed"
703                 df $MOUNT > /dev/null 2>&1
704         done
705         return $rc
706 }
707
708 test_17n() {
709         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
711         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
712         remote_mds_nodsh && skip "remote MDS with nodsh"
713         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
714         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
715                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
716
717         local i
718
719         test_mkdir $DIR/$tdir
720         for ((i=0; i<10; i++)); do
721                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
722                         error "create remote dir error $i"
723                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
724                         error "create files under remote dir failed $i"
725         done
726
727         check_fs_consistency_17n ||
728                 error "e2fsck report error after create files under remote dir"
729
730         for ((i = 0; i < 10; i++)); do
731                 rm -rf $DIR/$tdir/remote_dir_${i} ||
732                         error "destroy remote dir error $i"
733         done
734
735         check_fs_consistency_17n ||
736                 error "e2fsck report error after unlink files under remote dir"
737
738         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
739                 skip "lustre < 2.4.50 does not support migrate mv"
740
741         for ((i = 0; i < 10; i++)); do
742                 mkdir -p $DIR/$tdir/remote_dir_${i}
743                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
744                         error "create files under remote dir failed $i"
745                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
746                         error "migrate remote dir error $i"
747         done
748         check_fs_consistency_17n || error "e2fsck report error after migration"
749
750         for ((i = 0; i < 10; i++)); do
751                 rm -rf $DIR/$tdir/remote_dir_${i} ||
752                         error "destroy remote dir error $i"
753         done
754
755         check_fs_consistency_17n || error "e2fsck report error after unlink"
756 }
757 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
758
759 test_17o() {
760         remote_mds_nodsh && skip "remote MDS with nodsh"
761         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
762                 skip "Need MDS version at least 2.3.64"
763
764         local wdir=$DIR/${tdir}o
765         local mdt_index
766         local rc=0
767
768         test_mkdir $wdir
769         touch $wdir/$tfile
770         mdt_index=$($LFS getstripe -m $wdir/$tfile)
771         mdt_index=$((mdt_index + 1))
772
773         cancel_lru_locks mdc
774         #fail mds will wait the failover finish then set
775         #following fail_loc to avoid interfer the recovery process.
776         fail mds${mdt_index}
777
778         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
779         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
780         ls -l $wdir/$tfile && rc=1
781         do_facet mds${mdt_index} lctl set_param fail_loc=0
782         [[ $rc -eq 0 ]] || error "stat file should fail"
783 }
784 run_test 17o "stat file with incompat LMA feature"
785
786 test_18() {
787         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
788         ls $DIR || error "Failed to ls $DIR: $?"
789 }
790 run_test 18 "touch .../f ; ls ... =============================="
791
792 test_19a() {
793         touch $DIR/$tfile
794         ls -l $DIR
795         rm $DIR/$tfile
796         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
797 }
798 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
799
800 test_19b() {
801         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
802 }
803 run_test 19b "ls -l .../f19 (should return error) =============="
804
805 test_19c() {
806         [ $RUNAS_ID -eq $UID ] &&
807                 skip_env "RUNAS_ID = UID = $UID -- skipping"
808
809         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
810 }
811 run_test 19c "$RUNAS touch .../f19 (should return error) =="
812
813 test_19d() {
814         cat $DIR/f19 && error || true
815 }
816 run_test 19d "cat .../f19 (should return error) =============="
817
818 test_20() {
819         touch $DIR/$tfile
820         rm $DIR/$tfile
821         touch $DIR/$tfile
822         rm $DIR/$tfile
823         touch $DIR/$tfile
824         rm $DIR/$tfile
825         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
826 }
827 run_test 20 "touch .../f ; ls -l ..."
828
829 test_21() {
830         test_mkdir $DIR/$tdir
831         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
832         ln -s dangle $DIR/$tdir/link
833         echo foo >> $DIR/$tdir/link
834         cat $DIR/$tdir/dangle
835         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
836         $CHECKSTAT -f -t file $DIR/$tdir/link ||
837                 error "$tdir/link not linked to a file"
838 }
839 run_test 21 "write to dangling link"
840
841 test_22() {
842         local wdir=$DIR/$tdir
843         test_mkdir $wdir
844         chown $RUNAS_ID:$RUNAS_GID $wdir
845         (cd $wdir || error "cd $wdir failed";
846                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
847                 $RUNAS tar xf -)
848         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
849         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
850         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
851                 error "checkstat -u failed"
852 }
853 run_test 22 "unpack tar archive as non-root user"
854
855 # was test_23
856 test_23a() {
857         test_mkdir $DIR/$tdir
858         local file=$DIR/$tdir/$tfile
859
860         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
861         openfile -f O_CREAT:O_EXCL $file &&
862                 error "$file recreate succeeded" || true
863 }
864 run_test 23a "O_CREAT|O_EXCL in subdir"
865
866 test_23b() { # bug 18988
867         test_mkdir $DIR/$tdir
868         local file=$DIR/$tdir/$tfile
869
870         rm -f $file
871         echo foo > $file || error "write filed"
872         echo bar >> $file || error "append filed"
873         $CHECKSTAT -s 8 $file || error "wrong size"
874         rm $file
875 }
876 run_test 23b "O_APPEND check"
877
878 # LU-9409, size with O_APPEND and tiny writes
879 test_23c() {
880         local file=$DIR/$tfile
881
882         # single dd
883         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
884         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
885         rm -f $file
886
887         # racing tiny writes
888         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
889         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
890         wait
891         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
892         rm -f $file
893
894         #racing tiny & normal writes
895         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
896         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
897         wait
898         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
899         rm -f $file
900
901         #racing tiny & normal writes 2, ugly numbers
902         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
903         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
904         wait
905         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
906         rm -f $file
907 }
908 run_test 23c "O_APPEND size checks for tiny writes"
909
910 # LU-11069 file offset is correct after appending writes
911 test_23d() {
912         local file=$DIR/$tfile
913         local offset
914
915         echo CentaurHauls > $file
916         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
917         if ((offset != 26)); then
918                 error "wrong offset, expected 26, got '$offset'"
919         fi
920 }
921 run_test 23d "file offset is correct after appending writes"
922
923 # rename sanity
924 test_24a() {
925         echo '-- same directory rename'
926         test_mkdir $DIR/$tdir
927         touch $DIR/$tdir/$tfile.1
928         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
929         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
930 }
931 run_test 24a "rename file to non-existent target"
932
933 test_24b() {
934         test_mkdir $DIR/$tdir
935         touch $DIR/$tdir/$tfile.{1,2}
936         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
937         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
938         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
939 }
940 run_test 24b "rename file to existing target"
941
942 test_24c() {
943         test_mkdir $DIR/$tdir
944         test_mkdir $DIR/$tdir/d$testnum.1
945         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
946         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
947         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
948 }
949 run_test 24c "rename directory to non-existent target"
950
951 test_24d() {
952         test_mkdir -c1 $DIR/$tdir
953         test_mkdir -c1 $DIR/$tdir/d$testnum.1
954         test_mkdir -c1 $DIR/$tdir/d$testnum.2
955         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
956         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
957         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
958 }
959 run_test 24d "rename directory to existing target"
960
961 test_24e() {
962         echo '-- cross directory renames --'
963         test_mkdir $DIR/R5a
964         test_mkdir $DIR/R5b
965         touch $DIR/R5a/f
966         mv $DIR/R5a/f $DIR/R5b/g
967         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
968         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
969 }
970 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
971
972 test_24f() {
973         test_mkdir $DIR/R6a
974         test_mkdir $DIR/R6b
975         touch $DIR/R6a/f $DIR/R6b/g
976         mv $DIR/R6a/f $DIR/R6b/g
977         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
978         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
979 }
980 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
981
982 test_24g() {
983         test_mkdir $DIR/R7a
984         test_mkdir $DIR/R7b
985         test_mkdir $DIR/R7a/d
986         mv $DIR/R7a/d $DIR/R7b/e
987         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
988         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
989 }
990 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
991
992 test_24h() {
993         test_mkdir -c1 $DIR/R8a
994         test_mkdir -c1 $DIR/R8b
995         test_mkdir -c1 $DIR/R8a/d
996         test_mkdir -c1 $DIR/R8b/e
997         mrename $DIR/R8a/d $DIR/R8b/e
998         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
999         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1000 }
1001 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1002
1003 test_24i() {
1004         echo "-- rename error cases"
1005         test_mkdir $DIR/R9
1006         test_mkdir $DIR/R9/a
1007         touch $DIR/R9/f
1008         mrename $DIR/R9/f $DIR/R9/a
1009         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1010         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1011         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1012 }
1013 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1014
1015 test_24j() {
1016         test_mkdir $DIR/R10
1017         mrename $DIR/R10/f $DIR/R10/g
1018         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1019         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1020         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1021 }
1022 run_test 24j "source does not exist ============================"
1023
1024 test_24k() {
1025         test_mkdir $DIR/R11a
1026         test_mkdir $DIR/R11a/d
1027         touch $DIR/R11a/f
1028         mv $DIR/R11a/f $DIR/R11a/d
1029         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1030         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1031 }
1032 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1033
1034 # bug 2429 - rename foo foo foo creates invalid file
1035 test_24l() {
1036         f="$DIR/f24l"
1037         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1038 }
1039 run_test 24l "Renaming a file to itself ========================"
1040
1041 test_24m() {
1042         f="$DIR/f24m"
1043         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1044         # on ext3 this does not remove either the source or target files
1045         # though the "expected" operation would be to remove the source
1046         $CHECKSTAT -t file ${f} || error "${f} missing"
1047         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1048 }
1049 run_test 24m "Renaming a file to a hard link to itself ========="
1050
1051 test_24n() {
1052     f="$DIR/f24n"
1053     # this stats the old file after it was renamed, so it should fail
1054     touch ${f}
1055     $CHECKSTAT ${f} || error "${f} missing"
1056     mv ${f} ${f}.rename
1057     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1058     $CHECKSTAT -a ${f} || error "${f} exists"
1059 }
1060 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1061
1062 test_24o() {
1063         test_mkdir $DIR/$tdir
1064         rename_many -s random -v -n 10 $DIR/$tdir
1065 }
1066 run_test 24o "rename of files during htree split"
1067
1068 test_24p() {
1069         test_mkdir $DIR/R12a
1070         test_mkdir $DIR/R12b
1071         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1072         mrename $DIR/R12a $DIR/R12b
1073         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1074         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1075         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1076         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1077 }
1078 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1079
1080 cleanup_multiop_pause() {
1081         trap 0
1082         kill -USR1 $MULTIPID
1083 }
1084
1085 test_24q() {
1086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1087
1088         test_mkdir $DIR/R13a
1089         test_mkdir $DIR/R13b
1090         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1091         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1092         MULTIPID=$!
1093
1094         trap cleanup_multiop_pause EXIT
1095         mrename $DIR/R13a $DIR/R13b
1096         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1097         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1098         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1099         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1100         cleanup_multiop_pause
1101         wait $MULTIPID || error "multiop close failed"
1102 }
1103 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1104
1105 test_24r() { #bug 3789
1106         test_mkdir $DIR/R14a
1107         test_mkdir $DIR/R14a/b
1108         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1109         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1110         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1111 }
1112 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1113
1114 test_24s() {
1115         test_mkdir $DIR/R15a
1116         test_mkdir $DIR/R15a/b
1117         test_mkdir $DIR/R15a/b/c
1118         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1119         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1120         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1121 }
1122 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1123 test_24t() {
1124         test_mkdir $DIR/R16a
1125         test_mkdir $DIR/R16a/b
1126         test_mkdir $DIR/R16a/b/c
1127         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1128         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1129         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1130 }
1131 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1132
1133 test_24u() { # bug12192
1134         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1135         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1136 }
1137 run_test 24u "create stripe file"
1138
1139 simple_cleanup_common() {
1140         local rc=0
1141         trap 0
1142         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1143
1144         local start=$SECONDS
1145         rm -rf $DIR/$tdir
1146         rc=$?
1147         wait_delete_completed
1148         echo "cleanup time $((SECONDS - start))"
1149         return $rc
1150 }
1151
1152 max_pages_per_rpc() {
1153         local mdtname="$(printf "MDT%04x" ${1:-0})"
1154         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1155 }
1156
1157 test_24v() {
1158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1159
1160         local nrfiles=${COUNT:-100000}
1161         local fname="$DIR/$tdir/$tfile"
1162
1163         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1164         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1165
1166         test_mkdir "$(dirname $fname)"
1167         # assume MDT0000 has the fewest inodes
1168         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1169         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1170         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1171
1172         trap simple_cleanup_common EXIT
1173
1174         createmany -m "$fname" $nrfiles
1175
1176         cancel_lru_locks mdc
1177         lctl set_param mdc.*.stats clear
1178
1179         # was previously test_24D: LU-6101
1180         # readdir() returns correct number of entries after cursor reload
1181         local num_ls=$(ls $DIR/$tdir | wc -l)
1182         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1183         local num_all=$(ls -a $DIR/$tdir | wc -l)
1184         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1185                 [ $num_all -ne $((nrfiles + 2)) ]; then
1186                         error "Expected $nrfiles files, got $num_ls " \
1187                                 "($num_uniq unique $num_all .&..)"
1188         fi
1189         # LU-5 large readdir
1190         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1191         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1192         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1193         # take into account of overhead in lu_dirpage header and end mark in
1194         # each page, plus one in rpc_num calculation.
1195         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1196         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1197         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1198         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1199         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1200         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1201         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1202         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1203                 error "large readdir doesn't take effect: " \
1204                       "$mds_readpage should be about $rpc_max"
1205
1206         simple_cleanup_common
1207 }
1208 run_test 24v "list large directory (test hash collision, b=17560)"
1209
1210 test_24w() { # bug21506
1211         SZ1=234852
1212         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1213         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1214         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1215         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1216         [[ "$SZ1" -eq "$SZ2" ]] ||
1217                 error "Error reading at the end of the file $tfile"
1218 }
1219 run_test 24w "Reading a file larger than 4Gb"
1220
1221 test_24x() {
1222         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1224         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1225                 skip "Need MDS version at least 2.7.56"
1226
1227         local MDTIDX=1
1228         local remote_dir=$DIR/$tdir/remote_dir
1229
1230         test_mkdir $DIR/$tdir
1231         $LFS mkdir -i $MDTIDX $remote_dir ||
1232                 error "create remote directory failed"
1233
1234         test_mkdir $DIR/$tdir/src_dir
1235         touch $DIR/$tdir/src_file
1236         test_mkdir $remote_dir/tgt_dir
1237         touch $remote_dir/tgt_file
1238
1239         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1240                 error "rename dir cross MDT failed!"
1241
1242         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1243                 error "rename file cross MDT failed!"
1244
1245         touch $DIR/$tdir/ln_file
1246         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1247                 error "ln file cross MDT failed"
1248
1249         rm -rf $DIR/$tdir || error "Can not delete directories"
1250 }
1251 run_test 24x "cross MDT rename/link"
1252
1253 test_24y() {
1254         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1256
1257         local remote_dir=$DIR/$tdir/remote_dir
1258         local mdtidx=1
1259
1260         test_mkdir $DIR/$tdir
1261         $LFS mkdir -i $mdtidx $remote_dir ||
1262                 error "create remote directory failed"
1263
1264         test_mkdir $remote_dir/src_dir
1265         touch $remote_dir/src_file
1266         test_mkdir $remote_dir/tgt_dir
1267         touch $remote_dir/tgt_file
1268
1269         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1270                 error "rename subdir in the same remote dir failed!"
1271
1272         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1273                 error "rename files in the same remote dir failed!"
1274
1275         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1276                 error "link files in the same remote dir failed!"
1277
1278         rm -rf $DIR/$tdir || error "Can not delete directories"
1279 }
1280 run_test 24y "rename/link on the same dir should succeed"
1281
1282 test_24z() {
1283         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1284         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1285                 skip "Need MDS version at least 2.12.51"
1286
1287         local index
1288
1289         for index in 0 1; do
1290                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1291                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1292         done
1293
1294         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1295
1296         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1297         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1298
1299         local mdts=$(comma_list $(mdts_nodes))
1300
1301         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1302         stack_trap "do_nodes $mdts $LCTL \
1303                 set_param mdt.*.enable_remote_rename=1" EXIT
1304
1305         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1306
1307         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1308         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1309 }
1310 run_test 24z "cross-MDT rename is done as cp"
1311
1312 test_24A() { # LU-3182
1313         local NFILES=5000
1314
1315         rm -rf $DIR/$tdir
1316         test_mkdir $DIR/$tdir
1317         trap simple_cleanup_common EXIT
1318         createmany -m $DIR/$tdir/$tfile $NFILES
1319         local t=$(ls $DIR/$tdir | wc -l)
1320         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1321         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1322         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1323            [ $v -ne $((NFILES + 2)) ] ; then
1324                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1325         fi
1326
1327         simple_cleanup_common || error "Can not delete directories"
1328 }
1329 run_test 24A "readdir() returns correct number of entries."
1330
1331 test_24B() { # LU-4805
1332         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1333
1334         local count
1335
1336         test_mkdir $DIR/$tdir
1337         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1338                 error "create striped dir failed"
1339
1340         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1341         [ $count -eq 2 ] || error "Expected 2, got $count"
1342
1343         touch $DIR/$tdir/striped_dir/a
1344
1345         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1346         [ $count -eq 3 ] || error "Expected 3, got $count"
1347
1348         touch $DIR/$tdir/striped_dir/.f
1349
1350         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1351         [ $count -eq 4 ] || error "Expected 4, got $count"
1352
1353         rm -rf $DIR/$tdir || error "Can not delete directories"
1354 }
1355 run_test 24B "readdir for striped dir return correct number of entries"
1356
1357 test_24C() {
1358         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1359
1360         mkdir $DIR/$tdir
1361         mkdir $DIR/$tdir/d0
1362         mkdir $DIR/$tdir/d1
1363
1364         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1365                 error "create striped dir failed"
1366
1367         cd $DIR/$tdir/d0/striped_dir
1368
1369         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1370         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1371         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1372
1373         [ "$d0_ino" = "$parent_ino" ] ||
1374                 error ".. wrong, expect $d0_ino, get $parent_ino"
1375
1376         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1377                 error "mv striped dir failed"
1378
1379         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1380
1381         [ "$d1_ino" = "$parent_ino" ] ||
1382                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1383 }
1384 run_test 24C "check .. in striped dir"
1385
1386 test_24E() {
1387         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1389
1390         mkdir -p $DIR/$tdir
1391         mkdir $DIR/$tdir/src_dir
1392         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1393                 error "create remote source failed"
1394
1395         touch $DIR/$tdir/src_dir/src_child/a
1396
1397         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1398                 error "create remote target dir failed"
1399
1400         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1401                 error "create remote target child failed"
1402
1403         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1404                 error "rename dir cross MDT failed!"
1405
1406         find $DIR/$tdir
1407
1408         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1409                 error "src_child still exists after rename"
1410
1411         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1412                 error "missing file(a) after rename"
1413
1414         rm -rf $DIR/$tdir || error "Can not delete directories"
1415 }
1416 run_test 24E "cross MDT rename/link"
1417
1418 test_24F () {
1419         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1420
1421         local repeats=1000
1422         [ "$SLOW" = "no" ] && repeats=100
1423
1424         mkdir -p $DIR/$tdir
1425
1426         echo "$repeats repeats"
1427         for ((i = 0; i < repeats; i++)); do
1428                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1429                 touch $DIR/$tdir/test/a || error "touch fails"
1430                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1431                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1432         done
1433
1434         true
1435 }
1436 run_test 24F "hash order vs readdir (LU-11330)"
1437
1438 test_25a() {
1439         echo '== symlink sanity ============================================='
1440
1441         test_mkdir $DIR/d25
1442         ln -s d25 $DIR/s25
1443         touch $DIR/s25/foo ||
1444                 error "File creation in symlinked directory failed"
1445 }
1446 run_test 25a "create file in symlinked directory ==============="
1447
1448 test_25b() {
1449         [ ! -d $DIR/d25 ] && test_25a
1450         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1451 }
1452 run_test 25b "lookup file in symlinked directory ==============="
1453
1454 test_26a() {
1455         test_mkdir $DIR/d26
1456         test_mkdir $DIR/d26/d26-2
1457         ln -s d26/d26-2 $DIR/s26
1458         touch $DIR/s26/foo || error "File creation failed"
1459 }
1460 run_test 26a "multiple component symlink ======================="
1461
1462 test_26b() {
1463         test_mkdir -p $DIR/$tdir/d26-2
1464         ln -s $tdir/d26-2/foo $DIR/s26-2
1465         touch $DIR/s26-2 || error "File creation failed"
1466 }
1467 run_test 26b "multiple component symlink at end of lookup ======"
1468
1469 test_26c() {
1470         test_mkdir $DIR/d26.2
1471         touch $DIR/d26.2/foo
1472         ln -s d26.2 $DIR/s26.2-1
1473         ln -s s26.2-1 $DIR/s26.2-2
1474         ln -s s26.2-2 $DIR/s26.2-3
1475         chmod 0666 $DIR/s26.2-3/foo
1476 }
1477 run_test 26c "chain of symlinks"
1478
1479 # recursive symlinks (bug 439)
1480 test_26d() {
1481         ln -s d26-3/foo $DIR/d26-3
1482 }
1483 run_test 26d "create multiple component recursive symlink"
1484
1485 test_26e() {
1486         [ ! -h $DIR/d26-3 ] && test_26d
1487         rm $DIR/d26-3
1488 }
1489 run_test 26e "unlink multiple component recursive symlink"
1490
1491 # recursive symlinks (bug 7022)
1492 test_26f() {
1493         test_mkdir $DIR/$tdir
1494         test_mkdir $DIR/$tdir/$tfile
1495         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1496         test_mkdir -p lndir/bar1
1497         test_mkdir $DIR/$tdir/$tfile/$tfile
1498         cd $tfile                || error "cd $tfile failed"
1499         ln -s .. dotdot          || error "ln dotdot failed"
1500         ln -s dotdot/lndir lndir || error "ln lndir failed"
1501         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1502         output=`ls $tfile/$tfile/lndir/bar1`
1503         [ "$output" = bar1 ] && error "unexpected output"
1504         rm -r $tfile             || error "rm $tfile failed"
1505         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1506 }
1507 run_test 26f "rm -r of a directory which has recursive symlink"
1508
1509 test_27a() {
1510         test_mkdir $DIR/$tdir
1511         $LFS getstripe $DIR/$tdir
1512         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1513         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1514         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1515 }
1516 run_test 27a "one stripe file"
1517
1518 test_27b() {
1519         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1520
1521         test_mkdir $DIR/$tdir
1522         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1523         $LFS getstripe -c $DIR/$tdir/$tfile
1524         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1525                 error "two-stripe file doesn't have two stripes"
1526
1527         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1528 }
1529 run_test 27b "create and write to two stripe file"
1530
1531 # 27c family tests specific striping, setstripe -o
1532 test_27ca() {
1533         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1534         test_mkdir -p $DIR/$tdir
1535         local osts="1"
1536
1537         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1538         $LFS getstripe -i $DIR/$tdir/$tfile
1539         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1540                 error "stripe not on specified OST"
1541
1542         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1543 }
1544 run_test 27ca "one stripe on specified OST"
1545
1546 test_27cb() {
1547         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1548         test_mkdir -p $DIR/$tdir
1549         local osts="1,0"
1550         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1551         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1552         echo "$getstripe"
1553
1554         # Strip getstripe output to a space separated list of OSTs
1555         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1556                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1557         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1558                 error "stripes not on specified OSTs"
1559
1560         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1561 }
1562 run_test 27cb "two stripes on specified OSTs"
1563
1564 test_27cc() {
1565         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1566         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1567                 skip "server does not support overstriping"
1568
1569         test_mkdir -p $DIR/$tdir
1570         local osts="0,0"
1571         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1572         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1573         echo "$getstripe"
1574
1575         # Strip getstripe output to a space separated list of OSTs
1576         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1577                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1578         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1579                 error "stripes not on specified OSTs"
1580
1581         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1582 }
1583 run_test 27cc "two stripes on the same OST"
1584
1585 test_27cd() {
1586         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1587         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1588                 skip "server does not support overstriping"
1589         test_mkdir -p $DIR/$tdir
1590         local osts="0,1,1,0"
1591         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1592         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1593         echo "$getstripe"
1594
1595         # Strip getstripe output to a space separated list of OSTs
1596         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1597                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1598         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1599                 error "stripes not on specified OSTs"
1600
1601         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1602 }
1603 run_test 27cd "four stripes on two OSTs"
1604
1605 test_27ce() {
1606         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1607                 skip_env "too many osts, skipping"
1608         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1609                 skip "server does not support overstriping"
1610         # We do one more stripe than we have OSTs
1611         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1612                 skip_env "ea_inode feature disabled"
1613
1614         test_mkdir -p $DIR/$tdir
1615         local osts=""
1616         for i in $(seq 0 $OSTCOUNT);
1617         do
1618                 osts=$osts"0"
1619                 if [ $i -ne $OSTCOUNT ]; then
1620                         osts=$osts","
1621                 fi
1622         done
1623         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1624         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1625         echo "$getstripe"
1626
1627         # Strip getstripe output to a space separated list of OSTs
1628         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1629                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1630         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1631                 error "stripes not on specified OSTs"
1632
1633         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1634 }
1635 run_test 27ce "more stripes than OSTs with -o"
1636
1637 test_27d() {
1638         test_mkdir $DIR/$tdir
1639         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1640                 error "setstripe failed"
1641         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1642         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1643 }
1644 run_test 27d "create file with default settings"
1645
1646 test_27e() {
1647         # LU-5839 adds check for existed layout before setting it
1648         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1649                 skip "Need MDS version at least 2.7.56"
1650
1651         test_mkdir $DIR/$tdir
1652         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1653         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1654         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1655 }
1656 run_test 27e "setstripe existing file (should return error)"
1657
1658 test_27f() {
1659         test_mkdir $DIR/$tdir
1660         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1661                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1662         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1663                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1664         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1665         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1666 }
1667 run_test 27f "setstripe with bad stripe size (should return error)"
1668
1669 test_27g() {
1670         test_mkdir $DIR/$tdir
1671         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1672         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1673                 error "$DIR/$tdir/$tfile has object"
1674 }
1675 run_test 27g "$LFS getstripe with no objects"
1676
1677 test_27ga() {
1678         test_mkdir $DIR/$tdir
1679         touch $DIR/$tdir/$tfile || error "touch failed"
1680         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1681         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1682         local rc=$?
1683         (( rc == 2 )) || error "getstripe did not return ENOENT"
1684 }
1685 run_test 27ga "$LFS getstripe with missing file (should return error)"
1686
1687 test_27i() {
1688         test_mkdir $DIR/$tdir
1689         touch $DIR/$tdir/$tfile || error "touch failed"
1690         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1691                 error "missing objects"
1692 }
1693 run_test 27i "$LFS getstripe with some objects"
1694
1695 test_27j() {
1696         test_mkdir $DIR/$tdir
1697         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1698                 error "setstripe failed" || true
1699 }
1700 run_test 27j "setstripe with bad stripe offset (should return error)"
1701
1702 test_27k() { # bug 2844
1703         test_mkdir $DIR/$tdir
1704         local file=$DIR/$tdir/$tfile
1705         local ll_max_blksize=$((4 * 1024 * 1024))
1706         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1707         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1708         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1709         dd if=/dev/zero of=$file bs=4k count=1
1710         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1711         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1712 }
1713 run_test 27k "limit i_blksize for broken user apps"
1714
1715 test_27l() {
1716         mcreate $DIR/$tfile || error "creating file"
1717         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1718                 error "setstripe should have failed" || true
1719 }
1720 run_test 27l "check setstripe permissions (should return error)"
1721
1722 test_27m() {
1723         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1724
1725         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1726                 skip_env "multiple clients -- skipping"
1727
1728         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1729                    head -n1)
1730         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1731                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1732         fi
1733         trap simple_cleanup_common EXIT
1734         test_mkdir $DIR/$tdir
1735         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1736         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1737                 error "dd should fill OST0"
1738         i=2
1739         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1740                 i=$((i + 1))
1741                 [ $i -gt 256 ] && break
1742         done
1743         i=$((i + 1))
1744         touch $DIR/$tdir/$tfile.$i
1745         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1746             awk '{print $1}'| grep -w "0") ] &&
1747                 error "OST0 was full but new created file still use it"
1748         i=$((i + 1))
1749         touch $DIR/$tdir/$tfile.$i
1750         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1751             awk '{print $1}'| grep -w "0") ] &&
1752                 error "OST0 was full but new created file still use it"
1753         simple_cleanup_common
1754 }
1755 run_test 27m "create file while OST0 was full"
1756
1757 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1758 # if the OST isn't full anymore.
1759 reset_enospc() {
1760         local OSTIDX=${1:-""}
1761
1762         local list=$(comma_list $(osts_nodes))
1763         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1764
1765         do_nodes $list lctl set_param fail_loc=0
1766         sync    # initiate all OST_DESTROYs from MDS to OST
1767         sleep_maxage
1768 }
1769
1770 exhaust_precreations() {
1771         local OSTIDX=$1
1772         local FAILLOC=$2
1773         local FAILIDX=${3:-$OSTIDX}
1774         local ofacet=ost$((OSTIDX + 1))
1775
1776         test_mkdir -p -c1 $DIR/$tdir
1777         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1778         local mfacet=mds$((mdtidx + 1))
1779         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1780
1781         local OST=$(ostname_from_index $OSTIDX)
1782
1783         # on the mdt's osc
1784         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1785         local last_id=$(do_facet $mfacet lctl get_param -n \
1786                         osp.$mdtosc_proc1.prealloc_last_id)
1787         local next_id=$(do_facet $mfacet lctl get_param -n \
1788                         osp.$mdtosc_proc1.prealloc_next_id)
1789
1790         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1791         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1792
1793         test_mkdir -p $DIR/$tdir/${OST}
1794         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1795 #define OBD_FAIL_OST_ENOSPC              0x215
1796         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1797         echo "Creating to objid $last_id on ost $OST..."
1798         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1799         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1800         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1801         sleep_maxage
1802 }
1803
1804 exhaust_all_precreations() {
1805         local i
1806         for (( i=0; i < OSTCOUNT; i++ )) ; do
1807                 exhaust_precreations $i $1 -1
1808         done
1809 }
1810
1811 test_27n() {
1812         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1814         remote_mds_nodsh && skip "remote MDS with nodsh"
1815         remote_ost_nodsh && skip "remote OST with nodsh"
1816
1817         reset_enospc
1818         rm -f $DIR/$tdir/$tfile
1819         exhaust_precreations 0 0x80000215
1820         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1821         touch $DIR/$tdir/$tfile || error "touch failed"
1822         $LFS getstripe $DIR/$tdir/$tfile
1823         reset_enospc
1824 }
1825 run_test 27n "create file with some full OSTs"
1826
1827 test_27o() {
1828         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1830         remote_mds_nodsh && skip "remote MDS with nodsh"
1831         remote_ost_nodsh && skip "remote OST with nodsh"
1832
1833         reset_enospc
1834         rm -f $DIR/$tdir/$tfile
1835         exhaust_all_precreations 0x215
1836
1837         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1838
1839         reset_enospc
1840         rm -rf $DIR/$tdir/*
1841 }
1842 run_test 27o "create file with all full OSTs (should error)"
1843
1844 test_27p() {
1845         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1847         remote_mds_nodsh && skip "remote MDS with nodsh"
1848         remote_ost_nodsh && skip "remote OST with nodsh"
1849
1850         reset_enospc
1851         rm -f $DIR/$tdir/$tfile
1852         test_mkdir $DIR/$tdir
1853
1854         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1855         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1856         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1857
1858         exhaust_precreations 0 0x80000215
1859         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1860         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1861         $LFS getstripe $DIR/$tdir/$tfile
1862
1863         reset_enospc
1864 }
1865 run_test 27p "append to a truncated file with some full OSTs"
1866
1867 test_27q() {
1868         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1870         remote_mds_nodsh && skip "remote MDS with nodsh"
1871         remote_ost_nodsh && skip "remote OST with nodsh"
1872
1873         reset_enospc
1874         rm -f $DIR/$tdir/$tfile
1875
1876         test_mkdir $DIR/$tdir
1877         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1878         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1879                 error "truncate $DIR/$tdir/$tfile failed"
1880         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1881
1882         exhaust_all_precreations 0x215
1883
1884         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1885         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1886
1887         reset_enospc
1888 }
1889 run_test 27q "append to truncated file with all OSTs full (should error)"
1890
1891 test_27r() {
1892         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1894         remote_mds_nodsh && skip "remote MDS with nodsh"
1895         remote_ost_nodsh && skip "remote OST with nodsh"
1896
1897         reset_enospc
1898         rm -f $DIR/$tdir/$tfile
1899         exhaust_precreations 0 0x80000215
1900
1901         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1902
1903         reset_enospc
1904 }
1905 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1906
1907 test_27s() { # bug 10725
1908         test_mkdir $DIR/$tdir
1909         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1910         local stripe_count=0
1911         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1912         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1913                 error "stripe width >= 2^32 succeeded" || true
1914
1915 }
1916 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1917
1918 test_27t() { # bug 10864
1919         WDIR=$(pwd)
1920         WLFS=$(which lfs)
1921         cd $DIR
1922         touch $tfile
1923         $WLFS getstripe $tfile
1924         cd $WDIR
1925 }
1926 run_test 27t "check that utils parse path correctly"
1927
1928 test_27u() { # bug 4900
1929         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1930         remote_mds_nodsh && skip "remote MDS with nodsh"
1931
1932         local index
1933         local list=$(comma_list $(mdts_nodes))
1934
1935 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1936         do_nodes $list $LCTL set_param fail_loc=0x139
1937         test_mkdir -p $DIR/$tdir
1938         trap simple_cleanup_common EXIT
1939         createmany -o $DIR/$tdir/t- 1000
1940         do_nodes $list $LCTL set_param fail_loc=0
1941
1942         TLOG=$TMP/$tfile.getstripe
1943         $LFS getstripe $DIR/$tdir > $TLOG
1944         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1945         unlinkmany $DIR/$tdir/t- 1000
1946         trap 0
1947         [[ $OBJS -gt 0 ]] &&
1948                 error "$OBJS objects created on OST-0. See $TLOG" ||
1949                 rm -f $TLOG
1950 }
1951 run_test 27u "skip object creation on OSC w/o objects"
1952
1953 test_27v() { # bug 4900
1954         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1956         remote_mds_nodsh && skip "remote MDS with nodsh"
1957         remote_ost_nodsh && skip "remote OST with nodsh"
1958
1959         exhaust_all_precreations 0x215
1960         reset_enospc
1961
1962         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1963
1964         touch $DIR/$tdir/$tfile
1965         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1966         # all except ost1
1967         for (( i=1; i < OSTCOUNT; i++ )); do
1968                 do_facet ost$i lctl set_param fail_loc=0x705
1969         done
1970         local START=`date +%s`
1971         createmany -o $DIR/$tdir/$tfile 32
1972
1973         local FINISH=`date +%s`
1974         local TIMEOUT=`lctl get_param -n timeout`
1975         local PROCESS=$((FINISH - START))
1976         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1977                error "$FINISH - $START >= $TIMEOUT / 2"
1978         sleep $((TIMEOUT / 2 - PROCESS))
1979         reset_enospc
1980 }
1981 run_test 27v "skip object creation on slow OST"
1982
1983 test_27w() { # bug 10997
1984         test_mkdir $DIR/$tdir
1985         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1986         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1987                 error "stripe size $size != 65536" || true
1988         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1989                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1990 }
1991 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1992
1993 test_27wa() {
1994         [[ $OSTCOUNT -lt 2 ]] &&
1995                 skip_env "skipping multiple stripe count/offset test"
1996
1997         test_mkdir $DIR/$tdir
1998         for i in $(seq 1 $OSTCOUNT); do
1999                 offset=$((i - 1))
2000                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2001                         error "setstripe -c $i -i $offset failed"
2002                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2003                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2004                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2005                 [ $index -ne $offset ] &&
2006                         error "stripe offset $index != $offset" || true
2007         done
2008 }
2009 run_test 27wa "check $LFS setstripe -c -i options"
2010
2011 test_27x() {
2012         remote_ost_nodsh && skip "remote OST with nodsh"
2013         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2015
2016         OFFSET=$(($OSTCOUNT - 1))
2017         OSTIDX=0
2018         local OST=$(ostname_from_index $OSTIDX)
2019
2020         test_mkdir $DIR/$tdir
2021         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2022         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2023         sleep_maxage
2024         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2025         for i in $(seq 0 $OFFSET); do
2026                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2027                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2028                 error "OST0 was degraded but new created file still use it"
2029         done
2030         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2031 }
2032 run_test 27x "create files while OST0 is degraded"
2033
2034 test_27y() {
2035         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2036         remote_mds_nodsh && skip "remote MDS with nodsh"
2037         remote_ost_nodsh && skip "remote OST with nodsh"
2038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2039
2040         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2041         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2042                 osp.$mdtosc.prealloc_last_id)
2043         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2044                 osp.$mdtosc.prealloc_next_id)
2045         local fcount=$((last_id - next_id))
2046         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2047         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2048
2049         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2050                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2051         local OST_DEACTIVE_IDX=-1
2052         local OSC
2053         local OSTIDX
2054         local OST
2055
2056         for OSC in $MDS_OSCS; do
2057                 OST=$(osc_to_ost $OSC)
2058                 OSTIDX=$(index_from_ostuuid $OST)
2059                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2060                         OST_DEACTIVE_IDX=$OSTIDX
2061                 fi
2062                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2063                         echo $OSC "is Deactivated:"
2064                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2065                 fi
2066         done
2067
2068         OSTIDX=$(index_from_ostuuid $OST)
2069         test_mkdir $DIR/$tdir
2070         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2071
2072         for OSC in $MDS_OSCS; do
2073                 OST=$(osc_to_ost $OSC)
2074                 OSTIDX=$(index_from_ostuuid $OST)
2075                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2076                         echo $OST "is degraded:"
2077                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2078                                                 obdfilter.$OST.degraded=1
2079                 fi
2080         done
2081
2082         sleep_maxage
2083         createmany -o $DIR/$tdir/$tfile $fcount
2084
2085         for OSC in $MDS_OSCS; do
2086                 OST=$(osc_to_ost $OSC)
2087                 OSTIDX=$(index_from_ostuuid $OST)
2088                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2089                         echo $OST "is recovered from degraded:"
2090                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2091                                                 obdfilter.$OST.degraded=0
2092                 else
2093                         do_facet $SINGLEMDS lctl --device %$OSC activate
2094                 fi
2095         done
2096
2097         # all osp devices get activated, hence -1 stripe count restored
2098         local stripe_count=0
2099
2100         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2101         # devices get activated.
2102         sleep_maxage
2103         $LFS setstripe -c -1 $DIR/$tfile
2104         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2105         rm -f $DIR/$tfile
2106         [ $stripe_count -ne $OSTCOUNT ] &&
2107                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2108         return 0
2109 }
2110 run_test 27y "create files while OST0 is degraded and the rest inactive"
2111
2112 check_seq_oid()
2113 {
2114         log "check file $1"
2115
2116         lmm_count=$($LFS getstripe -c $1)
2117         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2118         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2119
2120         local old_ifs="$IFS"
2121         IFS=$'[:]'
2122         fid=($($LFS path2fid $1))
2123         IFS="$old_ifs"
2124
2125         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2126         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2127
2128         # compare lmm_seq and lu_fid->f_seq
2129         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2130         # compare lmm_object_id and lu_fid->oid
2131         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2132
2133         # check the trusted.fid attribute of the OST objects of the file
2134         local have_obdidx=false
2135         local stripe_nr=0
2136         $LFS getstripe $1 | while read obdidx oid hex seq; do
2137                 # skip lines up to and including "obdidx"
2138                 [ -z "$obdidx" ] && break
2139                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2140                 $have_obdidx || continue
2141
2142                 local ost=$((obdidx + 1))
2143                 local dev=$(ostdevname $ost)
2144                 local oid_hex
2145
2146                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2147
2148                 seq=$(echo $seq | sed -e "s/^0x//g")
2149                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2150                         oid_hex=$(echo $oid)
2151                 else
2152                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2153                 fi
2154                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2155
2156                 local ff=""
2157                 #
2158                 # Don't unmount/remount the OSTs if we don't need to do that.
2159                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2160                 # update too, until that use mount/ll_decode_filter_fid/mount.
2161                 # Re-enable when debugfs will understand new filter_fid.
2162                 #
2163                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2164                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2165                                 $dev 2>/dev/null" | grep "parent=")
2166                 fi
2167                 if [ -z "$ff" ]; then
2168                         stop ost$ost
2169                         mount_fstype ost$ost
2170                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2171                                 $(facet_mntpt ost$ost)/$obj_file)
2172                         unmount_fstype ost$ost
2173                         start ost$ost $dev $OST_MOUNT_OPTS
2174                         clients_up
2175                 fi
2176
2177                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2178
2179                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2180
2181                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2182                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2183                 #
2184                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2185                 #       stripe_size=1048576 component_id=1 component_start=0 \
2186                 #       component_end=33554432
2187                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2188                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2189                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2190                 local ff_pstripe
2191                 if grep -q 'stripe=' <<<$ff; then
2192                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2193                 else
2194                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2195                         # into f_ver in this case.  See comment on ff_parent.
2196                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2197                 fi
2198
2199                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2200                 [ $ff_pseq = $lmm_seq ] ||
2201                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2202                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2203                 [ $ff_poid = $lmm_oid ] ||
2204                         error "FF parent OID $ff_poid != $lmm_oid"
2205                 (($ff_pstripe == $stripe_nr)) ||
2206                         error "FF stripe $ff_pstripe != $stripe_nr"
2207
2208                 stripe_nr=$((stripe_nr + 1))
2209                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2210                         continue
2211                 if grep -q 'stripe_count=' <<<$ff; then
2212                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2213                                             -e 's/ .*//' <<<$ff)
2214                         [ $lmm_count = $ff_scnt ] ||
2215                                 error "FF stripe count $lmm_count != $ff_scnt"
2216                 fi
2217         done
2218 }
2219
2220 test_27z() {
2221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2222         remote_ost_nodsh && skip "remote OST with nodsh"
2223
2224         test_mkdir $DIR/$tdir
2225         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2226                 { error "setstripe -c -1 failed"; return 1; }
2227         # We need to send a write to every object to get parent FID info set.
2228         # This _should_ also work for setattr, but does not currently.
2229         # touch $DIR/$tdir/$tfile-1 ||
2230         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2231                 { error "dd $tfile-1 failed"; return 2; }
2232         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2233                 { error "setstripe -c -1 failed"; return 3; }
2234         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2235                 { error "dd $tfile-2 failed"; return 4; }
2236
2237         # make sure write RPCs have been sent to OSTs
2238         sync; sleep 5; sync
2239
2240         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2241         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2242 }
2243 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2244
2245 test_27A() { # b=19102
2246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2247
2248         save_layout_restore_at_exit $MOUNT
2249         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2250         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2251                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2252         local default_size=$($LFS getstripe -S $MOUNT)
2253         local default_offset=$($LFS getstripe -i $MOUNT)
2254         local dsize=$(do_facet $SINGLEMDS \
2255                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2256         [ $default_size -eq $dsize ] ||
2257                 error "stripe size $default_size != $dsize"
2258         [ $default_offset -eq -1 ] ||
2259                 error "stripe offset $default_offset != -1"
2260 }
2261 run_test 27A "check filesystem-wide default LOV EA values"
2262
2263 test_27B() { # LU-2523
2264         test_mkdir $DIR/$tdir
2265         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2266         touch $DIR/$tdir/f0
2267         # open f1 with O_LOV_DELAY_CREATE
2268         # rename f0 onto f1
2269         # call setstripe ioctl on open file descriptor for f1
2270         # close
2271         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2272                 $DIR/$tdir/f0
2273
2274         rm -f $DIR/$tdir/f1
2275         # open f1 with O_LOV_DELAY_CREATE
2276         # unlink f1
2277         # call setstripe ioctl on open file descriptor for f1
2278         # close
2279         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2280
2281         # Allow multiop to fail in imitation of NFS's busted semantics.
2282         true
2283 }
2284 run_test 27B "call setstripe on open unlinked file/rename victim"
2285
2286 # 27C family tests full striping and overstriping
2287 test_27Ca() { #LU-2871
2288         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2289
2290         declare -a ost_idx
2291         local index
2292         local found
2293         local i
2294         local j
2295
2296         test_mkdir $DIR/$tdir
2297         cd $DIR/$tdir
2298         for i in $(seq 0 $((OSTCOUNT - 1))); do
2299                 # set stripe across all OSTs starting from OST$i
2300                 $LFS setstripe -i $i -c -1 $tfile$i
2301                 # get striping information
2302                 ost_idx=($($LFS getstripe $tfile$i |
2303                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2304                 echo ${ost_idx[@]}
2305
2306                 # check the layout
2307                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2308                         error "${#ost_idx[@]} != $OSTCOUNT"
2309
2310                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2311                         found=0
2312                         for j in $(echo ${ost_idx[@]}); do
2313                                 if [ $index -eq $j ]; then
2314                                         found=1
2315                                         break
2316                                 fi
2317                         done
2318                         [ $found = 1 ] ||
2319                                 error "Can not find $index in ${ost_idx[@]}"
2320                 done
2321         done
2322 }
2323 run_test 27Ca "check full striping across all OSTs"
2324
2325 test_27Cb() {
2326         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2327                 skip "server does not support overstriping"
2328         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2329                 skip_env "too many osts, skipping"
2330
2331         test_mkdir -p $DIR/$tdir
2332         local setcount=$(($OSTCOUNT * 2))
2333         [ $setcount -ge 160 ] || large_xattr_enabled ||
2334                 skip_env "ea_inode feature disabled"
2335
2336         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2337                 error "setstripe failed"
2338
2339         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2340         [ $count -eq $setcount ] ||
2341                 error "stripe count $count, should be $setcount"
2342
2343         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2344                 error "overstriped should be set in pattern"
2345
2346         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2347                 error "dd failed"
2348 }
2349 run_test 27Cb "more stripes than OSTs with -C"
2350
2351 test_27Cc() {
2352         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2353                 skip "server does not support overstriping"
2354         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2355
2356         test_mkdir -p $DIR/$tdir
2357         local setcount=$(($OSTCOUNT - 1))
2358
2359         [ $setcount -ge 160 ] || large_xattr_enabled ||
2360                 skip_env "ea_inode feature disabled"
2361
2362         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2363                 error "setstripe failed"
2364
2365         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2366         [ $count -eq $setcount ] ||
2367                 error "stripe count $count, should be $setcount"
2368
2369         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2370                 error "overstriped should not be set in pattern"
2371
2372         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2373                 error "dd failed"
2374 }
2375 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2376
2377 test_27Cd() {
2378         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2379                 skip "server does not support overstriping"
2380         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2381         large_xattr_enabled || skip_env "ea_inode feature disabled"
2382
2383         test_mkdir -p $DIR/$tdir
2384         local setcount=$LOV_MAX_STRIPE_COUNT
2385
2386         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2387                 error "setstripe failed"
2388
2389         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2390         [ $count -eq $setcount ] ||
2391                 error "stripe count $count, should be $setcount"
2392
2393         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2394                 error "overstriped should be set in pattern"
2395
2396         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2397                 error "dd failed"
2398
2399         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2400 }
2401 run_test 27Cd "test maximum stripe count"
2402
2403 test_27Ce() {
2404         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2405                 skip "server does not support overstriping"
2406         test_mkdir -p $DIR/$tdir
2407
2408         pool_add $TESTNAME || error "Pool creation failed"
2409         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2410
2411         local setcount=8
2412
2413         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2414                 error "setstripe failed"
2415
2416         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2417         [ $count -eq $setcount ] ||
2418                 error "stripe count $count, should be $setcount"
2419
2420         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2421                 error "overstriped should be set in pattern"
2422
2423         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2424                 error "dd failed"
2425
2426         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2427 }
2428 run_test 27Ce "test pool with overstriping"
2429
2430 test_27Cf() {
2431         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2432                 skip "server does not support overstriping"
2433         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2434                 skip_env "too many osts, skipping"
2435
2436         test_mkdir -p $DIR/$tdir
2437
2438         local setcount=$(($OSTCOUNT * 2))
2439         [ $setcount -ge 160 ] || large_xattr_enabled ||
2440                 skip_env "ea_inode feature disabled"
2441
2442         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2443                 error "setstripe failed"
2444
2445         echo 1 > $DIR/$tdir/$tfile
2446
2447         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2448         [ $count -eq $setcount ] ||
2449                 error "stripe count $count, should be $setcount"
2450
2451         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2452                 error "overstriped should be set in pattern"
2453
2454         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2455                 error "dd failed"
2456
2457         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2458 }
2459 run_test 27Cf "test default inheritance with overstriping"
2460
2461 test_27D() {
2462         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2463         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2464         remote_mds_nodsh && skip "remote MDS with nodsh"
2465
2466         local POOL=${POOL:-testpool}
2467         local first_ost=0
2468         local last_ost=$(($OSTCOUNT - 1))
2469         local ost_step=1
2470         local ost_list=$(seq $first_ost $ost_step $last_ost)
2471         local ost_range="$first_ost $last_ost $ost_step"
2472
2473         test_mkdir $DIR/$tdir
2474         pool_add $POOL || error "pool_add failed"
2475         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2476
2477         local skip27D
2478         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2479                 skip27D+="-s 29"
2480         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2481                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2482                         skip27D+=" -s 30,31"
2483         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2484           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2485                 skip27D+=" -s 32,33"
2486         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2487                 skip27D+=" -s 34"
2488         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2489                 error "llapi_layout_test failed"
2490
2491         destroy_test_pools || error "destroy test pools failed"
2492 }
2493 run_test 27D "validate llapi_layout API"
2494
2495 # Verify that default_easize is increased from its initial value after
2496 # accessing a widely striped file.
2497 test_27E() {
2498         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2499         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2500                 skip "client does not have LU-3338 fix"
2501
2502         # 72 bytes is the minimum space required to store striping
2503         # information for a file striped across one OST:
2504         # (sizeof(struct lov_user_md_v3) +
2505         #  sizeof(struct lov_user_ost_data_v1))
2506         local min_easize=72
2507         $LCTL set_param -n llite.*.default_easize $min_easize ||
2508                 error "lctl set_param failed"
2509         local easize=$($LCTL get_param -n llite.*.default_easize)
2510
2511         [ $easize -eq $min_easize ] ||
2512                 error "failed to set default_easize"
2513
2514         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2515                 error "setstripe failed"
2516         # In order to ensure stat() call actually talks to MDS we need to
2517         # do something drastic to this file to shake off all lock, e.g.
2518         # rename it (kills lookup lock forcing cache cleaning)
2519         mv $DIR/$tfile $DIR/${tfile}-1
2520         ls -l $DIR/${tfile}-1
2521         rm $DIR/${tfile}-1
2522
2523         easize=$($LCTL get_param -n llite.*.default_easize)
2524
2525         [ $easize -gt $min_easize ] ||
2526                 error "default_easize not updated"
2527 }
2528 run_test 27E "check that default extended attribute size properly increases"
2529
2530 test_27F() { # LU-5346/LU-7975
2531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2532         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2533         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2534                 skip "Need MDS version at least 2.8.51"
2535         remote_ost_nodsh && skip "remote OST with nodsh"
2536
2537         test_mkdir $DIR/$tdir
2538         rm -f $DIR/$tdir/f0
2539         $LFS setstripe -c 2 $DIR/$tdir
2540
2541         # stop all OSTs to reproduce situation for LU-7975 ticket
2542         for num in $(seq $OSTCOUNT); do
2543                 stop ost$num
2544         done
2545
2546         # open/create f0 with O_LOV_DELAY_CREATE
2547         # truncate f0 to a non-0 size
2548         # close
2549         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2550
2551         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2552         # open/write it again to force delayed layout creation
2553         cat /etc/hosts > $DIR/$tdir/f0 &
2554         catpid=$!
2555
2556         # restart OSTs
2557         for num in $(seq $OSTCOUNT); do
2558                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2559                         error "ost$num failed to start"
2560         done
2561
2562         wait $catpid || error "cat failed"
2563
2564         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2565         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2566                 error "wrong stripecount"
2567
2568 }
2569 run_test 27F "Client resend delayed layout creation with non-zero size"
2570
2571 test_27G() { #LU-10629
2572         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2573                 skip "Need MDS version at least 2.11.51"
2574         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2575         remote_mds_nodsh && skip "remote MDS with nodsh"
2576         local POOL=${POOL:-testpool}
2577         local ostrange="0 0 1"
2578
2579         test_mkdir $DIR/$tdir
2580         pool_add $POOL || error "pool_add failed"
2581         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2582         $LFS setstripe -p $POOL $DIR/$tdir
2583
2584         local pool=$($LFS getstripe -p $DIR/$tdir)
2585
2586         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2587
2588         $LFS setstripe -d $DIR/$tdir
2589
2590         pool=$($LFS getstripe -p $DIR/$tdir)
2591
2592         rmdir $DIR/$tdir
2593
2594         [ -z "$pool" ] || error "'$pool' is not empty"
2595 }
2596 run_test 27G "Clear OST pool from stripe"
2597
2598 test_27H() {
2599         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2600                 skip "Need MDS version newer than 2.11.54"
2601         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2602         test_mkdir $DIR/$tdir
2603         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2604         touch $DIR/$tdir/$tfile
2605         $LFS getstripe -c $DIR/$tdir/$tfile
2606         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2607                 error "two-stripe file doesn't have two stripes"
2608
2609         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2610         $LFS getstripe -y $DIR/$tdir/$tfile
2611         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2612              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2613                 error "expected l_ost_idx: [02]$ not matched"
2614
2615         # make sure ost list has been cleared
2616         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2617         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2618                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2619         touch $DIR/$tdir/f3
2620         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2621 }
2622 run_test 27H "Set specific OSTs stripe"
2623
2624 test_27I() {
2625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2626         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2627         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2628                 skip "Need MDS version newer than 2.12.52"
2629         local pool=$TESTNAME
2630         local ostrange="1 1 1"
2631
2632         save_layout_restore_at_exit $MOUNT
2633         $LFS setstripe -c 2 -i 0 $MOUNT
2634         pool_add $pool || error "pool_add failed"
2635         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2636         test_mkdir $DIR/$tdir
2637         $LFS setstripe -p $pool $DIR/$tdir
2638         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2639         $LFS getstripe $DIR/$tdir/$tfile
2640 }
2641 run_test 27I "check that root dir striping does not break parent dir one"
2642
2643 test_27J() {
2644         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
2645                 skip "Need MDS version newer than 2.12.51"
2646
2647         test_mkdir $DIR/$tdir
2648         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2649         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2650
2651         # create foreign file (raw way)
2652         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2653                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2654
2655         # verify foreign file (raw way)
2656         parse_foreign_file -f $DIR/$tdir/$tfile |
2657                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2658                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2659         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2660                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2661         parse_foreign_file -f $DIR/$tdir/$tfile |
2662                 grep "lov_foreign_size: 73" ||
2663                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2664         parse_foreign_file -f $DIR/$tdir/$tfile |
2665                 grep "lov_foreign_type: 1" ||
2666                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2667         parse_foreign_file -f $DIR/$tdir/$tfile |
2668                 grep "lov_foreign_flags: 0x0000DA08" ||
2669                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2670         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2671                 grep "lov_foreign_value: 0x" |
2672                 sed -e 's/lov_foreign_value: 0x//')
2673         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2674         [[ $lov = ${lov2// /} ]] ||
2675                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2676
2677         # create foreign file (lfs + API)
2678         $LFS setstripe --foreign=daos --flags 0xda08 \
2679                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2680                 error "$DIR/$tdir/${tfile}2: create failed"
2681
2682         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2683                 grep "lfm_magic:.*0x0BD70BD0" ||
2684                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2685         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2686         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2687                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2688         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2689                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2690         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2691                 grep "lfm_flags:.*0x0000DA08" ||
2692                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2693         $LFS getstripe $DIR/$tdir/${tfile}2 |
2694                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2695                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2696
2697         # modify striping should fail
2698         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2699                 error "$DIR/$tdir/$tfile: setstripe should fail"
2700         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2701                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2702
2703         # R/W should fail
2704         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2705         cat $DIR/$tdir/${tfile}2 &&
2706                 error "$DIR/$tdir/${tfile}2: read should fail"
2707         cat /etc/passwd > $DIR/$tdir/$tfile &&
2708                 error "$DIR/$tdir/$tfile: write should fail"
2709         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2710                 error "$DIR/$tdir/${tfile}2: write should fail"
2711
2712         # chmod should work
2713         chmod 222 $DIR/$tdir/$tfile ||
2714                 error "$DIR/$tdir/$tfile: chmod failed"
2715         chmod 222 $DIR/$tdir/${tfile}2 ||
2716                 error "$DIR/$tdir/${tfile}2: chmod failed"
2717
2718         # chown should work
2719         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2720                 error "$DIR/$tdir/$tfile: chown failed"
2721         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2722                 error "$DIR/$tdir/${tfile}2: chown failed"
2723
2724         # rename should work
2725         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2726                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2727         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2728                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2729
2730         #remove foreign file
2731         rm $DIR/$tdir/${tfile}.new ||
2732                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2733         rm $DIR/$tdir/${tfile}2.new ||
2734                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2735 }
2736 run_test 27J "basic ops on file with foreign LOV"
2737
2738 test_27K() {
2739         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
2740                 skip "Need MDS version newer than 2.12.49"
2741
2742         test_mkdir $DIR/$tdir
2743         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2744         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2745
2746         # create foreign dir (raw way)
2747         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2748                 error "create_foreign_dir FAILED"
2749
2750         # verify foreign dir (raw way)
2751         parse_foreign_dir -d $DIR/$tdir/$tdir |
2752                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2753                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2754         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2755                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2756         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2757                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2758         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2759                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2760         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2761                 grep "lmv_foreign_value: 0x" |
2762                 sed 's/lmv_foreign_value: 0x//')
2763         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2764                 sed 's/ //g')
2765         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2766
2767         # create foreign dir (lfs + API)
2768         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2769                 $DIR/$tdir/${tdir}2 ||
2770                 error "$DIR/$tdir/${tdir}2: create failed"
2771
2772         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2773                 grep "lfm_magic:.*0x0CD50CD0" ||
2774                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2775         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2776         # - sizeof(lfm_type) - sizeof(lfm_flags)
2777         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2778                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2779         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2780                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2781         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2782                 grep "lfm_flags:.*0x0000DA05" ||
2783                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2784         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2785                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2786                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2787
2788         # file create in dir should fail
2789         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2790         touch $DIR/$tdir/${tdir}2/$tfile &&
2791                 "$DIR/${tdir}2: file create should fail"
2792
2793         # chmod should work
2794         chmod 777 $DIR/$tdir/$tdir ||
2795                 error "$DIR/$tdir: chmod failed"
2796         chmod 777 $DIR/$tdir/${tdir}2 ||
2797                 error "$DIR/${tdir}2: chmod failed"
2798
2799         # chown should work
2800         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2801                 error "$DIR/$tdir: chown failed"
2802         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2803                 error "$DIR/${tdir}2: chown failed"
2804
2805         # rename should work
2806         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2807                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2808         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2809                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2810
2811         #remove foreign dir
2812         rmdir $DIR/$tdir/${tdir}.new ||
2813                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2814         rmdir $DIR/$tdir/${tdir}2.new ||
2815                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2816 }
2817 run_test 27K "basic ops on dir with foreign LMV"
2818
2819 test_27L() {
2820         remote_mds_nodsh && skip "remote MDS with nodsh"
2821
2822         local POOL=${POOL:-$TESTNAME}
2823
2824         pool_add $POOL || error "pool_add failed"
2825
2826         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2827                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2828                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2829 }
2830 run_test 27L "lfs pool_list gives correct pool name"
2831
2832 test_27M() {
2833         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2834                 skip "Need MDS version >= than 2.12.57"
2835         remote_mds_nodsh && skip "remote MDS with nodsh"
2836         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2837
2838         test_mkdir $DIR/$tdir
2839
2840         # Set default striping on directory
2841         $LFS setstripe -C 4 $DIR/$tdir
2842
2843         echo 1 > $DIR/$tdir/${tfile}.1
2844         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2845         local setcount=4
2846         [ $count -eq $setcount ] ||
2847                 error "(1) stripe count $count, should be $setcount"
2848
2849         # Capture existing append_stripe_count setting for restore
2850         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2851         local mdts=$(comma_list $(mdts_nodes))
2852         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2853
2854         local appendcount=$orig_count
2855         echo 1 >> $DIR/$tdir/${tfile}.2_append
2856         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2857         [ $count -eq $appendcount ] ||
2858                 error "(2)stripe count $count, should be $appendcount for append"
2859
2860         # Disable O_APPEND striping, verify it works
2861         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2862
2863         # Should now get the default striping, which is 4
2864         setcount=4
2865         echo 1 >> $DIR/$tdir/${tfile}.3_append
2866         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2867         [ $count -eq $setcount ] ||
2868                 error "(3) stripe count $count, should be $setcount"
2869
2870         # Try changing the stripe count for append files
2871         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2872
2873         # Append striping is now 2 (directory default is still 4)
2874         appendcount=2
2875         echo 1 >> $DIR/$tdir/${tfile}.4_append
2876         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2877         [ $count -eq $appendcount ] ||
2878                 error "(4) stripe count $count, should be $appendcount for append"
2879
2880         # Test append stripe count of -1
2881         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2882         appendcount=$OSTCOUNT
2883         echo 1 >> $DIR/$tdir/${tfile}.5
2884         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2885         [ $count -eq $appendcount ] ||
2886                 error "(5) stripe count $count, should be $appendcount for append"
2887
2888         # Set append striping back to default of 1
2889         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2890
2891         # Try a new default striping, PFL + DOM
2892         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2893
2894         # Create normal DOM file, DOM returns stripe count == 0
2895         setcount=0
2896         touch $DIR/$tdir/${tfile}.6
2897         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2898         [ $count -eq $setcount ] ||
2899                 error "(6) stripe count $count, should be $setcount"
2900
2901         # Show
2902         appendcount=1
2903         echo 1 >> $DIR/$tdir/${tfile}.7_append
2904         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2905         [ $count -eq $appendcount ] ||
2906                 error "(7) stripe count $count, should be $appendcount for append"
2907
2908         # Clean up DOM layout
2909         $LFS setstripe -d $DIR/$tdir
2910
2911         # Now test that append striping works when layout is from root
2912         $LFS setstripe -c 2 $MOUNT
2913         # Make a special directory for this
2914         mkdir $DIR/${tdir}/${tdir}.2
2915         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2916
2917         # Verify for normal file
2918         setcount=2
2919         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2920         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2921         [ $count -eq $setcount ] ||
2922                 error "(8) stripe count $count, should be $setcount"
2923
2924         appendcount=1
2925         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2926         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2927         [ $count -eq $appendcount ] ||
2928                 error "(9) stripe count $count, should be $appendcount for append"
2929
2930         # Now test O_APPEND striping with pools
2931         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2932         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2933
2934         # Create the pool
2935         pool_add $TESTNAME || error "pool creation failed"
2936         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2937
2938         echo 1 >> $DIR/$tdir/${tfile}.10_append
2939
2940         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2941         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2942
2943         # Check that count is still correct
2944         appendcount=1
2945         echo 1 >> $DIR/$tdir/${tfile}.11_append
2946         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2947         [ $count -eq $appendcount ] ||
2948                 error "(11) stripe count $count, should be $appendcount for append"
2949
2950         # Disable O_APPEND stripe count, verify pool works separately
2951         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2952
2953         echo 1 >> $DIR/$tdir/${tfile}.12_append
2954
2955         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
2956         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
2957
2958         # Remove pool setting, verify it's not applied
2959         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
2960
2961         echo 1 >> $DIR/$tdir/${tfile}.13_append
2962
2963         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
2964         [ "$pool" = "" ] || error "(13) pool found: $pool"
2965 }
2966 run_test 27M "test O_APPEND striping"
2967
2968 test_27N() {
2969         combined_mgs_mds && skip "needs separate MGS/MDT"
2970
2971         pool_add $TESTNAME || error "pool_add failed"
2972         do_facet mgs "$LCTL pool_list $FSNAME" |
2973                 grep -Fx "${FSNAME}.${TESTNAME}" ||
2974                 error "lctl pool_list on MGS failed"
2975 }
2976 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
2977
2978 # createtest also checks that device nodes are created and
2979 # then visible correctly (#2091)
2980 test_28() { # bug 2091
2981         test_mkdir $DIR/d28
2982         $CREATETEST $DIR/d28/ct || error "createtest failed"
2983 }
2984 run_test 28 "create/mknod/mkdir with bad file types ============"
2985
2986 test_29() {
2987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2988
2989         sync; sleep 1; sync # flush out any dirty pages from previous tests
2990         cancel_lru_locks
2991         test_mkdir $DIR/d29
2992         touch $DIR/d29/foo
2993         log 'first d29'
2994         ls -l $DIR/d29
2995
2996         declare -i LOCKCOUNTORIG=0
2997         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2998                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2999         done
3000         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3001
3002         declare -i LOCKUNUSEDCOUNTORIG=0
3003         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3004                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3005         done
3006
3007         log 'second d29'
3008         ls -l $DIR/d29
3009         log 'done'
3010
3011         declare -i LOCKCOUNTCURRENT=0
3012         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3013                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3014         done
3015
3016         declare -i LOCKUNUSEDCOUNTCURRENT=0
3017         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3018                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3019         done
3020
3021         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3022                 $LCTL set_param -n ldlm.dump_namespaces ""
3023                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3024                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3025                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3026                 return 2
3027         fi
3028         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3029                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3030                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3031                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3032                 return 3
3033         fi
3034 }
3035 run_test 29 "IT_GETATTR regression  ============================"
3036
3037 test_30a() { # was test_30
3038         cp $(which ls) $DIR || cp /bin/ls $DIR
3039         $DIR/ls / || error "Can't execute binary from lustre"
3040         rm $DIR/ls
3041 }
3042 run_test 30a "execute binary from Lustre (execve) =============="
3043
3044 test_30b() {
3045         cp `which ls` $DIR || cp /bin/ls $DIR
3046         chmod go+rx $DIR/ls
3047         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3048         rm $DIR/ls
3049 }
3050 run_test 30b "execute binary from Lustre as non-root ==========="
3051
3052 test_30c() { # b=22376
3053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3054
3055         cp `which ls` $DIR || cp /bin/ls $DIR
3056         chmod a-rw $DIR/ls
3057         cancel_lru_locks mdc
3058         cancel_lru_locks osc
3059         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3060         rm -f $DIR/ls
3061 }
3062 run_test 30c "execute binary from Lustre without read perms ===="
3063
3064 test_31a() {
3065         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3066         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3067 }
3068 run_test 31a "open-unlink file =================================="
3069
3070 test_31b() {
3071         touch $DIR/f31 || error "touch $DIR/f31 failed"
3072         ln $DIR/f31 $DIR/f31b || error "ln failed"
3073         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3074         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3075 }
3076 run_test 31b "unlink file with multiple links while open ======="
3077
3078 test_31c() {
3079         touch $DIR/f31 || error "touch $DIR/f31 failed"
3080         ln $DIR/f31 $DIR/f31c || error "ln failed"
3081         multiop_bg_pause $DIR/f31 O_uc ||
3082                 error "multiop_bg_pause for $DIR/f31 failed"
3083         MULTIPID=$!
3084         $MULTIOP $DIR/f31c Ouc
3085         kill -USR1 $MULTIPID
3086         wait $MULTIPID
3087 }
3088 run_test 31c "open-unlink file with multiple links ============="
3089
3090 test_31d() {
3091         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3092         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3093 }
3094 run_test 31d "remove of open directory ========================="
3095
3096 test_31e() { # bug 2904
3097         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3098 }
3099 run_test 31e "remove of open non-empty directory ==============="
3100
3101 test_31f() { # bug 4554
3102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3103
3104         set -vx
3105         test_mkdir $DIR/d31f
3106         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3107         cp /etc/hosts $DIR/d31f
3108         ls -l $DIR/d31f
3109         $LFS getstripe $DIR/d31f/hosts
3110         multiop_bg_pause $DIR/d31f D_c || return 1
3111         MULTIPID=$!
3112
3113         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3114         test_mkdir $DIR/d31f
3115         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3116         cp /etc/hosts $DIR/d31f
3117         ls -l $DIR/d31f
3118         $LFS getstripe $DIR/d31f/hosts
3119         multiop_bg_pause $DIR/d31f D_c || return 1
3120         MULTIPID2=$!
3121
3122         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3123         wait $MULTIPID || error "first opendir $MULTIPID failed"
3124
3125         sleep 6
3126
3127         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3128         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3129         set +vx
3130 }
3131 run_test 31f "remove of open directory with open-unlink file ==="
3132
3133 test_31g() {
3134         echo "-- cross directory link --"
3135         test_mkdir -c1 $DIR/${tdir}ga
3136         test_mkdir -c1 $DIR/${tdir}gb
3137         touch $DIR/${tdir}ga/f
3138         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3139         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3140         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3141         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3142         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3143 }
3144 run_test 31g "cross directory link==============="
3145
3146 test_31h() {
3147         echo "-- cross directory link --"
3148         test_mkdir -c1 $DIR/${tdir}
3149         test_mkdir -c1 $DIR/${tdir}/dir
3150         touch $DIR/${tdir}/f
3151         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3152         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3153         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3154         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3155         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3156 }
3157 run_test 31h "cross directory link under child==============="
3158
3159 test_31i() {
3160         echo "-- cross directory link --"
3161         test_mkdir -c1 $DIR/$tdir
3162         test_mkdir -c1 $DIR/$tdir/dir
3163         touch $DIR/$tdir/dir/f
3164         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3165         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3166         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3167         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3168         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3169 }
3170 run_test 31i "cross directory link under parent==============="
3171
3172 test_31j() {
3173         test_mkdir -c1 -p $DIR/$tdir
3174         test_mkdir -c1 -p $DIR/$tdir/dir1
3175         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3176         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3177         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3178         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3179         return 0
3180 }
3181 run_test 31j "link for directory==============="
3182
3183 test_31k() {
3184         test_mkdir -c1 -p $DIR/$tdir
3185         touch $DIR/$tdir/s
3186         touch $DIR/$tdir/exist
3187         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3188         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3189         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3190         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3191         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3192         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3193         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3194         return 0
3195 }
3196 run_test 31k "link to file: the same, non-existing, dir==============="
3197
3198 test_31m() {
3199         mkdir $DIR/d31m
3200         touch $DIR/d31m/s
3201         mkdir $DIR/d31m2
3202         touch $DIR/d31m2/exist
3203         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3204         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3205         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3206         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3207         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3208         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3209         return 0
3210 }
3211 run_test 31m "link to file: the same, non-existing, dir==============="
3212
3213 test_31n() {
3214         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3215         nlink=$(stat --format=%h $DIR/$tfile)
3216         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3217         local fd=$(free_fd)
3218         local cmd="exec $fd<$DIR/$tfile"
3219         eval $cmd
3220         cmd="exec $fd<&-"
3221         trap "eval $cmd" EXIT
3222         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3223         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3224         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3225         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3226         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3227         eval $cmd
3228 }
3229 run_test 31n "check link count of unlinked file"
3230
3231 link_one() {
3232         local tempfile=$(mktemp $1_XXXXXX)
3233         mlink $tempfile $1 2> /dev/null &&
3234                 echo "$BASHPID: link $tempfile to $1 succeeded"
3235         munlink $tempfile
3236 }
3237
3238 test_31o() { # LU-2901
3239         test_mkdir $DIR/$tdir
3240         for LOOP in $(seq 100); do
3241                 rm -f $DIR/$tdir/$tfile*
3242                 for THREAD in $(seq 8); do
3243                         link_one $DIR/$tdir/$tfile.$LOOP &
3244                 done
3245                 wait
3246                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3247                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3248                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3249                         break || true
3250         done
3251 }
3252 run_test 31o "duplicate hard links with same filename"
3253
3254 test_31p() {
3255         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3256
3257         test_mkdir $DIR/$tdir
3258         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3259         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3260
3261         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3262                 error "open unlink test1 failed"
3263         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3264                 error "open unlink test2 failed"
3265
3266         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3267                 error "test1 still exists"
3268         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3269                 error "test2 still exists"
3270 }
3271 run_test 31p "remove of open striped directory"
3272
3273 cleanup_test32_mount() {
3274         local rc=0
3275         trap 0
3276         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3277         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3278         losetup -d $loopdev || true
3279         rm -rf $DIR/$tdir
3280         return $rc
3281 }
3282
3283 test_32a() {
3284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3285
3286         echo "== more mountpoints and symlinks ================="
3287         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3288         trap cleanup_test32_mount EXIT
3289         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3290         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3291                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3292         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3293                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3294         cleanup_test32_mount
3295 }
3296 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3297
3298 test_32b() {
3299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3300
3301         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3302         trap cleanup_test32_mount EXIT
3303         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3304         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3305                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3306         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3307                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3308         cleanup_test32_mount
3309 }
3310 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3311
3312 test_32c() {
3313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3314
3315         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3316         trap cleanup_test32_mount EXIT
3317         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3318         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3319                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3320         test_mkdir -p $DIR/$tdir/d2/test_dir
3321         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3322                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3323         cleanup_test32_mount
3324 }
3325 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3326
3327 test_32d() {
3328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3329
3330         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3331         trap cleanup_test32_mount EXIT
3332         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3333         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3334                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3335         test_mkdir -p $DIR/$tdir/d2/test_dir
3336         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3337                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3338         cleanup_test32_mount
3339 }
3340 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3341
3342 test_32e() {
3343         rm -fr $DIR/$tdir
3344         test_mkdir -p $DIR/$tdir/tmp
3345         local tmp_dir=$DIR/$tdir/tmp
3346         ln -s $DIR/$tdir $tmp_dir/symlink11
3347         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3348         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3349         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3350 }
3351 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3352
3353 test_32f() {
3354         rm -fr $DIR/$tdir
3355         test_mkdir -p $DIR/$tdir/tmp
3356         local tmp_dir=$DIR/$tdir/tmp
3357         ln -s $DIR/$tdir $tmp_dir/symlink11
3358         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3359         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3360         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3361 }
3362 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3363
3364 test_32g() {
3365         local tmp_dir=$DIR/$tdir/tmp
3366         test_mkdir -p $tmp_dir
3367         test_mkdir $DIR/${tdir}2
3368         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3369         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3370         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3371         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3372         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3373         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3374 }
3375 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3376
3377 test_32h() {
3378         rm -fr $DIR/$tdir $DIR/${tdir}2
3379         tmp_dir=$DIR/$tdir/tmp
3380         test_mkdir -p $tmp_dir
3381         test_mkdir $DIR/${tdir}2
3382         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3383         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3384         ls $tmp_dir/symlink12 || error "listing symlink12"
3385         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3386 }
3387 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3388
3389 test_32i() {
3390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3391
3392         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3393         trap cleanup_test32_mount EXIT
3394         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3395         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3396                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3397         touch $DIR/$tdir/test_file
3398         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3399                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3400         cleanup_test32_mount
3401 }
3402 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3403
3404 test_32j() {
3405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3406
3407         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3408         trap cleanup_test32_mount EXIT
3409         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3410         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3411                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3412         touch $DIR/$tdir/test_file
3413         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3414                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3415         cleanup_test32_mount
3416 }
3417 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3418
3419 test_32k() {
3420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3421
3422         rm -fr $DIR/$tdir
3423         trap cleanup_test32_mount EXIT
3424         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3425         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3426                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3427         test_mkdir -p $DIR/$tdir/d2
3428         touch $DIR/$tdir/d2/test_file || error "touch failed"
3429         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3430                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3431         cleanup_test32_mount
3432 }
3433 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3434
3435 test_32l() {
3436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3437
3438         rm -fr $DIR/$tdir
3439         trap cleanup_test32_mount EXIT
3440         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3441         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3442                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3443         test_mkdir -p $DIR/$tdir/d2
3444         touch $DIR/$tdir/d2/test_file || error "touch failed"
3445         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3446                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3447         cleanup_test32_mount
3448 }
3449 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3450
3451 test_32m() {
3452         rm -fr $DIR/d32m
3453         test_mkdir -p $DIR/d32m/tmp
3454         TMP_DIR=$DIR/d32m/tmp
3455         ln -s $DIR $TMP_DIR/symlink11
3456         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3457         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3458                 error "symlink11 not a link"
3459         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3460                 error "symlink01 not a link"
3461 }
3462 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3463
3464 test_32n() {
3465         rm -fr $DIR/d32n
3466         test_mkdir -p $DIR/d32n/tmp
3467         TMP_DIR=$DIR/d32n/tmp
3468         ln -s $DIR $TMP_DIR/symlink11
3469         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3470         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3471         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3472 }
3473 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3474
3475 test_32o() {
3476         touch $DIR/$tfile
3477         test_mkdir -p $DIR/d32o/tmp
3478         TMP_DIR=$DIR/d32o/tmp
3479         ln -s $DIR/$tfile $TMP_DIR/symlink12
3480         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3481         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3482                 error "symlink12 not a link"
3483         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3484         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3485                 error "$DIR/d32o/tmp/symlink12 not file type"
3486         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3487                 error "$DIR/d32o/symlink02 not file type"
3488 }
3489 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3490
3491 test_32p() {
3492         log 32p_1
3493         rm -fr $DIR/d32p
3494         log 32p_2
3495         rm -f $DIR/$tfile
3496         log 32p_3
3497         touch $DIR/$tfile
3498         log 32p_4
3499         test_mkdir -p $DIR/d32p/tmp
3500         log 32p_5
3501         TMP_DIR=$DIR/d32p/tmp
3502         log 32p_6
3503         ln -s $DIR/$tfile $TMP_DIR/symlink12
3504         log 32p_7
3505         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3506         log 32p_8
3507         cat $DIR/d32p/tmp/symlink12 ||
3508                 error "Can't open $DIR/d32p/tmp/symlink12"
3509         log 32p_9
3510         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3511         log 32p_10
3512 }
3513 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3514
3515 test_32q() {
3516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3517
3518         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3519         trap cleanup_test32_mount EXIT
3520         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3521         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3522         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3523                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3524         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3525         cleanup_test32_mount
3526 }
3527 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3528
3529 test_32r() {
3530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3531
3532         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3533         trap cleanup_test32_mount EXIT
3534         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3535         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3536         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3537                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3538         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3539         cleanup_test32_mount
3540 }
3541 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3542
3543 test_33aa() {
3544         rm -f $DIR/$tfile
3545         touch $DIR/$tfile
3546         chmod 444 $DIR/$tfile
3547         chown $RUNAS_ID $DIR/$tfile
3548         log 33_1
3549         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3550         log 33_2
3551 }
3552 run_test 33aa "write file with mode 444 (should return error)"
3553
3554 test_33a() {
3555         rm -fr $DIR/$tdir
3556         test_mkdir $DIR/$tdir
3557         chown $RUNAS_ID $DIR/$tdir
3558         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3559                 error "$RUNAS create $tdir/$tfile failed"
3560         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3561                 error "open RDWR" || true
3562 }
3563 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3564
3565 test_33b() {
3566         rm -fr $DIR/$tdir
3567         test_mkdir $DIR/$tdir
3568         chown $RUNAS_ID $DIR/$tdir
3569         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3570 }
3571 run_test 33b "test open file with malformed flags (No panic)"
3572
3573 test_33c() {
3574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3575         remote_ost_nodsh && skip "remote OST with nodsh"
3576
3577         local ostnum
3578         local ostname
3579         local write_bytes
3580         local all_zeros
3581
3582         all_zeros=:
3583         rm -fr $DIR/$tdir
3584         test_mkdir $DIR/$tdir
3585         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3586
3587         sync
3588         for ostnum in $(seq $OSTCOUNT); do
3589                 # test-framework's OST numbering is one-based, while Lustre's
3590                 # is zero-based
3591                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3592                 # Parsing llobdstat's output sucks; we could grep the /proc
3593                 # path, but that's likely to not be as portable as using the
3594                 # llobdstat utility.  So we parse lctl output instead.
3595                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3596                         obdfilter/$ostname/stats |
3597                         awk '/^write_bytes/ {print $7}' )
3598                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3599                 if (( ${write_bytes:-0} > 0 ))
3600                 then
3601                         all_zeros=false
3602                         break;
3603                 fi
3604         done
3605
3606         $all_zeros || return 0
3607
3608         # Write four bytes
3609         echo foo > $DIR/$tdir/bar
3610         # Really write them
3611         sync
3612
3613         # Total up write_bytes after writing.  We'd better find non-zeros.
3614         for ostnum in $(seq $OSTCOUNT); do
3615                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3616                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3617                         obdfilter/$ostname/stats |
3618                         awk '/^write_bytes/ {print $7}' )
3619                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3620                 if (( ${write_bytes:-0} > 0 ))
3621                 then
3622                         all_zeros=false
3623                         break;
3624                 fi
3625         done
3626
3627         if $all_zeros
3628         then
3629                 for ostnum in $(seq $OSTCOUNT); do
3630                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3631                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3632                         do_facet ost$ostnum lctl get_param -n \
3633                                 obdfilter/$ostname/stats
3634                 done
3635                 error "OST not keeping write_bytes stats (b22312)"
3636         fi
3637 }
3638 run_test 33c "test llobdstat and write_bytes"
3639
3640 test_33d() {
3641         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3643
3644         local MDTIDX=1
3645         local remote_dir=$DIR/$tdir/remote_dir
3646
3647         test_mkdir $DIR/$tdir
3648         $LFS mkdir -i $MDTIDX $remote_dir ||
3649                 error "create remote directory failed"
3650
3651         touch $remote_dir/$tfile
3652         chmod 444 $remote_dir/$tfile
3653         chown $RUNAS_ID $remote_dir/$tfile
3654
3655         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3656
3657         chown $RUNAS_ID $remote_dir
3658         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3659                                         error "create" || true
3660         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3661                                     error "open RDWR" || true
3662         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3663 }
3664 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3665
3666 test_33e() {
3667         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3668
3669         mkdir $DIR/$tdir
3670
3671         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3672         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3673         mkdir $DIR/$tdir/local_dir
3674
3675         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3676         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3677         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3678
3679         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3680                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3681
3682         rmdir $DIR/$tdir/* || error "rmdir failed"
3683
3684         umask 777
3685         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3686         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3687         mkdir $DIR/$tdir/local_dir
3688
3689         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3690         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3691         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3692
3693         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3694                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3695
3696         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3697
3698         umask 000
3699         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3700         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3701         mkdir $DIR/$tdir/local_dir
3702
3703         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3704         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3705         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3706
3707         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3708                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3709 }
3710 run_test 33e "mkdir and striped directory should have same mode"
3711
3712 cleanup_33f() {
3713         trap 0
3714         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3715 }
3716
3717 test_33f() {
3718         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3719         remote_mds_nodsh && skip "remote MDS with nodsh"
3720
3721         mkdir $DIR/$tdir
3722         chmod go+rwx $DIR/$tdir
3723         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3724         trap cleanup_33f EXIT
3725
3726         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3727                 error "cannot create striped directory"
3728
3729         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3730                 error "cannot create files in striped directory"
3731
3732         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3733                 error "cannot remove files in striped directory"
3734
3735         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3736                 error "cannot remove striped directory"
3737
3738         cleanup_33f
3739 }
3740 run_test 33f "nonroot user can create, access, and remove a striped directory"
3741
3742 test_33g() {
3743         mkdir -p $DIR/$tdir/dir2
3744
3745         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3746         echo $err
3747         [[ $err =~ "exists" ]] || error "Not exists error"
3748 }
3749 run_test 33g "nonroot user create already existing root created file"
3750
3751 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3752 test_34a() {
3753         rm -f $DIR/f34
3754         $MCREATE $DIR/f34 || error "mcreate failed"
3755         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3756                 error "getstripe failed"
3757         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3758         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3759                 error "getstripe failed"
3760         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3761                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3762 }
3763 run_test 34a "truncate file that has not been opened ==========="
3764
3765 test_34b() {
3766         [ ! -f $DIR/f34 ] && test_34a
3767         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3768                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3769         $OPENFILE -f O_RDONLY $DIR/f34
3770         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3771                 error "getstripe failed"
3772         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3773                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3774 }
3775 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3776
3777 test_34c() {
3778         [ ! -f $DIR/f34 ] && test_34a
3779         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3780                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3781         $OPENFILE -f O_RDWR $DIR/f34
3782         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3783                 error "$LFS getstripe failed"
3784         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3785                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3786 }
3787 run_test 34c "O_RDWR opening file-with-size works =============="
3788
3789 test_34d() {
3790         [ ! -f $DIR/f34 ] && test_34a
3791         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3792                 error "dd failed"
3793         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3794                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3795         rm $DIR/f34
3796 }
3797 run_test 34d "write to sparse file ============================="
3798
3799 test_34e() {
3800         rm -f $DIR/f34e
3801         $MCREATE $DIR/f34e || error "mcreate failed"
3802         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3803         $CHECKSTAT -s 1000 $DIR/f34e ||
3804                 error "Size of $DIR/f34e not equal to 1000 bytes"
3805         $OPENFILE -f O_RDWR $DIR/f34e
3806         $CHECKSTAT -s 1000 $DIR/f34e ||
3807                 error "Size of $DIR/f34e not equal to 1000 bytes"
3808 }
3809 run_test 34e "create objects, some with size and some without =="
3810
3811 test_34f() { # bug 6242, 6243
3812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3813
3814         SIZE34F=48000
3815         rm -f $DIR/f34f
3816         $MCREATE $DIR/f34f || error "mcreate failed"
3817         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3818         dd if=$DIR/f34f of=$TMP/f34f
3819         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3820         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3821         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3822         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3823         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3824 }
3825 run_test 34f "read from a file with no objects until EOF ======="
3826
3827 test_34g() {
3828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3829
3830         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3831                 error "dd failed"
3832         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3833         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3834                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3835         cancel_lru_locks osc
3836         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3837                 error "wrong size after lock cancel"
3838
3839         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3840         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3841                 error "expanding truncate failed"
3842         cancel_lru_locks osc
3843         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3844                 error "wrong expanded size after lock cancel"
3845 }
3846 run_test 34g "truncate long file ==============================="
3847
3848 test_34h() {
3849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3850
3851         local gid=10
3852         local sz=1000
3853
3854         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3855         sync # Flush the cache so that multiop below does not block on cache
3856              # flush when getting the group lock
3857         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3858         MULTIPID=$!
3859
3860         # Since just timed wait is not good enough, let's do a sync write
3861         # that way we are sure enough time for a roundtrip + processing
3862         # passed + 2 seconds of extra margin.
3863         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3864         rm $DIR/${tfile}-1
3865         sleep 2
3866
3867         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3868                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3869                 kill -9 $MULTIPID
3870         fi
3871         wait $MULTIPID
3872         local nsz=`stat -c %s $DIR/$tfile`
3873         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3874 }
3875 run_test 34h "ftruncate file under grouplock should not block"
3876
3877 test_35a() {
3878         cp /bin/sh $DIR/f35a
3879         chmod 444 $DIR/f35a
3880         chown $RUNAS_ID $DIR/f35a
3881         $RUNAS $DIR/f35a && error || true
3882         rm $DIR/f35a
3883 }
3884 run_test 35a "exec file with mode 444 (should return and not leak)"
3885
3886 test_36a() {
3887         rm -f $DIR/f36
3888         utime $DIR/f36 || error "utime failed for MDS"
3889 }
3890 run_test 36a "MDS utime check (mknod, utime)"
3891
3892 test_36b() {
3893         echo "" > $DIR/f36
3894         utime $DIR/f36 || error "utime failed for OST"
3895 }
3896 run_test 36b "OST utime check (open, utime)"
3897
3898 test_36c() {
3899         rm -f $DIR/d36/f36
3900         test_mkdir $DIR/d36
3901         chown $RUNAS_ID $DIR/d36
3902         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3903 }
3904 run_test 36c "non-root MDS utime check (mknod, utime)"
3905
3906 test_36d() {
3907         [ ! -d $DIR/d36 ] && test_36c
3908         echo "" > $DIR/d36/f36
3909         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3910 }
3911 run_test 36d "non-root OST utime check (open, utime)"
3912
3913 test_36e() {
3914         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3915
3916         test_mkdir $DIR/$tdir
3917         touch $DIR/$tdir/$tfile
3918         $RUNAS utime $DIR/$tdir/$tfile &&
3919                 error "utime worked, expected failure" || true
3920 }
3921 run_test 36e "utime on non-owned file (should return error)"
3922
3923 subr_36fh() {
3924         local fl="$1"
3925         local LANG_SAVE=$LANG
3926         local LC_LANG_SAVE=$LC_LANG
3927         export LANG=C LC_LANG=C # for date language
3928
3929         DATESTR="Dec 20  2000"
3930         test_mkdir $DIR/$tdir
3931         lctl set_param fail_loc=$fl
3932         date; date +%s
3933         cp /etc/hosts $DIR/$tdir/$tfile
3934         sync & # write RPC generated with "current" inode timestamp, but delayed
3935         sleep 1
3936         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3937         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3938         cancel_lru_locks $OSC
3939         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3940         date; date +%s
3941         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3942                 echo "BEFORE: $LS_BEFORE" && \
3943                 echo "AFTER : $LS_AFTER" && \
3944                 echo "WANT  : $DATESTR" && \
3945                 error "$DIR/$tdir/$tfile timestamps changed" || true
3946
3947         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3948 }
3949
3950 test_36f() {
3951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3952
3953         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3954         subr_36fh "0x80000214"
3955 }
3956 run_test 36f "utime on file racing with OST BRW write =========="
3957
3958 test_36g() {
3959         remote_ost_nodsh && skip "remote OST with nodsh"
3960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3961         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3962                 skip "Need MDS version at least 2.12.51"
3963
3964         local fmd_max_age
3965         local fmd
3966         local facet="ost1"
3967         local tgt="obdfilter"
3968
3969         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3970
3971         test_mkdir $DIR/$tdir
3972         fmd_max_age=$(do_facet $facet \
3973                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3974                 head -n 1")
3975
3976         echo "FMD max age: ${fmd_max_age}s"
3977         touch $DIR/$tdir/$tfile
3978         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3979                 gawk '{cnt=cnt+$1}  END{print cnt}')
3980         echo "FMD before: $fmd"
3981         [[ $fmd == 0 ]] &&
3982                 error "FMD wasn't create by touch"
3983         sleep $((fmd_max_age + 12))
3984         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3985                 gawk '{cnt=cnt+$1}  END{print cnt}')
3986         echo "FMD after: $fmd"
3987         [[ $fmd == 0 ]] ||
3988                 error "FMD wasn't expired by ping"
3989 }
3990 run_test 36g "FMD cache expiry ====================="
3991
3992 test_36h() {
3993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3994
3995         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3996         subr_36fh "0x80000227"
3997 }
3998 run_test 36h "utime on file racing with OST BRW write =========="
3999
4000 test_36i() {
4001         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4002
4003         test_mkdir $DIR/$tdir
4004         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4005
4006         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4007         local new_mtime=$((mtime + 200))
4008
4009         #change Modify time of striped dir
4010         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4011                         error "change mtime failed"
4012
4013         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4014
4015         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4016 }
4017 run_test 36i "change mtime on striped directory"
4018
4019 # test_37 - duplicate with tests 32q 32r
4020
4021 test_38() {
4022         local file=$DIR/$tfile
4023         touch $file
4024         openfile -f O_DIRECTORY $file
4025         local RC=$?
4026         local ENOTDIR=20
4027         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4028         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4029 }
4030 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4031
4032 test_39a() { # was test_39
4033         touch $DIR/$tfile
4034         touch $DIR/${tfile}2
4035 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4036 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4037 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4038         sleep 2
4039         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4040         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4041                 echo "mtime"
4042                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4043                 echo "atime"
4044                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4045                 echo "ctime"
4046                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4047                 error "O_TRUNC didn't change timestamps"
4048         fi
4049 }
4050 run_test 39a "mtime changed on create"
4051
4052 test_39b() {
4053         test_mkdir -c1 $DIR/$tdir
4054         cp -p /etc/passwd $DIR/$tdir/fopen
4055         cp -p /etc/passwd $DIR/$tdir/flink
4056         cp -p /etc/passwd $DIR/$tdir/funlink
4057         cp -p /etc/passwd $DIR/$tdir/frename
4058         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4059
4060         sleep 1
4061         echo "aaaaaa" >> $DIR/$tdir/fopen
4062         echo "aaaaaa" >> $DIR/$tdir/flink
4063         echo "aaaaaa" >> $DIR/$tdir/funlink
4064         echo "aaaaaa" >> $DIR/$tdir/frename
4065
4066         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4067         local link_new=`stat -c %Y $DIR/$tdir/flink`
4068         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4069         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4070
4071         cat $DIR/$tdir/fopen > /dev/null
4072         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4073         rm -f $DIR/$tdir/funlink2
4074         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4075
4076         for (( i=0; i < 2; i++ )) ; do
4077                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4078                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4079                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4080                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4081
4082                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4083                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4084                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4085                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4086
4087                 cancel_lru_locks $OSC
4088                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4089         done
4090 }
4091 run_test 39b "mtime change on open, link, unlink, rename  ======"
4092
4093 # this should be set to past
4094 TEST_39_MTIME=`date -d "1 year ago" +%s`
4095
4096 # bug 11063
4097 test_39c() {
4098         touch $DIR1/$tfile
4099         sleep 2
4100         local mtime0=`stat -c %Y $DIR1/$tfile`
4101
4102         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4103         local mtime1=`stat -c %Y $DIR1/$tfile`
4104         [ "$mtime1" = $TEST_39_MTIME ] || \
4105                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4106
4107         local d1=`date +%s`
4108         echo hello >> $DIR1/$tfile
4109         local d2=`date +%s`
4110         local mtime2=`stat -c %Y $DIR1/$tfile`
4111         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4112                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4113
4114         mv $DIR1/$tfile $DIR1/$tfile-1
4115
4116         for (( i=0; i < 2; i++ )) ; do
4117                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4118                 [ "$mtime2" = "$mtime3" ] || \
4119                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4120
4121                 cancel_lru_locks $OSC
4122                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4123         done
4124 }
4125 run_test 39c "mtime change on rename ==========================="
4126
4127 # bug 21114
4128 test_39d() {
4129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4130
4131         touch $DIR1/$tfile
4132         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4133
4134         for (( i=0; i < 2; i++ )) ; do
4135                 local mtime=`stat -c %Y $DIR1/$tfile`
4136                 [ $mtime = $TEST_39_MTIME ] || \
4137                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4138
4139                 cancel_lru_locks $OSC
4140                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4141         done
4142 }
4143 run_test 39d "create, utime, stat =============================="
4144
4145 # bug 21114
4146 test_39e() {
4147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4148
4149         touch $DIR1/$tfile
4150         local mtime1=`stat -c %Y $DIR1/$tfile`
4151
4152         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4153
4154         for (( i=0; i < 2; i++ )) ; do
4155                 local mtime2=`stat -c %Y $DIR1/$tfile`
4156                 [ $mtime2 = $TEST_39_MTIME ] || \
4157                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4158
4159                 cancel_lru_locks $OSC
4160                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4161         done
4162 }
4163 run_test 39e "create, stat, utime, stat ========================"
4164
4165 # bug 21114
4166 test_39f() {
4167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4168
4169         touch $DIR1/$tfile
4170         mtime1=`stat -c %Y $DIR1/$tfile`
4171
4172         sleep 2
4173         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4174
4175         for (( i=0; i < 2; i++ )) ; do
4176                 local mtime2=`stat -c %Y $DIR1/$tfile`
4177                 [ $mtime2 = $TEST_39_MTIME ] || \
4178                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4179
4180                 cancel_lru_locks $OSC
4181                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4182         done
4183 }
4184 run_test 39f "create, stat, sleep, utime, stat ================="
4185
4186 # bug 11063
4187 test_39g() {
4188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4189
4190         echo hello >> $DIR1/$tfile
4191         local mtime1=`stat -c %Y $DIR1/$tfile`
4192
4193         sleep 2
4194         chmod o+r $DIR1/$tfile
4195
4196         for (( i=0; i < 2; i++ )) ; do
4197                 local mtime2=`stat -c %Y $DIR1/$tfile`
4198                 [ "$mtime1" = "$mtime2" ] || \
4199                         error "lost mtime: $mtime2, should be $mtime1"
4200
4201                 cancel_lru_locks $OSC
4202                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4203         done
4204 }
4205 run_test 39g "write, chmod, stat ==============================="
4206
4207 # bug 11063
4208 test_39h() {
4209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4210
4211         touch $DIR1/$tfile
4212         sleep 1
4213
4214         local d1=`date`
4215         echo hello >> $DIR1/$tfile
4216         local mtime1=`stat -c %Y $DIR1/$tfile`
4217
4218         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4219         local d2=`date`
4220         if [ "$d1" != "$d2" ]; then
4221                 echo "write and touch not within one second"
4222         else
4223                 for (( i=0; i < 2; i++ )) ; do
4224                         local mtime2=`stat -c %Y $DIR1/$tfile`
4225                         [ "$mtime2" = $TEST_39_MTIME ] || \
4226                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4227
4228                         cancel_lru_locks $OSC
4229                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4230                 done
4231         fi
4232 }
4233 run_test 39h "write, utime within one second, stat ============="
4234
4235 test_39i() {
4236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4237
4238         touch $DIR1/$tfile
4239         sleep 1
4240
4241         echo hello >> $DIR1/$tfile
4242         local mtime1=`stat -c %Y $DIR1/$tfile`
4243
4244         mv $DIR1/$tfile $DIR1/$tfile-1
4245
4246         for (( i=0; i < 2; i++ )) ; do
4247                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4248
4249                 [ "$mtime1" = "$mtime2" ] || \
4250                         error "lost mtime: $mtime2, should be $mtime1"
4251
4252                 cancel_lru_locks $OSC
4253                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4254         done
4255 }
4256 run_test 39i "write, rename, stat =============================="
4257
4258 test_39j() {
4259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4260
4261         start_full_debug_logging
4262         touch $DIR1/$tfile
4263         sleep 1
4264
4265         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4266         lctl set_param fail_loc=0x80000412
4267         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4268                 error "multiop failed"
4269         local multipid=$!
4270         local mtime1=`stat -c %Y $DIR1/$tfile`
4271
4272         mv $DIR1/$tfile $DIR1/$tfile-1
4273
4274         kill -USR1 $multipid
4275         wait $multipid || error "multiop close failed"
4276
4277         for (( i=0; i < 2; i++ )) ; do
4278                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4279                 [ "$mtime1" = "$mtime2" ] ||
4280                         error "mtime is lost on close: $mtime2, " \
4281                               "should be $mtime1"
4282
4283                 cancel_lru_locks
4284                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4285         done
4286         lctl set_param fail_loc=0
4287         stop_full_debug_logging
4288 }
4289 run_test 39j "write, rename, close, stat ======================="
4290
4291 test_39k() {
4292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4293
4294         touch $DIR1/$tfile
4295         sleep 1
4296
4297         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4298         local multipid=$!
4299         local mtime1=`stat -c %Y $DIR1/$tfile`
4300
4301         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4302
4303         kill -USR1 $multipid
4304         wait $multipid || error "multiop close failed"
4305
4306         for (( i=0; i < 2; i++ )) ; do
4307                 local mtime2=`stat -c %Y $DIR1/$tfile`
4308
4309                 [ "$mtime2" = $TEST_39_MTIME ] || \
4310                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4311
4312                 cancel_lru_locks
4313                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4314         done
4315 }
4316 run_test 39k "write, utime, close, stat ========================"
4317
4318 # this should be set to future
4319 TEST_39_ATIME=`date -d "1 year" +%s`
4320
4321 test_39l() {
4322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4323         remote_mds_nodsh && skip "remote MDS with nodsh"
4324
4325         local atime_diff=$(do_facet $SINGLEMDS \
4326                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4327         rm -rf $DIR/$tdir
4328         mkdir -p $DIR/$tdir
4329
4330         # test setting directory atime to future
4331         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4332         local atime=$(stat -c %X $DIR/$tdir)
4333         [ "$atime" = $TEST_39_ATIME ] ||
4334                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4335
4336         # test setting directory atime from future to now
4337         local now=$(date +%s)
4338         touch -a -d @$now $DIR/$tdir
4339
4340         atime=$(stat -c %X $DIR/$tdir)
4341         [ "$atime" -eq "$now"  ] ||
4342                 error "atime is not updated from future: $atime, $now"
4343
4344         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4345         sleep 3
4346
4347         # test setting directory atime when now > dir atime + atime_diff
4348         local d1=$(date +%s)
4349         ls $DIR/$tdir
4350         local d2=$(date +%s)
4351         cancel_lru_locks mdc
4352         atime=$(stat -c %X $DIR/$tdir)
4353         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4354                 error "atime is not updated  : $atime, should be $d2"
4355
4356         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4357         sleep 3
4358
4359         # test not setting directory atime when now < dir atime + atime_diff
4360         ls $DIR/$tdir
4361         cancel_lru_locks mdc
4362         atime=$(stat -c %X $DIR/$tdir)
4363         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4364                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4365
4366         do_facet $SINGLEMDS \
4367                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4368 }
4369 run_test 39l "directory atime update ==========================="
4370
4371 test_39m() {
4372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4373
4374         touch $DIR1/$tfile
4375         sleep 2
4376         local far_past_mtime=$(date -d "May 29 1953" +%s)
4377         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4378
4379         touch -m -d @$far_past_mtime $DIR1/$tfile
4380         touch -a -d @$far_past_atime $DIR1/$tfile
4381
4382         for (( i=0; i < 2; i++ )) ; do
4383                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4384                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4385                         error "atime or mtime set incorrectly"
4386
4387                 cancel_lru_locks $OSC
4388                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4389         done
4390 }
4391 run_test 39m "test atime and mtime before 1970"
4392
4393 test_39n() { # LU-3832
4394         remote_mds_nodsh && skip "remote MDS with nodsh"
4395
4396         local atime_diff=$(do_facet $SINGLEMDS \
4397                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4398         local atime0
4399         local atime1
4400         local atime2
4401
4402         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4403
4404         rm -rf $DIR/$tfile
4405         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4406         atime0=$(stat -c %X $DIR/$tfile)
4407
4408         sleep 5
4409         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4410         atime1=$(stat -c %X $DIR/$tfile)
4411
4412         sleep 5
4413         cancel_lru_locks mdc
4414         cancel_lru_locks osc
4415         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4416         atime2=$(stat -c %X $DIR/$tfile)
4417
4418         do_facet $SINGLEMDS \
4419                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4420
4421         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4422         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4423 }
4424 run_test 39n "check that O_NOATIME is honored"
4425
4426 test_39o() {
4427         TESTDIR=$DIR/$tdir/$tfile
4428         [ -e $TESTDIR ] && rm -rf $TESTDIR
4429         mkdir -p $TESTDIR
4430         cd $TESTDIR
4431         links1=2
4432         ls
4433         mkdir a b
4434         ls
4435         links2=$(stat -c %h .)
4436         [ $(($links1 + 2)) != $links2 ] &&
4437                 error "wrong links count $(($links1 + 2)) != $links2"
4438         rmdir b
4439         links3=$(stat -c %h .)
4440         [ $(($links1 + 1)) != $links3 ] &&
4441                 error "wrong links count $links1 != $links3"
4442         return 0
4443 }
4444 run_test 39o "directory cached attributes updated after create"
4445
4446 test_39p() {
4447         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4448
4449         local MDTIDX=1
4450         TESTDIR=$DIR/$tdir/$tdir
4451         [ -e $TESTDIR ] && rm -rf $TESTDIR
4452         test_mkdir -p $TESTDIR
4453         cd $TESTDIR
4454         links1=2
4455         ls
4456         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4457         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4458         ls
4459         links2=$(stat -c %h .)
4460         [ $(($links1 + 2)) != $links2 ] &&
4461                 error "wrong links count $(($links1 + 2)) != $links2"
4462         rmdir remote_dir2
4463         links3=$(stat -c %h .)
4464         [ $(($links1 + 1)) != $links3 ] &&
4465                 error "wrong links count $links1 != $links3"
4466         return 0
4467 }
4468 run_test 39p "remote directory cached attributes updated after create ========"
4469
4470
4471 test_39q() { # LU-8041
4472         local testdir=$DIR/$tdir
4473         mkdir -p $testdir
4474         multiop_bg_pause $testdir D_c || error "multiop failed"
4475         local multipid=$!
4476         cancel_lru_locks mdc
4477         kill -USR1 $multipid
4478         local atime=$(stat -c %X $testdir)
4479         [ "$atime" -ne 0 ] || error "atime is zero"
4480 }
4481 run_test 39q "close won't zero out atime"
4482
4483 test_40() {
4484         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4485         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4486                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4487         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4488                 error "$tfile is not 4096 bytes in size"
4489 }
4490 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4491
4492 test_41() {
4493         # bug 1553
4494         small_write $DIR/f41 18
4495 }
4496 run_test 41 "test small file write + fstat ====================="
4497
4498 count_ost_writes() {
4499         lctl get_param -n ${OSC}.*.stats |
4500                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4501                         END { printf("%0.0f", writes) }'
4502 }
4503
4504 # decent default
4505 WRITEBACK_SAVE=500
4506 DIRTY_RATIO_SAVE=40
4507 MAX_DIRTY_RATIO=50
4508 BG_DIRTY_RATIO_SAVE=10
4509 MAX_BG_DIRTY_RATIO=25
4510
4511 start_writeback() {
4512         trap 0
4513         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4514         # dirty_ratio, dirty_background_ratio
4515         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4516                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4517                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4518                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4519         else
4520                 # if file not here, we are a 2.4 kernel
4521                 kill -CONT `pidof kupdated`
4522         fi
4523 }
4524
4525 stop_writeback() {
4526         # setup the trap first, so someone cannot exit the test at the
4527         # exact wrong time and mess up a machine
4528         trap start_writeback EXIT
4529         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4530         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4531                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4532                 sysctl -w vm.dirty_writeback_centisecs=0
4533                 sysctl -w vm.dirty_writeback_centisecs=0
4534                 # save and increase /proc/sys/vm/dirty_ratio
4535                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4536                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4537                 # save and increase /proc/sys/vm/dirty_background_ratio
4538                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4539                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4540         else
4541                 # if file not here, we are a 2.4 kernel
4542                 kill -STOP `pidof kupdated`
4543         fi
4544 }
4545
4546 # ensure that all stripes have some grant before we test client-side cache
4547 setup_test42() {
4548         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4549                 dd if=/dev/zero of=$i bs=4k count=1
4550                 rm $i
4551         done
4552 }
4553
4554 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4555 # file truncation, and file removal.
4556 test_42a() {
4557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4558
4559         setup_test42
4560         cancel_lru_locks $OSC
4561         stop_writeback
4562         sync; sleep 1; sync # just to be safe
4563         BEFOREWRITES=`count_ost_writes`
4564         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4565         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4566         AFTERWRITES=`count_ost_writes`
4567         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4568                 error "$BEFOREWRITES < $AFTERWRITES"
4569         start_writeback
4570 }
4571 run_test 42a "ensure that we don't flush on close"
4572
4573 test_42b() {
4574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4575
4576         setup_test42
4577         cancel_lru_locks $OSC
4578         stop_writeback
4579         sync
4580         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4581         BEFOREWRITES=$(count_ost_writes)
4582         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4583         AFTERWRITES=$(count_ost_writes)
4584         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4585                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4586         fi
4587         BEFOREWRITES=$(count_ost_writes)
4588         sync || error "sync: $?"
4589         AFTERWRITES=$(count_ost_writes)
4590         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4591                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4592         fi
4593         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4594         start_writeback
4595         return 0
4596 }
4597 run_test 42b "test destroy of file with cached dirty data ======"
4598
4599 # if these tests just want to test the effect of truncation,
4600 # they have to be very careful.  consider:
4601 # - the first open gets a {0,EOF}PR lock
4602 # - the first write conflicts and gets a {0, count-1}PW
4603 # - the rest of the writes are under {count,EOF}PW
4604 # - the open for truncate tries to match a {0,EOF}PR
4605 #   for the filesize and cancels the PWs.
4606 # any number of fixes (don't get {0,EOF} on open, match
4607 # composite locks, do smarter file size management) fix
4608 # this, but for now we want these tests to verify that
4609 # the cancellation with truncate intent works, so we
4610 # start the file with a full-file pw lock to match against
4611 # until the truncate.
4612 trunc_test() {
4613         test=$1
4614         file=$DIR/$test
4615         offset=$2
4616         cancel_lru_locks $OSC
4617         stop_writeback
4618         # prime the file with 0,EOF PW to match
4619         touch $file
4620         $TRUNCATE $file 0
4621         sync; sync
4622         # now the real test..
4623         dd if=/dev/zero of=$file bs=1024 count=100
4624         BEFOREWRITES=`count_ost_writes`
4625         $TRUNCATE $file $offset
4626         cancel_lru_locks $OSC
4627         AFTERWRITES=`count_ost_writes`
4628         start_writeback
4629 }
4630
4631 test_42c() {
4632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4633
4634         trunc_test 42c 1024
4635         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4636                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4637         rm $file
4638 }
4639 run_test 42c "test partial truncate of file with cached dirty data"
4640
4641 test_42d() {
4642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4643
4644         trunc_test 42d 0
4645         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4646                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4647         rm $file
4648 }
4649 run_test 42d "test complete truncate of file with cached dirty data"
4650
4651 test_42e() { # bug22074
4652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4653
4654         local TDIR=$DIR/${tdir}e
4655         local pages=16 # hardcoded 16 pages, don't change it.
4656         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4657         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4658         local max_dirty_mb
4659         local warmup_files
4660
4661         test_mkdir $DIR/${tdir}e
4662         $LFS setstripe -c 1 $TDIR
4663         createmany -o $TDIR/f $files
4664
4665         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4666
4667         # we assume that with $OSTCOUNT files, at least one of them will
4668         # be allocated on OST0.
4669         warmup_files=$((OSTCOUNT * max_dirty_mb))
4670         createmany -o $TDIR/w $warmup_files
4671
4672         # write a large amount of data into one file and sync, to get good
4673         # avail_grant number from OST.
4674         for ((i=0; i<$warmup_files; i++)); do
4675                 idx=$($LFS getstripe -i $TDIR/w$i)
4676                 [ $idx -ne 0 ] && continue
4677                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4678                 break
4679         done
4680         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4681         sync
4682         $LCTL get_param $proc_osc0/cur_dirty_bytes
4683         $LCTL get_param $proc_osc0/cur_grant_bytes
4684
4685         # create as much dirty pages as we can while not to trigger the actual
4686         # RPCs directly. but depends on the env, VFS may trigger flush during this
4687         # period, hopefully we are good.
4688         for ((i=0; i<$warmup_files; i++)); do
4689                 idx=$($LFS getstripe -i $TDIR/w$i)
4690                 [ $idx -ne 0 ] && continue
4691                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4692         done
4693         $LCTL get_param $proc_osc0/cur_dirty_bytes
4694         $LCTL get_param $proc_osc0/cur_grant_bytes
4695
4696         # perform the real test
4697         $LCTL set_param $proc_osc0/rpc_stats 0
4698         for ((;i<$files; i++)); do
4699                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4700                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4701         done
4702         sync
4703         $LCTL get_param $proc_osc0/rpc_stats
4704
4705         local percent=0
4706         local have_ppr=false
4707         $LCTL get_param $proc_osc0/rpc_stats |
4708                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4709                         # skip lines until we are at the RPC histogram data
4710                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4711                         $have_ppr || continue
4712
4713                         # we only want the percent stat for < 16 pages
4714                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4715
4716                         percent=$((percent + WPCT))
4717                         if [[ $percent -gt 15 ]]; then
4718                                 error "less than 16-pages write RPCs" \
4719                                       "$percent% > 15%"
4720                                 break
4721                         fi
4722                 done
4723         rm -rf $TDIR
4724 }
4725 run_test 42e "verify sub-RPC writes are not done synchronously"
4726
4727 test_43A() { # was test_43
4728         test_mkdir $DIR/$tdir
4729         cp -p /bin/ls $DIR/$tdir/$tfile
4730         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4731         pid=$!
4732         # give multiop a chance to open
4733         sleep 1
4734
4735         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4736         kill -USR1 $pid
4737 }
4738 run_test 43A "execution of file opened for write should return -ETXTBSY"
4739
4740 test_43a() {
4741         test_mkdir $DIR/$tdir
4742         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4743         $DIR/$tdir/sleep 60 &
4744         SLEEP_PID=$!
4745         # Make sure exec of $tdir/sleep wins race with truncate
4746         sleep 1
4747         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4748         kill $SLEEP_PID
4749 }
4750 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4751
4752 test_43b() {
4753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4754
4755         test_mkdir $DIR/$tdir
4756         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4757         $DIR/$tdir/sleep 60 &
4758         SLEEP_PID=$!
4759         # Make sure exec of $tdir/sleep wins race with truncate
4760         sleep 1
4761         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4762         kill $SLEEP_PID
4763 }
4764 run_test 43b "truncate of file being executed should return -ETXTBSY"
4765
4766 test_43c() {
4767         local testdir="$DIR/$tdir"
4768         test_mkdir $testdir
4769         cp $SHELL $testdir/
4770         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4771                 ( cd $testdir && md5sum -c )
4772 }
4773 run_test 43c "md5sum of copy into lustre"
4774
4775 test_44A() { # was test_44
4776         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4777
4778         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4779         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4780 }
4781 run_test 44A "zero length read from a sparse stripe"
4782
4783 test_44a() {
4784         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4785                 awk '{ print $2 }')
4786         [ -z "$nstripe" ] && skip "can't get stripe info"
4787         [[ $nstripe -gt $OSTCOUNT ]] &&
4788                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4789
4790         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4791                 awk '{ print $2 }')
4792         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4793                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4794                         awk '{ print $2 }')
4795         fi
4796
4797         OFFSETS="0 $((stride/2)) $((stride-1))"
4798         for offset in $OFFSETS; do
4799                 for i in $(seq 0 $((nstripe-1))); do
4800                         local GLOBALOFFSETS=""
4801                         # size in Bytes
4802                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4803                         local myfn=$DIR/d44a-$size
4804                         echo "--------writing $myfn at $size"
4805                         ll_sparseness_write $myfn $size ||
4806                                 error "ll_sparseness_write"
4807                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4808                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4809                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4810
4811                         for j in $(seq 0 $((nstripe-1))); do
4812                                 # size in Bytes
4813                                 size=$((((j + $nstripe )*$stride + $offset)))
4814                                 ll_sparseness_write $myfn $size ||
4815                                         error "ll_sparseness_write"
4816                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4817                         done
4818                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4819                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4820                         rm -f $myfn
4821                 done
4822         done
4823 }
4824 run_test 44a "test sparse pwrite ==============================="
4825
4826 dirty_osc_total() {
4827         tot=0
4828         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4829                 tot=$(($tot + $d))
4830         done
4831         echo $tot
4832 }
4833 do_dirty_record() {
4834         before=`dirty_osc_total`
4835         echo executing "\"$*\""
4836         eval $*
4837         after=`dirty_osc_total`
4838         echo before $before, after $after
4839 }
4840 test_45() {
4841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4842
4843         f="$DIR/f45"
4844         # Obtain grants from OST if it supports it
4845         echo blah > ${f}_grant
4846         stop_writeback
4847         sync
4848         do_dirty_record "echo blah > $f"
4849         [[ $before -eq $after ]] && error "write wasn't cached"
4850         do_dirty_record "> $f"
4851         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4852         do_dirty_record "echo blah > $f"
4853         [[ $before -eq $after ]] && error "write wasn't cached"
4854         do_dirty_record "sync"
4855         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4856         do_dirty_record "echo blah > $f"
4857         [[ $before -eq $after ]] && error "write wasn't cached"
4858         do_dirty_record "cancel_lru_locks osc"
4859         [[ $before -gt $after ]] ||
4860                 error "lock cancellation didn't lower dirty count"
4861         start_writeback
4862 }
4863 run_test 45 "osc io page accounting ============================"
4864
4865 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4866 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4867 # objects offset and an assert hit when an rpc was built with 1023's mapped
4868 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4869 test_46() {
4870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4871
4872         f="$DIR/f46"
4873         stop_writeback
4874         sync
4875         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4876         sync
4877         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4878         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4879         sync
4880         start_writeback
4881 }
4882 run_test 46 "dirtying a previously written page ================"
4883
4884 # test_47 is removed "Device nodes check" is moved to test_28
4885
4886 test_48a() { # bug 2399
4887         [ "$mds1_FSTYPE" = "zfs" ] &&
4888         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4889                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4890
4891         test_mkdir $DIR/$tdir
4892         cd $DIR/$tdir
4893         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4894         test_mkdir $DIR/$tdir
4895         touch foo || error "'touch foo' failed after recreating cwd"
4896         test_mkdir bar
4897         touch .foo || error "'touch .foo' failed after recreating cwd"
4898         test_mkdir .bar
4899         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4900         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4901         cd . || error "'cd .' failed after recreating cwd"
4902         mkdir . && error "'mkdir .' worked after recreating cwd"
4903         rmdir . && error "'rmdir .' worked after recreating cwd"
4904         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4905         cd .. || error "'cd ..' failed after recreating cwd"
4906 }
4907 run_test 48a "Access renamed working dir (should return errors)="
4908
4909 test_48b() { # bug 2399
4910         rm -rf $DIR/$tdir
4911         test_mkdir $DIR/$tdir
4912         cd $DIR/$tdir
4913         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4914         touch foo && error "'touch foo' worked after removing cwd"
4915         mkdir foo && error "'mkdir foo' worked after removing cwd"
4916         touch .foo && error "'touch .foo' worked after removing cwd"
4917         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4918         ls . > /dev/null && error "'ls .' worked after removing cwd"
4919         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4920         mkdir . && error "'mkdir .' worked after removing cwd"
4921         rmdir . && error "'rmdir .' worked after removing cwd"
4922         ln -s . foo && error "'ln -s .' worked after removing cwd"
4923         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4924 }
4925 run_test 48b "Access removed working dir (should return errors)="
4926
4927 test_48c() { # bug 2350
4928         #lctl set_param debug=-1
4929         #set -vx
4930         rm -rf $DIR/$tdir
4931         test_mkdir -p $DIR/$tdir/dir
4932         cd $DIR/$tdir/dir
4933         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4934         $TRACE touch foo && error "touch foo worked after removing cwd"
4935         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4936         touch .foo && error "touch .foo worked after removing cwd"
4937         mkdir .foo && error "mkdir .foo worked after removing cwd"
4938         $TRACE ls . && error "'ls .' worked after removing cwd"
4939         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4940         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4941         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4942         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4943         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4944 }
4945 run_test 48c "Access removed working subdir (should return errors)"
4946
4947 test_48d() { # bug 2350
4948         #lctl set_param debug=-1
4949         #set -vx
4950         rm -rf $DIR/$tdir
4951         test_mkdir -p $DIR/$tdir/dir
4952         cd $DIR/$tdir/dir
4953         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4954         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4955         $TRACE touch foo && error "'touch foo' worked after removing parent"
4956         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4957         touch .foo && error "'touch .foo' worked after removing parent"
4958         mkdir .foo && error "mkdir .foo worked after removing parent"
4959         $TRACE ls . && error "'ls .' worked after removing parent"
4960         $TRACE ls .. && error "'ls ..' worked after removing parent"
4961         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4962         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4963         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4964         true
4965 }
4966 run_test 48d "Access removed parent subdir (should return errors)"
4967
4968 test_48e() { # bug 4134
4969         #lctl set_param debug=-1
4970         #set -vx
4971         rm -rf $DIR/$tdir
4972         test_mkdir -p $DIR/$tdir/dir
4973         cd $DIR/$tdir/dir
4974         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4975         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4976         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4977         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4978         # On a buggy kernel addition of "touch foo" after cd .. will
4979         # produce kernel oops in lookup_hash_it
4980         touch ../foo && error "'cd ..' worked after recreate parent"
4981         cd $DIR
4982         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4983 }
4984 run_test 48e "Access to recreated parent subdir (should return errors)"
4985
4986 test_49() { # LU-1030
4987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4988         remote_ost_nodsh && skip "remote OST with nodsh"
4989
4990         # get ost1 size - $FSNAME-OST0000
4991         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4992                 awk '{ print $4 }')
4993         # write 800M at maximum
4994         [[ $ost1_size -lt 2 ]] && ost1_size=2
4995         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4996
4997         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4998         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4999         local dd_pid=$!
5000
5001         # change max_pages_per_rpc while writing the file
5002         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5003         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5004         # loop until dd process exits
5005         while ps ax -opid | grep -wq $dd_pid; do
5006                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5007                 sleep $((RANDOM % 5 + 1))
5008         done
5009         # restore original max_pages_per_rpc
5010         $LCTL set_param $osc1_mppc=$orig_mppc
5011         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5012 }
5013 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5014
5015 test_50() {
5016         # bug 1485
5017         test_mkdir $DIR/$tdir
5018         cd $DIR/$tdir
5019         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5020 }
5021 run_test 50 "special situations: /proc symlinks  ==============="
5022
5023 test_51a() {    # was test_51
5024         # bug 1516 - create an empty entry right after ".." then split dir
5025         test_mkdir -c1 $DIR/$tdir
5026         touch $DIR/$tdir/foo
5027         $MCREATE $DIR/$tdir/bar
5028         rm $DIR/$tdir/foo
5029         createmany -m $DIR/$tdir/longfile 201
5030         FNUM=202
5031         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5032                 $MCREATE $DIR/$tdir/longfile$FNUM
5033                 FNUM=$(($FNUM + 1))
5034                 echo -n "+"
5035         done
5036         echo
5037         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5038 }
5039 run_test 51a "special situations: split htree with empty entry =="
5040
5041 cleanup_print_lfs_df () {
5042         trap 0
5043         $LFS df
5044         $LFS df -i
5045 }
5046
5047 test_51b() {
5048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5049
5050         local dir=$DIR/$tdir
5051         local nrdirs=$((65536 + 100))
5052
5053         # cleanup the directory
5054         rm -fr $dir
5055
5056         test_mkdir -c1 $dir
5057
5058         $LFS df
5059         $LFS df -i
5060         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5061         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5062         [[ $numfree -lt $nrdirs ]] &&
5063                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5064
5065         # need to check free space for the directories as well
5066         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5067         numfree=$(( blkfree / $(fs_inode_ksize) ))
5068         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5069
5070         trap cleanup_print_lfs_df EXIT
5071
5072         # create files
5073         createmany -d $dir/d $nrdirs || {
5074                 unlinkmany $dir/d $nrdirs
5075                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5076         }
5077
5078         # really created :
5079         nrdirs=$(ls -U $dir | wc -l)
5080
5081         # unlink all but 100 subdirectories, then check it still works
5082         local left=100
5083         local delete=$((nrdirs - left))
5084
5085         $LFS df
5086         $LFS df -i
5087
5088         # for ldiskfs the nlink count should be 1, but this is OSD specific
5089         # and so this is listed for informational purposes only
5090         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5091         unlinkmany -d $dir/d $delete ||
5092                 error "unlink of first $delete subdirs failed"
5093
5094         echo "nlink between: $(stat -c %h $dir)"
5095         local found=$(ls -U $dir | wc -l)
5096         [ $found -ne $left ] &&
5097                 error "can't find subdirs: found only $found, expected $left"
5098
5099         unlinkmany -d $dir/d $delete $left ||
5100                 error "unlink of second $left subdirs failed"
5101         # regardless of whether the backing filesystem tracks nlink accurately
5102         # or not, the nlink count shouldn't be more than "." and ".." here
5103         local after=$(stat -c %h $dir)
5104         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5105                 echo "nlink after: $after"
5106
5107         cleanup_print_lfs_df
5108 }
5109 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5110
5111 test_51d() {
5112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5113         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5114
5115         test_mkdir $DIR/$tdir
5116         createmany -o $DIR/$tdir/t- 1000
5117         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5118         for N in $(seq 0 $((OSTCOUNT - 1))); do
5119                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5120                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5121                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5122                         '($1 == '$N') { objs += 1 } \
5123                         END { printf("%0.0f", objs) }')
5124                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5125         done
5126         unlinkmany $DIR/$tdir/t- 1000
5127
5128         NLAST=0
5129         for N in $(seq 1 $((OSTCOUNT - 1))); do
5130                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5131                         error "OST $N has less objects vs OST $NLAST" \
5132                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5133                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5134                         error "OST $N has less objects vs OST $NLAST" \
5135                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5136
5137                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5138                         error "OST $N has less #0 objects vs OST $NLAST" \
5139                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5140                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5141                         error "OST $N has less #0 objects vs OST $NLAST" \
5142                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5143                 NLAST=$N
5144         done
5145         rm -f $TMP/$tfile
5146 }
5147 run_test 51d "check object distribution"
5148
5149 test_51e() {
5150         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5151                 skip_env "ldiskfs only test"
5152         fi
5153
5154         test_mkdir -c1 $DIR/$tdir
5155         test_mkdir -c1 $DIR/$tdir/d0
5156
5157         touch $DIR/$tdir/d0/foo
5158         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5159                 error "file exceed 65000 nlink limit!"
5160         unlinkmany $DIR/$tdir/d0/f- 65001
5161         return 0
5162 }
5163 run_test 51e "check file nlink limit"
5164
5165 test_51f() {
5166         test_mkdir $DIR/$tdir
5167
5168         local max=100000
5169         local ulimit_old=$(ulimit -n)
5170         local spare=20 # number of spare fd's for scripts/libraries, etc.
5171         local mdt=$($LFS getstripe -m $DIR/$tdir)
5172         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5173
5174         echo "MDT$mdt numfree=$numfree, max=$max"
5175         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5176         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5177                 while ! ulimit -n $((numfree + spare)); do
5178                         numfree=$((numfree * 3 / 4))
5179                 done
5180                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5181         else
5182                 echo "left ulimit at $ulimit_old"
5183         fi
5184
5185         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5186                 unlinkmany $DIR/$tdir/f $numfree
5187                 error "create+open $numfree files in $DIR/$tdir failed"
5188         }
5189         ulimit -n $ulimit_old
5190
5191         # if createmany exits at 120s there will be fewer than $numfree files
5192         unlinkmany $DIR/$tdir/f $numfree || true
5193 }
5194 run_test 51f "check many open files limit"
5195
5196 test_52a() {
5197         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5198         test_mkdir $DIR/$tdir
5199         touch $DIR/$tdir/foo
5200         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5201         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5202         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5203         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5204         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5205                                         error "link worked"
5206         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5207         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5208         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5209                                                      error "lsattr"
5210         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5211         cp -r $DIR/$tdir $TMP/
5212         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5213 }
5214 run_test 52a "append-only flag test (should return errors)"
5215
5216 test_52b() {
5217         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5218         test_mkdir $DIR/$tdir
5219         touch $DIR/$tdir/foo
5220         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5221         cat test > $DIR/$tdir/foo && error "cat test worked"
5222         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5223         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5224         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5225                                         error "link worked"
5226         echo foo >> $DIR/$tdir/foo && error "echo worked"
5227         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5228         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5229         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5230         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5231                                                         error "lsattr"
5232         chattr -i $DIR/$tdir/foo || error "chattr failed"
5233
5234         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5235 }
5236 run_test 52b "immutable flag test (should return errors) ======="
5237
5238 test_53() {
5239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5240         remote_mds_nodsh && skip "remote MDS with nodsh"
5241         remote_ost_nodsh && skip "remote OST with nodsh"
5242
5243         local param
5244         local param_seq
5245         local ostname
5246         local mds_last
5247         local mds_last_seq
5248         local ost_last
5249         local ost_last_seq
5250         local ost_last_id
5251         local ostnum
5252         local node
5253         local found=false
5254         local support_last_seq=true
5255
5256         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5257                 support_last_seq=false
5258
5259         # only test MDT0000
5260         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5261         local value
5262         for value in $(do_facet $SINGLEMDS \
5263                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5264                 param=$(echo ${value[0]} | cut -d "=" -f1)
5265                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5266
5267                 if $support_last_seq; then
5268                         param_seq=$(echo $param |
5269                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5270                         mds_last_seq=$(do_facet $SINGLEMDS \
5271                                        $LCTL get_param -n $param_seq)
5272                 fi
5273                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5274
5275                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5276                 node=$(facet_active_host ost$((ostnum+1)))
5277                 param="obdfilter.$ostname.last_id"
5278                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5279                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5280                         ost_last_id=$ost_last
5281
5282                         if $support_last_seq; then
5283                                 ost_last_id=$(echo $ost_last |
5284                                               awk -F':' '{print $2}' |
5285                                               sed -e "s/^0x//g")
5286                                 ost_last_seq=$(echo $ost_last |
5287                                                awk -F':' '{print $1}')
5288                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5289                         fi
5290
5291                         if [[ $ost_last_id != $mds_last ]]; then
5292                                 error "$ost_last_id != $mds_last"
5293                         else
5294                                 found=true
5295                                 break
5296                         fi
5297                 done
5298         done
5299         $found || error "can not match last_seq/last_id for $mdtosc"
5300         return 0
5301 }
5302 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5303
5304 test_54a() {
5305         perl -MSocket -e ';' || skip "no Socket perl module installed"
5306
5307         $SOCKETSERVER $DIR/socket ||
5308                 error "$SOCKETSERVER $DIR/socket failed: $?"
5309         $SOCKETCLIENT $DIR/socket ||
5310                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5311         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5312 }
5313 run_test 54a "unix domain socket test =========================="
5314
5315 test_54b() {
5316         f="$DIR/f54b"
5317         mknod $f c 1 3
5318         chmod 0666 $f
5319         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5320 }
5321 run_test 54b "char device works in lustre ======================"
5322
5323 find_loop_dev() {
5324         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5325         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5326         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5327
5328         for i in $(seq 3 7); do
5329                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5330                 LOOPDEV=$LOOPBASE$i
5331                 LOOPNUM=$i
5332                 break
5333         done
5334 }
5335
5336 cleanup_54c() {
5337         local rc=0
5338         loopdev="$DIR/loop54c"
5339
5340         trap 0
5341         $UMOUNT $DIR/$tdir || rc=$?
5342         losetup -d $loopdev || true
5343         losetup -d $LOOPDEV || true
5344         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5345         return $rc
5346 }
5347
5348 test_54c() {
5349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5350
5351         loopdev="$DIR/loop54c"
5352
5353         find_loop_dev
5354         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5355         trap cleanup_54c EXIT
5356         mknod $loopdev b 7 $LOOPNUM
5357         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5358         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5359         losetup $loopdev $DIR/$tfile ||
5360                 error "can't set up $loopdev for $DIR/$tfile"
5361         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5362         test_mkdir $DIR/$tdir
5363         mount -t ext2 $loopdev $DIR/$tdir ||
5364                 error "error mounting $loopdev on $DIR/$tdir"
5365         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5366                 error "dd write"
5367         df $DIR/$tdir
5368         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5369                 error "dd read"
5370         cleanup_54c
5371 }
5372 run_test 54c "block device works in lustre ====================="
5373
5374 test_54d() {
5375         f="$DIR/f54d"
5376         string="aaaaaa"
5377         mknod $f p
5378         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5379 }
5380 run_test 54d "fifo device works in lustre ======================"
5381
5382 test_54e() {
5383         f="$DIR/f54e"
5384         string="aaaaaa"
5385         cp -aL /dev/console $f
5386         echo $string > $f || error "echo $string to $f failed"
5387 }
5388 run_test 54e "console/tty device works in lustre ======================"
5389
5390 test_56a() {
5391         local numfiles=3
5392         local dir=$DIR/$tdir
5393
5394         rm -rf $dir
5395         test_mkdir -p $dir/dir
5396         for i in $(seq $numfiles); do
5397                 touch $dir/file$i
5398                 touch $dir/dir/file$i
5399         done
5400
5401         local numcomp=$($LFS getstripe --component-count $dir)
5402
5403         [[ $numcomp == 0 ]] && numcomp=1
5404
5405         # test lfs getstripe with --recursive
5406         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5407
5408         [[ $filenum -eq $((numfiles * 2)) ]] ||
5409                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5410         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5411         [[ $filenum -eq $numfiles ]] ||
5412                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5413         echo "$LFS getstripe showed obdidx or l_ost_idx"
5414
5415         # test lfs getstripe with file instead of dir
5416         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5417         [[ $filenum -eq 1 ]] ||
5418                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5419         echo "$LFS getstripe file1 passed"
5420
5421         #test lfs getstripe with --verbose
5422         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5423         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5424                 error "$LFS getstripe --verbose $dir: "\
5425                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5426         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5427                 error "$LFS getstripe $dir: showed lmm_magic"
5428
5429         #test lfs getstripe with -v prints lmm_fid
5430         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5431         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5432                 error "$LFS getstripe -v $dir: "\
5433                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5434         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5435                 error "$LFS getstripe $dir: showed lmm_fid by default"
5436         echo "$LFS getstripe --verbose passed"
5437
5438         #check for FID information
5439         local fid1=$($LFS getstripe --fid $dir/file1)
5440         local fid2=$($LFS getstripe --verbose $dir/file1 |
5441                      awk '/lmm_fid: / { print $2; exit; }')
5442         local fid3=$($LFS path2fid $dir/file1)
5443
5444         [ "$fid1" != "$fid2" ] &&
5445                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5446         [ "$fid1" != "$fid3" ] &&
5447                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5448         echo "$LFS getstripe --fid passed"
5449
5450         #test lfs getstripe with --obd
5451         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5452                 error "$LFS getstripe --obd wrong_uuid: should return error"
5453
5454         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5455
5456         local ostidx=1
5457         local obduuid=$(ostuuid_from_index $ostidx)
5458         local found=$($LFS getstripe -r --obd $obduuid $dir |
5459                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5460
5461         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5462         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5463                 ((filenum--))
5464         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5465                 ((filenum--))
5466
5467         [[ $found -eq $filenum ]] ||
5468                 error "$LFS getstripe --obd: found $found expect $filenum"
5469         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5470                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5471                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5472                 error "$LFS getstripe --obd: should not show file on other obd"
5473         echo "$LFS getstripe --obd passed"
5474 }
5475 run_test 56a "check $LFS getstripe"
5476
5477 test_56b() {
5478         local dir=$DIR/$tdir
5479         local numdirs=3
5480
5481         test_mkdir $dir
5482         for i in $(seq $numdirs); do
5483                 test_mkdir $dir/dir$i
5484         done
5485
5486         # test lfs getdirstripe default mode is non-recursion, which is
5487         # different from lfs getstripe
5488         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5489
5490         [[ $dircnt -eq 1 ]] ||
5491                 error "$LFS getdirstripe: found $dircnt, not 1"
5492         dircnt=$($LFS getdirstripe --recursive $dir |
5493                 grep -c lmv_stripe_count)
5494         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5495                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5496 }
5497 run_test 56b "check $LFS getdirstripe"
5498
5499 test_56c() {
5500         remote_ost_nodsh && skip "remote OST with nodsh"
5501
5502         local ost_idx=0
5503         local ost_name=$(ostname_from_index $ost_idx)
5504         local old_status=$(ost_dev_status $ost_idx)
5505
5506         [[ -z "$old_status" ]] ||
5507                 skip_env "OST $ost_name is in $old_status status"
5508
5509         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5510         [[ $OST1_VERSION -ge $(version_code 2.12.55) ]] && do_facet ost1 \
5511                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5512         sleep_maxage
5513
5514         local new_status=$(ost_dev_status $ost_idx)
5515
5516         [[ "$new_status" =~ "D" ]] ||
5517                 error "$ost_name status is '$new_status', missing 'D'"
5518         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5519                 [[ "$new_status" =~ "N" ]] ||
5520                         error "$ost_name status is '$new_status', missing 'N'"
5521         fi
5522
5523         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5524         [[ $OST1_VERSION -ge $(version_code 2.12.55) ]] && do_facet ost1 \
5525                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5526         sleep_maxage
5527
5528         new_status=$(ost_dev_status $ost_idx)
5529         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5530                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5531 }
5532 run_test 56c "check 'lfs df' showing device status"
5533
5534 NUMFILES=3
5535 NUMDIRS=3
5536 setup_56() {
5537         local local_tdir="$1"
5538         local local_numfiles="$2"
5539         local local_numdirs="$3"
5540         local dir_params="$4"
5541         local dir_stripe_params="$5"
5542
5543         if [ ! -d "$local_tdir" ] ; then
5544                 test_mkdir -p $dir_stripe_params $local_tdir
5545                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5546                 for i in $(seq $local_numfiles) ; do
5547                         touch $local_tdir/file$i
5548                 done
5549                 for i in $(seq $local_numdirs) ; do
5550                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5551                         for j in $(seq $local_numfiles) ; do
5552                                 touch $local_tdir/dir$i/file$j
5553                         done
5554                 done
5555         fi
5556 }
5557
5558 setup_56_special() {
5559         local local_tdir=$1
5560         local local_numfiles=$2
5561         local local_numdirs=$3
5562
5563         setup_56 $local_tdir $local_numfiles $local_numdirs
5564
5565         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5566                 for i in $(seq $local_numfiles) ; do
5567                         mknod $local_tdir/loop${i}b b 7 $i
5568                         mknod $local_tdir/null${i}c c 1 3
5569                         ln -s $local_tdir/file1 $local_tdir/link${i}
5570                 done
5571                 for i in $(seq $local_numdirs) ; do
5572                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5573                         mknod $local_tdir/dir$i/null${i}c c 1 3
5574                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5575                 done
5576         fi
5577 }
5578
5579 test_56g() {
5580         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5581         local expected=$(($NUMDIRS + 2))
5582
5583         setup_56 $dir $NUMFILES $NUMDIRS
5584
5585         # test lfs find with -name
5586         for i in $(seq $NUMFILES) ; do
5587                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5588
5589                 [ $nums -eq $expected ] ||
5590                         error "lfs find -name '*$i' $dir wrong: "\
5591                               "found $nums, expected $expected"
5592         done
5593 }
5594 run_test 56g "check lfs find -name"
5595
5596 test_56h() {
5597         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5598         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5599
5600         setup_56 $dir $NUMFILES $NUMDIRS
5601
5602         # test lfs find with ! -name
5603         for i in $(seq $NUMFILES) ; do
5604                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5605
5606                 [ $nums -eq $expected ] ||
5607                         error "lfs find ! -name '*$i' $dir wrong: "\
5608                               "found $nums, expected $expected"
5609         done
5610 }
5611 run_test 56h "check lfs find ! -name"
5612
5613 test_56i() {
5614         local dir=$DIR/$tdir
5615
5616         test_mkdir $dir
5617
5618         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5619         local out=$($cmd)
5620
5621         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5622 }
5623 run_test 56i "check 'lfs find -ost UUID' skips directories"
5624
5625 test_56j() {
5626         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5627
5628         setup_56_special $dir $NUMFILES $NUMDIRS
5629
5630         local expected=$((NUMDIRS + 1))
5631         local cmd="$LFS find -type d $dir"
5632         local nums=$($cmd | wc -l)
5633
5634         [ $nums -eq $expected ] ||
5635                 error "'$cmd' wrong: found $nums, expected $expected"
5636 }
5637 run_test 56j "check lfs find -type d"
5638
5639 test_56k() {
5640         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5641
5642         setup_56_special $dir $NUMFILES $NUMDIRS
5643
5644         local expected=$(((NUMDIRS + 1) * NUMFILES))
5645         local cmd="$LFS find -type f $dir"
5646         local nums=$($cmd | wc -l)
5647
5648         [ $nums -eq $expected ] ||
5649                 error "'$cmd' wrong: found $nums, expected $expected"
5650 }
5651 run_test 56k "check lfs find -type f"
5652
5653 test_56l() {
5654         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5655
5656         setup_56_special $dir $NUMFILES $NUMDIRS
5657
5658         local expected=$((NUMDIRS + NUMFILES))
5659         local cmd="$LFS find -type b $dir"
5660         local nums=$($cmd | wc -l)
5661
5662         [ $nums -eq $expected ] ||
5663                 error "'$cmd' wrong: found $nums, expected $expected"
5664 }
5665 run_test 56l "check lfs find -type b"
5666
5667 test_56m() {
5668         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5669
5670         setup_56_special $dir $NUMFILES $NUMDIRS
5671
5672         local expected=$((NUMDIRS + NUMFILES))
5673         local cmd="$LFS find -type c $dir"
5674         local nums=$($cmd | wc -l)
5675         [ $nums -eq $expected ] ||
5676                 error "'$cmd' wrong: found $nums, expected $expected"
5677 }
5678 run_test 56m "check lfs find -type c"
5679
5680 test_56n() {
5681         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5682         setup_56_special $dir $NUMFILES $NUMDIRS
5683
5684         local expected=$((NUMDIRS + NUMFILES))
5685         local cmd="$LFS find -type l $dir"
5686         local nums=$($cmd | wc -l)
5687
5688         [ $nums -eq $expected ] ||
5689                 error "'$cmd' wrong: found $nums, expected $expected"
5690 }
5691 run_test 56n "check lfs find -type l"
5692
5693 test_56o() {
5694         local dir=$DIR/$tdir
5695
5696         setup_56 $dir $NUMFILES $NUMDIRS
5697         utime $dir/file1 > /dev/null || error "utime (1)"
5698         utime $dir/file2 > /dev/null || error "utime (2)"
5699         utime $dir/dir1 > /dev/null || error "utime (3)"
5700         utime $dir/dir2 > /dev/null || error "utime (4)"
5701         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5702         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5703
5704         local expected=4
5705         local nums=$($LFS find -mtime +0 $dir | wc -l)
5706
5707         [ $nums -eq $expected ] ||
5708                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5709
5710         expected=12
5711         cmd="$LFS find -mtime 0 $dir"
5712         nums=$($cmd | wc -l)
5713         [ $nums -eq $expected ] ||
5714                 error "'$cmd' wrong: found $nums, expected $expected"
5715 }
5716 run_test 56o "check lfs find -mtime for old files"
5717
5718 test_56ob() {
5719         local dir=$DIR/$tdir
5720         local expected=1
5721         local count=0
5722
5723         # just to make sure there is something that won't be found
5724         test_mkdir $dir
5725         touch $dir/$tfile.now
5726
5727         for age in year week day hour min; do
5728                 count=$((count + 1))
5729
5730                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5731                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5732                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5733
5734                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5735                 local nums=$($cmd | wc -l)
5736                 [ $nums -eq $expected ] ||
5737                         error "'$cmd' wrong: found $nums, expected $expected"
5738
5739                 cmd="$LFS find $dir -atime $count${age:0:1}"
5740                 nums=$($cmd | wc -l)
5741                 [ $nums -eq $expected ] ||
5742                         error "'$cmd' wrong: found $nums, expected $expected"
5743         done
5744
5745         sleep 2
5746         cmd="$LFS find $dir -ctime +1s -type f"
5747         nums=$($cmd | wc -l)
5748         (( $nums == $count * 2 + 1)) ||
5749                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5750 }
5751 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5752
5753 test_newerXY_base() {
5754         local x=$1
5755         local y=$2
5756         local dir=$DIR/$tdir
5757         local ref
5758         local negref
5759
5760         if [ $y == "t" ]; then
5761                 ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5762         else
5763                 ref=$DIR/$tfile.newer
5764                 touch $ref || error "touch $ref failed"
5765         fi
5766         sleep 2
5767         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5768         sleep 2
5769         if [ $y == "t" ]; then
5770                 negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5771         else
5772                 negref=$DIR/$tfile.newerneg
5773                 touch $negref || error "touch $negref failed"
5774         fi
5775
5776         local cmd="$LFS find $dir -newer$x$y $ref"
5777         local nums=$(eval $cmd | wc -l)
5778         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5779
5780         [ $nums -eq $expected ] ||
5781                 error "'$cmd' wrong: found $nums, expected $expected"
5782
5783         cmd="$LFS find $dir ! -newer$x$y $negref"
5784         nums=$(eval $cmd | wc -l)
5785         [ $nums -eq $expected ] ||
5786                 error "'$cmd' wrong: found $nums, expected $expected"
5787
5788         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
5789         nums=$(eval $cmd | wc -l)
5790         [ $nums -eq $expected ] ||
5791                 error "'$cmd' wrong: found $nums, expected $expected"
5792
5793         rm -rf $DIR/*
5794 }
5795
5796 test_56oc() {
5797         test_newerXY_base "a" "a"
5798         test_newerXY_base "a" "m"
5799         test_newerXY_base "a" "c"
5800         test_newerXY_base "m" "a"
5801         test_newerXY_base "m" "m"
5802         test_newerXY_base "m" "c"
5803         test_newerXY_base "c" "a"
5804         test_newerXY_base "c" "m"
5805         test_newerXY_base "c" "c"
5806         test_newerXY_base "a" "t"
5807         test_newerXY_base "m" "t"
5808         test_newerXY_base "c" "t"
5809 }
5810 run_test 56oc "check lfs find -newerXY work"
5811
5812 test_56p() {
5813         [ $RUNAS_ID -eq $UID ] &&
5814                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5815
5816         local dir=$DIR/$tdir
5817
5818         setup_56 $dir $NUMFILES $NUMDIRS
5819         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5820
5821         local expected=$NUMFILES
5822         local cmd="$LFS find -uid $RUNAS_ID $dir"
5823         local nums=$($cmd | wc -l)
5824
5825         [ $nums -eq $expected ] ||
5826                 error "'$cmd' wrong: found $nums, expected $expected"
5827
5828         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5829         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5830         nums=$($cmd | wc -l)
5831         [ $nums -eq $expected ] ||
5832                 error "'$cmd' wrong: found $nums, expected $expected"
5833 }
5834 run_test 56p "check lfs find -uid and ! -uid"
5835
5836 test_56q() {
5837         [ $RUNAS_ID -eq $UID ] &&
5838                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5839
5840         local dir=$DIR/$tdir
5841
5842         setup_56 $dir $NUMFILES $NUMDIRS
5843         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5844
5845         local expected=$NUMFILES
5846         local cmd="$LFS find -gid $RUNAS_GID $dir"
5847         local nums=$($cmd | wc -l)
5848
5849         [ $nums -eq $expected ] ||
5850                 error "'$cmd' wrong: found $nums, expected $expected"
5851
5852         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5853         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5854         nums=$($cmd | wc -l)
5855         [ $nums -eq $expected ] ||
5856                 error "'$cmd' wrong: found $nums, expected $expected"
5857 }
5858 run_test 56q "check lfs find -gid and ! -gid"
5859
5860 test_56r() {
5861         local dir=$DIR/$tdir
5862
5863         setup_56 $dir $NUMFILES $NUMDIRS
5864
5865         local expected=12
5866         local cmd="$LFS find -size 0 -type f -lazy $dir"
5867         local nums=$($cmd | wc -l)
5868
5869         [ $nums -eq $expected ] ||
5870                 error "'$cmd' wrong: found $nums, expected $expected"
5871         cmd="$LFS find -size 0 -type f $dir"
5872         nums=$($cmd | wc -l)
5873         [ $nums -eq $expected ] ||
5874                 error "'$cmd' wrong: found $nums, expected $expected"
5875
5876         expected=0
5877         cmd="$LFS find ! -size 0 -type f -lazy $dir"
5878         nums=$($cmd | wc -l)
5879         [ $nums -eq $expected ] ||
5880                 error "'$cmd' wrong: found $nums, expected $expected"
5881         cmd="$LFS find ! -size 0 -type f $dir"
5882         nums=$($cmd | wc -l)
5883         [ $nums -eq $expected ] ||
5884                 error "'$cmd' wrong: found $nums, expected $expected"
5885
5886         echo "test" > $dir/$tfile
5887         echo "test2" > $dir/$tfile.2 && sync
5888         expected=1
5889         cmd="$LFS find -size 5 -type f -lazy $dir"
5890         nums=$($cmd | wc -l)
5891         [ $nums -eq $expected ] ||
5892                 error "'$cmd' wrong: found $nums, expected $expected"
5893         cmd="$LFS find -size 5 -type f $dir"
5894         nums=$($cmd | wc -l)
5895         [ $nums -eq $expected ] ||
5896                 error "'$cmd' wrong: found $nums, expected $expected"
5897
5898         expected=1
5899         cmd="$LFS find -size +5 -type f -lazy $dir"
5900         nums=$($cmd | wc -l)
5901         [ $nums -eq $expected ] ||
5902                 error "'$cmd' wrong: found $nums, expected $expected"
5903         cmd="$LFS find -size +5 -type f $dir"
5904         nums=$($cmd | wc -l)
5905         [ $nums -eq $expected ] ||
5906                 error "'$cmd' wrong: found $nums, expected $expected"
5907
5908         expected=2
5909         cmd="$LFS find -size +0 -type f -lazy $dir"
5910         nums=$($cmd | wc -l)
5911         [ $nums -eq $expected ] ||
5912                 error "'$cmd' wrong: found $nums, expected $expected"
5913         cmd="$LFS find -size +0 -type f $dir"
5914         nums=$($cmd | wc -l)
5915         [ $nums -eq $expected ] ||
5916                 error "'$cmd' wrong: found $nums, expected $expected"
5917
5918         expected=2
5919         cmd="$LFS find ! -size -5 -type f -lazy $dir"
5920         nums=$($cmd | wc -l)
5921         [ $nums -eq $expected ] ||
5922                 error "'$cmd' wrong: found $nums, expected $expected"
5923         cmd="$LFS find ! -size -5 -type f $dir"
5924         nums=$($cmd | wc -l)
5925         [ $nums -eq $expected ] ||
5926                 error "'$cmd' wrong: found $nums, expected $expected"
5927
5928         expected=12
5929         cmd="$LFS find -size -5 -type f -lazy $dir"
5930         nums=$($cmd | wc -l)
5931         [ $nums -eq $expected ] ||
5932                 error "'$cmd' wrong: found $nums, expected $expected"
5933         cmd="$LFS find -size -5 -type f $dir"
5934         nums=$($cmd | wc -l)
5935         [ $nums -eq $expected ] ||
5936                 error "'$cmd' wrong: found $nums, expected $expected"
5937 }
5938 run_test 56r "check lfs find -size works"
5939
5940 test_56ra() {
5941         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
5942                 skip "MDS < 2.12.58 doesn't return LSOM data"
5943         local dir=$DIR/$tdir
5944
5945         [[ $OSC == "mdc" ]] && skip "DoM files" && return
5946
5947         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5948
5949         cancel_lru_locks $OSC
5950
5951         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5952         local expected=12
5953         local cmd="$LFS find -size 0 -type f -lazy $dir"
5954         local nums=$($cmd | wc -l)
5955
5956         [ $nums -eq $expected ] ||
5957                 error "'$cmd' wrong: found $nums, expected $expected"
5958
5959         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5960         [ $rpcs_before -eq $rpcs_after ] ||
5961                 error "'$cmd' should not send glimpse RPCs to OST"
5962         cmd="$LFS find -size 0 -type f $dir"
5963         nums=$($cmd | wc -l)
5964         [ $nums -eq $expected ] ||
5965                 error "'$cmd' wrong: found $nums, expected $expected"
5966         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5967         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5968         $LCTL get_param osc.*.stats
5969         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
5970                 error "'$cmd' should send 12 glimpse RPCs to OST"
5971
5972         cancel_lru_locks $OSC
5973         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5974         expected=0
5975         cmd="$LFS find ! -size 0 -type f -lazy $dir"
5976         nums=$($cmd | wc -l)
5977         [ $nums -eq $expected ] ||
5978                 error "'$cmd' wrong: found $nums, expected $expected"
5979         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5980         $LCTL get_param mdc.*.stats
5981         [ $rpcs_before -eq $rpcs_after ] ||
5982                 error "'$cmd' should not send glimpse RPCs to OST"
5983         cmd="$LFS find ! -size 0 -type f $dir"
5984         nums=$($cmd | wc -l)
5985         [ $nums -eq $expected ] ||
5986                 error "'$cmd' wrong: found $nums, expected $expected"
5987         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5988         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5989         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
5990                 error "'$cmd' should send 12 glimpse RPCs to OST"
5991
5992         echo "test" > $dir/$tfile
5993         echo "test2" > $dir/$tfile.2 && sync
5994         cancel_lru_locks $OSC
5995         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5996         expected=1
5997         cmd="$LFS find -size 5 -type f -lazy $dir"
5998         nums=$($cmd | wc -l)
5999         [ $nums -eq $expected ] ||
6000                 error "'$cmd' wrong: found $nums, expected $expected"
6001         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6002         [ $rpcs_before -eq $rpcs_after ] ||
6003                 error "'$cmd' should not send glimpse RPCs to OST"
6004         cmd="$LFS find -size 5 -type f $dir"
6005         nums=$($cmd | wc -l)
6006         [ $nums -eq $expected ] ||
6007                 error "'$cmd' wrong: found $nums, expected $expected"
6008         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6009         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6010         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6011                 error "'$cmd' should send 14 glimpse RPCs to OST"
6012
6013         cancel_lru_locks $OSC
6014         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6015         expected=1
6016         cmd="$LFS find -size +5 -type f -lazy $dir"
6017         nums=$($cmd | wc -l)
6018         [ $nums -eq $expected ] ||
6019                 error "'$cmd' wrong: found $nums, expected $expected"
6020         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6021         [ $rpcs_before -eq $rpcs_after ] ||
6022                 error "'$cmd' should not send glimpse RPCs to OST"
6023         cmd="$LFS find -size +5 -type f $dir"
6024         nums=$($cmd | wc -l)
6025         [ $nums -eq $expected ] ||
6026                 error "'$cmd' wrong: found $nums, expected $expected"
6027         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6028         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6029         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6030                 error "'$cmd' should send 14 glimpse RPCs to OST"
6031
6032         cancel_lru_locks $OSC
6033         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6034         expected=2
6035         cmd="$LFS find -size +0 -type f -lazy $dir"
6036         nums=$($cmd | wc -l)
6037         [ $nums -eq $expected ] ||
6038                 error "'$cmd' wrong: found $nums, expected $expected"
6039         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6040         [ $rpcs_before -eq $rpcs_after ] ||
6041                 error "'$cmd' should not send glimpse RPCs to OST"
6042         cmd="$LFS find -size +0 -type f $dir"
6043         nums=$($cmd | wc -l)
6044         [ $nums -eq $expected ] ||
6045                 error "'$cmd' wrong: found $nums, expected $expected"
6046         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6047         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6048         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6049                 error "'$cmd' should send 14 glimpse RPCs to OST"
6050
6051         cancel_lru_locks $OSC
6052         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6053         expected=2
6054         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6055         nums=$($cmd | wc -l)
6056         [ $nums -eq $expected ] ||
6057                 error "'$cmd' wrong: found $nums, expected $expected"
6058         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6059         [ $rpcs_before -eq $rpcs_after ] ||
6060                 error "'$cmd' should not send glimpse RPCs to OST"
6061         cmd="$LFS find ! -size -5 -type f $dir"
6062         nums=$($cmd | wc -l)
6063         [ $nums -eq $expected ] ||
6064                 error "'$cmd' wrong: found $nums, expected $expected"
6065         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6066         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6067         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6068                 error "'$cmd' should send 14 glimpse RPCs to OST"
6069
6070         cancel_lru_locks $OSC
6071         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6072         expected=12
6073         cmd="$LFS find -size -5 -type f -lazy $dir"
6074         nums=$($cmd | wc -l)
6075         [ $nums -eq $expected ] ||
6076                 error "'$cmd' wrong: found $nums, expected $expected"
6077         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6078         [ $rpcs_before -eq $rpcs_after ] ||
6079                 error "'$cmd' should not send glimpse RPCs to OST"
6080         cmd="$LFS find -size -5 -type f $dir"
6081         nums=$($cmd | wc -l)
6082         [ $nums -eq $expected ] ||
6083                 error "'$cmd' wrong: found $nums, expected $expected"
6084         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6085         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6086         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6087                 error "'$cmd' should send 14 glimpse RPCs to OST"
6088 }
6089 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6090
6091 test_56s() { # LU-611 #LU-9369
6092         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6093
6094         local dir=$DIR/$tdir
6095         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6096
6097         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6098         for i in $(seq $NUMDIRS); do
6099                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6100         done
6101
6102         local expected=$NUMDIRS
6103         local cmd="$LFS find -c $OSTCOUNT $dir"
6104         local nums=$($cmd | wc -l)
6105
6106         [ $nums -eq $expected ] || {
6107                 $LFS getstripe -R $dir
6108                 error "'$cmd' wrong: found $nums, expected $expected"
6109         }
6110
6111         expected=$((NUMDIRS + onestripe))
6112         cmd="$LFS find -stripe-count +0 -type f $dir"
6113         nums=$($cmd | wc -l)
6114         [ $nums -eq $expected ] || {
6115                 $LFS getstripe -R $dir
6116                 error "'$cmd' wrong: found $nums, expected $expected"
6117         }
6118
6119         expected=$onestripe
6120         cmd="$LFS find -stripe-count 1 -type f $dir"
6121         nums=$($cmd | wc -l)
6122         [ $nums -eq $expected ] || {
6123                 $LFS getstripe -R $dir
6124                 error "'$cmd' wrong: found $nums, expected $expected"
6125         }
6126
6127         cmd="$LFS find -stripe-count -2 -type f $dir"
6128         nums=$($cmd | wc -l)
6129         [ $nums -eq $expected ] || {
6130                 $LFS getstripe -R $dir
6131                 error "'$cmd' wrong: found $nums, expected $expected"
6132         }
6133
6134         expected=0
6135         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6136         nums=$($cmd | wc -l)
6137         [ $nums -eq $expected ] || {
6138                 $LFS getstripe -R $dir
6139                 error "'$cmd' wrong: found $nums, expected $expected"
6140         }
6141 }
6142 run_test 56s "check lfs find -stripe-count works"
6143
6144 test_56t() { # LU-611 #LU-9369
6145         local dir=$DIR/$tdir
6146
6147         setup_56 $dir 0 $NUMDIRS
6148         for i in $(seq $NUMDIRS); do
6149                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6150         done
6151
6152         local expected=$NUMDIRS
6153         local cmd="$LFS find -S 8M $dir"
6154         local nums=$($cmd | wc -l)
6155
6156         [ $nums -eq $expected ] || {
6157                 $LFS getstripe -R $dir
6158                 error "'$cmd' wrong: found $nums, expected $expected"
6159         }
6160         rm -rf $dir
6161
6162         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6163
6164         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6165
6166         expected=$(((NUMDIRS + 1) * NUMFILES))
6167         cmd="$LFS find -stripe-size 512k -type f $dir"
6168         nums=$($cmd | wc -l)
6169         [ $nums -eq $expected ] ||
6170                 error "'$cmd' wrong: found $nums, expected $expected"
6171
6172         cmd="$LFS find -stripe-size +320k -type f $dir"
6173         nums=$($cmd | wc -l)
6174         [ $nums -eq $expected ] ||
6175                 error "'$cmd' wrong: found $nums, expected $expected"
6176
6177         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6178         cmd="$LFS find -stripe-size +200k -type f $dir"
6179         nums=$($cmd | wc -l)
6180         [ $nums -eq $expected ] ||
6181                 error "'$cmd' wrong: found $nums, expected $expected"
6182
6183         cmd="$LFS find -stripe-size -640k -type f $dir"
6184         nums=$($cmd | wc -l)
6185         [ $nums -eq $expected ] ||
6186                 error "'$cmd' wrong: found $nums, expected $expected"
6187
6188         expected=4
6189         cmd="$LFS find -stripe-size 256k -type f $dir"
6190         nums=$($cmd | wc -l)
6191         [ $nums -eq $expected ] ||
6192                 error "'$cmd' wrong: found $nums, expected $expected"
6193
6194         cmd="$LFS find -stripe-size -320k -type f $dir"
6195         nums=$($cmd | wc -l)
6196         [ $nums -eq $expected ] ||
6197                 error "'$cmd' wrong: found $nums, expected $expected"
6198
6199         expected=0
6200         cmd="$LFS find -stripe-size 1024k -type f $dir"
6201         nums=$($cmd | wc -l)
6202         [ $nums -eq $expected ] ||
6203                 error "'$cmd' wrong: found $nums, expected $expected"
6204 }
6205 run_test 56t "check lfs find -stripe-size works"
6206
6207 test_56u() { # LU-611
6208         local dir=$DIR/$tdir
6209
6210         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6211
6212         if [[ $OSTCOUNT -gt 1 ]]; then
6213                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6214                 onestripe=4
6215         else
6216                 onestripe=0
6217         fi
6218
6219         local expected=$(((NUMDIRS + 1) * NUMFILES))
6220         local cmd="$LFS find -stripe-index 0 -type f $dir"
6221         local nums=$($cmd | wc -l)
6222
6223         [ $nums -eq $expected ] ||
6224                 error "'$cmd' wrong: found $nums, expected $expected"
6225
6226         expected=$onestripe
6227         cmd="$LFS find -stripe-index 1 -type f $dir"
6228         nums=$($cmd | wc -l)
6229         [ $nums -eq $expected ] ||
6230                 error "'$cmd' wrong: found $nums, expected $expected"
6231
6232         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6233         nums=$($cmd | wc -l)
6234         [ $nums -eq $expected ] ||
6235                 error "'$cmd' wrong: found $nums, expected $expected"
6236
6237         expected=0
6238         # This should produce an error and not return any files
6239         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6240         nums=$($cmd 2>/dev/null | wc -l)
6241         [ $nums -eq $expected ] ||
6242                 error "'$cmd' wrong: found $nums, expected $expected"
6243
6244         if [[ $OSTCOUNT -gt 1 ]]; then
6245                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6246                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6247                 nums=$($cmd | wc -l)
6248                 [ $nums -eq $expected ] ||
6249                         error "'$cmd' wrong: found $nums, expected $expected"
6250         fi
6251 }
6252 run_test 56u "check lfs find -stripe-index works"
6253
6254 test_56v() {
6255         local mdt_idx=0
6256         local dir=$DIR/$tdir
6257
6258         setup_56 $dir $NUMFILES $NUMDIRS
6259
6260         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6261         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6262
6263         for file in $($LFS find -m $UUID $dir); do
6264                 file_midx=$($LFS getstripe -m $file)
6265                 [ $file_midx -eq $mdt_idx ] ||
6266                         error "lfs find -m $UUID != getstripe -m $file_midx"
6267         done
6268 }
6269 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6270
6271 test_56w() {
6272         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6274
6275         local dir=$DIR/$tdir
6276
6277         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6278
6279         local stripe_size=$($LFS getstripe -S -d $dir) ||
6280                 error "$LFS getstripe -S -d $dir failed"
6281         stripe_size=${stripe_size%% *}
6282
6283         local file_size=$((stripe_size * OSTCOUNT))
6284         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6285         local required_space=$((file_num * file_size))
6286         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6287                            head -n1)
6288         [[ $free_space -le $((required_space / 1024)) ]] &&
6289                 skip_env "need $required_space, have $free_space kbytes"
6290
6291         local dd_bs=65536
6292         local dd_count=$((file_size / dd_bs))
6293
6294         # write data into the files
6295         local i
6296         local j
6297         local file
6298
6299         for i in $(seq $NUMFILES); do
6300                 file=$dir/file$i
6301                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6302                         error "write data into $file failed"
6303         done
6304         for i in $(seq $NUMDIRS); do
6305                 for j in $(seq $NUMFILES); do
6306                         file=$dir/dir$i/file$j
6307                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6308                                 error "write data into $file failed"
6309                 done
6310         done
6311
6312         # $LFS_MIGRATE will fail if hard link migration is unsupported
6313         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6314                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6315                         error "creating links to $dir/dir1/file1 failed"
6316         fi
6317
6318         local expected=-1
6319
6320         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6321
6322         # lfs_migrate file
6323         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6324
6325         echo "$cmd"
6326         eval $cmd || error "$cmd failed"
6327
6328         check_stripe_count $dir/file1 $expected
6329
6330         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6331         then
6332                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6333                 # OST 1 if it is on OST 0. This file is small enough to
6334                 # be on only one stripe.
6335                 file=$dir/migr_1_ost
6336                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6337                         error "write data into $file failed"
6338                 local obdidx=$($LFS getstripe -i $file)
6339                 local oldmd5=$(md5sum $file)
6340                 local newobdidx=0
6341
6342                 [[ $obdidx -eq 0 ]] && newobdidx=1
6343                 cmd="$LFS migrate -i $newobdidx $file"
6344                 echo $cmd
6345                 eval $cmd || error "$cmd failed"
6346
6347                 local realobdix=$($LFS getstripe -i $file)
6348                 local newmd5=$(md5sum $file)
6349
6350                 [[ $newobdidx -ne $realobdix ]] &&
6351                         error "new OST is different (was=$obdidx, "\
6352                               "wanted=$newobdidx, got=$realobdix)"
6353                 [[ "$oldmd5" != "$newmd5" ]] &&
6354                         error "md5sum differ: $oldmd5, $newmd5"
6355         fi
6356
6357         # lfs_migrate dir
6358         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6359         echo "$cmd"
6360         eval $cmd || error "$cmd failed"
6361
6362         for j in $(seq $NUMFILES); do
6363                 check_stripe_count $dir/dir1/file$j $expected
6364         done
6365
6366         # lfs_migrate works with lfs find
6367         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6368              $LFS_MIGRATE -y -c $expected"
6369         echo "$cmd"
6370         eval $cmd || error "$cmd failed"
6371
6372         for i in $(seq 2 $NUMFILES); do
6373                 check_stripe_count $dir/file$i $expected
6374         done
6375         for i in $(seq 2 $NUMDIRS); do
6376                 for j in $(seq $NUMFILES); do
6377                 check_stripe_count $dir/dir$i/file$j $expected
6378                 done
6379         done
6380 }
6381 run_test 56w "check lfs_migrate -c stripe_count works"
6382
6383 test_56wb() {
6384         local file1=$DIR/$tdir/file1
6385         local create_pool=false
6386         local initial_pool=$($LFS getstripe -p $DIR)
6387         local pool_list=()
6388         local pool=""
6389
6390         echo -n "Creating test dir..."
6391         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6392         echo "done."
6393
6394         echo -n "Creating test file..."
6395         touch $file1 || error "cannot create file"
6396         echo "done."
6397
6398         echo -n "Detecting existing pools..."
6399         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6400
6401         if [ ${#pool_list[@]} -gt 0 ]; then
6402                 echo "${pool_list[@]}"
6403                 for thispool in "${pool_list[@]}"; do
6404                         if [[ -z "$initial_pool" ||
6405                               "$initial_pool" != "$thispool" ]]; then
6406                                 pool="$thispool"
6407                                 echo "Using existing pool '$pool'"
6408                                 break
6409                         fi
6410                 done
6411         else
6412                 echo "none detected."
6413         fi
6414         if [ -z "$pool" ]; then
6415                 pool=${POOL:-testpool}
6416                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6417                 echo -n "Creating pool '$pool'..."
6418                 create_pool=true
6419                 pool_add $pool &> /dev/null ||
6420                         error "pool_add failed"
6421                 echo "done."
6422
6423                 echo -n "Adding target to pool..."
6424                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6425                         error "pool_add_targets failed"
6426                 echo "done."
6427         fi
6428
6429         echo -n "Setting pool using -p option..."
6430         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6431                 error "migrate failed rc = $?"
6432         echo "done."
6433
6434         echo -n "Verifying test file is in pool after migrating..."
6435         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6436                 error "file was not migrated to pool $pool"
6437         echo "done."
6438
6439         echo -n "Removing test file from pool '$pool'..."
6440         $LFS migrate $file1 &> /dev/null ||
6441                 error "cannot remove from pool"
6442         [ "$($LFS getstripe -p $file1)" ] &&
6443                 error "pool still set"
6444         echo "done."
6445
6446         echo -n "Setting pool using --pool option..."
6447         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6448                 error "migrate failed rc = $?"
6449         echo "done."
6450
6451         # Clean up
6452         rm -f $file1
6453         if $create_pool; then
6454                 destroy_test_pools 2> /dev/null ||
6455                         error "destroy test pools failed"
6456         fi
6457 }
6458 run_test 56wb "check lfs_migrate pool support"
6459
6460 test_56wc() {
6461         local file1="$DIR/$tdir/file1"
6462
6463         echo -n "Creating test dir..."
6464         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6465         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6466         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6467                 error "cannot set stripe"
6468         echo "done"
6469
6470         echo -n "Setting initial stripe for test file..."
6471         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6472                 error "cannot set stripe"
6473         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6474                 error "stripe size not set"
6475         echo "done."
6476
6477         # File currently set to -S 512K -c 1
6478
6479         # Ensure -c and -S options are rejected when -R is set
6480         echo -n "Verifying incompatible options are detected..."
6481         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6482                 error "incompatible -c and -R options not detected"
6483         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6484                 error "incompatible -S and -R options not detected"
6485         echo "done."
6486
6487         # Ensure unrecognized options are passed through to 'lfs migrate'
6488         echo -n "Verifying -S option is passed through to lfs migrate..."
6489         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6490                 error "migration failed"
6491         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
6492                 error "file was not restriped"
6493         echo "done."
6494
6495         # File currently set to -S 1M -c 1
6496
6497         # Ensure long options are supported
6498         echo -n "Verifying long options supported..."
6499         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6500                 error "long option without argument not supported"
6501         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6502                 error "long option with argument not supported"
6503         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6504                 error "file not restriped with --stripe-size option"
6505         echo "done."
6506
6507         # File currently set to -S 512K -c 1
6508
6509         if [ "$OSTCOUNT" -gt 1 ]; then
6510                 echo -n "Verifying explicit stripe count can be set..."
6511                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6512                         error "migrate failed"
6513                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
6514                         error "file not restriped to explicit count"
6515                 echo "done."
6516         fi
6517
6518         # File currently set to -S 512K -c 1 or -S 512K -c 2
6519
6520         # Ensure parent striping is used if -R is set, and no stripe
6521         # count or size is specified
6522         echo -n "Setting stripe for parent directory..."
6523         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6524                 error "cannot set stripe"
6525         echo "done."
6526
6527         echo -n "Verifying restripe option uses parent stripe settings..."
6528         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6529                 error "migrate failed"
6530         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
6531                 error "file not restriped to parent settings"
6532         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
6533                 error "file not restriped to parent settings"
6534         echo "done."
6535
6536         # File currently set to -S 1M -c 1
6537
6538         # Ensure striping is preserved if -R is not set, and no stripe
6539         # count or size is specified
6540         echo -n "Verifying striping size preserved when not specified..."
6541         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
6542         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6543                 error "cannot set stripe on parent directory"
6544         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6545                 error "migrate failed"
6546         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
6547                 error "file was restriped"
6548         echo "done."
6549
6550         # Ensure file name properly detected when final option has no argument
6551         echo -n "Verifying file name properly detected..."
6552         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6553                 error "file name interpreted as option argument"
6554         echo "done."
6555
6556         # Clean up
6557         rm -f "$file1"
6558 }
6559 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6560
6561 test_56wd() {
6562         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6563
6564         local file1=$DIR/$tdir/file1
6565
6566         echo -n "Creating test dir..."
6567         test_mkdir $DIR/$tdir || error "cannot create dir"
6568         echo "done."
6569
6570         echo -n "Creating test file..."
6571         touch $file1
6572         echo "done."
6573
6574         # Ensure 'lfs migrate' will fail by using a non-existent option,
6575         # and make sure rsync is not called to recover
6576         echo -n "Make sure --no-rsync option works..."
6577         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6578                 grep -q 'refusing to fall back to rsync' ||
6579                 error "rsync was called with --no-rsync set"
6580         echo "done."
6581
6582         # Ensure rsync is called without trying 'lfs migrate' first
6583         echo -n "Make sure --rsync option works..."
6584         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6585                 grep -q 'falling back to rsync' &&
6586                 error "lfs migrate was called with --rsync set"
6587         echo "done."
6588
6589         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6590         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6591                 grep -q 'at the same time' ||
6592                 error "--rsync and --no-rsync accepted concurrently"
6593         echo "done."
6594
6595         # Clean up
6596         rm -f $file1
6597 }
6598 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6599
6600 test_56x() {
6601         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6602         check_swap_layouts_support
6603
6604         local dir=$DIR/$tdir
6605         local ref1=/etc/passwd
6606         local file1=$dir/file1
6607
6608         test_mkdir $dir || error "creating dir $dir"
6609         $LFS setstripe -c 2 $file1
6610         cp $ref1 $file1
6611         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6612         stripe=$($LFS getstripe -c $file1)
6613         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6614         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6615
6616         # clean up
6617         rm -f $file1
6618 }
6619 run_test 56x "lfs migration support"
6620
6621 test_56xa() {
6622         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6623         check_swap_layouts_support
6624
6625         local dir=$DIR/$tdir/$testnum
6626
6627         test_mkdir -p $dir
6628
6629         local ref1=/etc/passwd
6630         local file1=$dir/file1
6631
6632         $LFS setstripe -c 2 $file1
6633         cp $ref1 $file1
6634         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6635
6636         local stripe=$($LFS getstripe -c $file1)
6637
6638         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6639         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6640
6641         # clean up
6642         rm -f $file1
6643 }
6644 run_test 56xa "lfs migration --block support"
6645
6646 check_migrate_links() {
6647         local dir="$1"
6648         local file1="$dir/file1"
6649         local begin="$2"
6650         local count="$3"
6651         local runas="$4"
6652         local total_count=$(($begin + $count - 1))
6653         local symlink_count=10
6654         local uniq_count=10
6655
6656         if [ ! -f "$file1" ]; then
6657                 echo -n "creating initial file..."
6658                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6659                         error "cannot setstripe initial file"
6660                 echo "done"
6661
6662                 echo -n "creating symlinks..."
6663                 for s in $(seq 1 $symlink_count); do
6664                         ln -s "$file1" "$dir/slink$s" ||
6665                                 error "cannot create symlinks"
6666                 done
6667                 echo "done"
6668
6669                 echo -n "creating nonlinked files..."
6670                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6671                         error "cannot create nonlinked files"
6672                 echo "done"
6673         fi
6674
6675         # create hard links
6676         if [ ! -f "$dir/file$total_count" ]; then
6677                 echo -n "creating hard links $begin:$total_count..."
6678                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6679                         /dev/null || error "cannot create hard links"
6680                 echo "done"
6681         fi
6682
6683         echo -n "checking number of hard links listed in xattrs..."
6684         local fid=$($LFS getstripe -F "$file1")
6685         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6686
6687         echo "${#paths[*]}"
6688         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6689                         skip "hard link list has unexpected size, skipping test"
6690         fi
6691         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6692                         error "link names should exceed xattrs size"
6693         fi
6694
6695         echo -n "migrating files..."
6696         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6697         local rc=$?
6698         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6699         echo "done"
6700
6701         # make sure all links have been properly migrated
6702         echo -n "verifying files..."
6703         fid=$($LFS getstripe -F "$file1") ||
6704                 error "cannot get fid for file $file1"
6705         for i in $(seq 2 $total_count); do
6706                 local fid2=$($LFS getstripe -F $dir/file$i)
6707
6708                 [ "$fid2" == "$fid" ] ||
6709                         error "migrated hard link has mismatched FID"
6710         done
6711
6712         # make sure hard links were properly detected, and migration was
6713         # performed only once for the entire link set; nonlinked files should
6714         # also be migrated
6715         local actual=$(grep -c 'done' <<< "$migrate_out")
6716         local expected=$(($uniq_count + 1))
6717
6718         [ "$actual" -eq  "$expected" ] ||
6719                 error "hard links individually migrated ($actual != $expected)"
6720
6721         # make sure the correct number of hard links are present
6722         local hardlinks=$(stat -c '%h' "$file1")
6723
6724         [ $hardlinks -eq $total_count ] ||
6725                 error "num hard links $hardlinks != $total_count"
6726         echo "done"
6727
6728         return 0
6729 }
6730
6731 test_56xb() {
6732         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6733                 skip "Need MDS version at least 2.10.55"
6734
6735         local dir="$DIR/$tdir"
6736
6737         test_mkdir "$dir" || error "cannot create dir $dir"
6738
6739         echo "testing lfs migrate mode when all links fit within xattrs"
6740         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6741
6742         echo "testing rsync mode when all links fit within xattrs"
6743         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6744
6745         echo "testing lfs migrate mode when all links do not fit within xattrs"
6746         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6747
6748         echo "testing rsync mode when all links do not fit within xattrs"
6749         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6750
6751         chown -R $RUNAS_ID $dir
6752         echo "testing non-root lfs migrate mode when not all links are in xattr"
6753         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
6754
6755         # clean up
6756         rm -rf $dir
6757 }
6758 run_test 56xb "lfs migration hard link support"
6759
6760 test_56xc() {
6761         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6762
6763         local dir="$DIR/$tdir"
6764
6765         test_mkdir "$dir" || error "cannot create dir $dir"
6766
6767         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6768         echo -n "Setting initial stripe for 20MB test file..."
6769         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
6770                 error "cannot setstripe 20MB file"
6771         echo "done"
6772         echo -n "Sizing 20MB test file..."
6773         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6774         echo "done"
6775         echo -n "Verifying small file autostripe count is 1..."
6776         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
6777                 error "cannot migrate 20MB file"
6778         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6779                 error "cannot get stripe for $dir/20mb"
6780         [ $stripe_count -eq 1 ] ||
6781                 error "unexpected stripe count $stripe_count for 20MB file"
6782         rm -f "$dir/20mb"
6783         echo "done"
6784
6785         # Test 2: File is small enough to fit within the available space on
6786         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6787         # have at least an additional 1KB for each desired stripe for test 3
6788         echo -n "Setting stripe for 1GB test file..."
6789         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
6790         echo "done"
6791         echo -n "Sizing 1GB test file..."
6792         # File size is 1GB + 3KB
6793         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
6794         echo "done"
6795
6796         # need at least 512MB per OST for 1GB file to fit in 2 stripes
6797         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
6798         if (( avail > 524288 * OSTCOUNT )); then
6799                 echo -n "Migrating 1GB file..."
6800                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
6801                         error "cannot migrate 1GB file"
6802                 echo "done"
6803                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
6804                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6805                         error "cannot getstripe for 1GB file"
6806                 [ $stripe_count -eq 2 ] ||
6807                         error "unexpected stripe count $stripe_count != 2"
6808                 echo "done"
6809         fi
6810
6811         # Test 3: File is too large to fit within the available space on
6812         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6813         if [ $OSTCOUNT -ge 3 ]; then
6814                 # The required available space is calculated as
6815                 # file size (1GB + 3KB) / OST count (3).
6816                 local kb_per_ost=349526
6817
6818                 echo -n "Migrating 1GB file with limit..."
6819                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
6820                         error "cannot migrate 1GB file with limit"
6821                 echo "done"
6822
6823                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6824                 echo -n "Verifying 1GB autostripe count with limited space..."
6825                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
6826                         error "unexpected stripe count $stripe_count (min 3)"
6827                 echo "done"
6828         fi
6829
6830         # clean up
6831         rm -rf $dir
6832 }
6833 run_test 56xc "lfs migration autostripe"
6834
6835 test_56y() {
6836         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
6837                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
6838
6839         local res=""
6840         local dir=$DIR/$tdir
6841         local f1=$dir/file1
6842         local f2=$dir/file2
6843
6844         test_mkdir -p $dir || error "creating dir $dir"
6845         touch $f1 || error "creating std file $f1"
6846         $MULTIOP $f2 H2c || error "creating released file $f2"
6847
6848         # a directory can be raid0, so ask only for files
6849         res=$($LFS find $dir -L raid0 -type f | wc -l)
6850         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6851
6852         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6853         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6854
6855         # only files can be released, so no need to force file search
6856         res=$($LFS find $dir -L released)
6857         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6858
6859         res=$($LFS find $dir -type f \! -L released)
6860         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6861 }
6862 run_test 56y "lfs find -L raid0|released"
6863
6864 test_56z() { # LU-4824
6865         # This checks to make sure 'lfs find' continues after errors
6866         # There are two classes of errors that should be caught:
6867         # - If multiple paths are provided, all should be searched even if one
6868         #   errors out
6869         # - If errors are encountered during the search, it should not terminate
6870         #   early
6871         local dir=$DIR/$tdir
6872         local i
6873
6874         test_mkdir $dir
6875         for i in d{0..9}; do
6876                 test_mkdir $dir/$i
6877                 touch $dir/$i/$tfile
6878         done
6879         $LFS find $DIR/non_existent_dir $dir &&
6880                 error "$LFS find did not return an error"
6881         # Make a directory unsearchable. This should NOT be the last entry in
6882         # directory order.  Arbitrarily pick the 6th entry
6883         chmod 700 $($LFS find $dir -type d | sed '6!d')
6884
6885         $RUNAS $LFS find $DIR/non_existent $dir
6886         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6887
6888         # The user should be able to see 10 directories and 9 files
6889         (( count == 19 )) ||
6890                 error "$LFS find found $count != 19 entries after error"
6891 }
6892 run_test 56z "lfs find should continue after an error"
6893
6894 test_56aa() { # LU-5937
6895         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6896
6897         local dir=$DIR/$tdir
6898
6899         mkdir $dir
6900         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6901
6902         createmany -o $dir/striped_dir/${tfile}- 1024
6903         local dirs=$($LFS find --size +8k $dir/)
6904
6905         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6906 }
6907 run_test 56aa "lfs find --size under striped dir"
6908
6909 test_56ab() { # LU-10705
6910         test_mkdir $DIR/$tdir
6911         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6912         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6913         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6914         # Flush writes to ensure valid blocks.  Need to be more thorough for
6915         # ZFS, since blocks are not allocated/returned to client immediately.
6916         sync_all_data
6917         wait_zfs_commit ost1 2
6918         cancel_lru_locks osc
6919         ls -ls $DIR/$tdir
6920
6921         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6922
6923         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6924
6925         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6926         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6927
6928         rm -f $DIR/$tdir/$tfile.[123]
6929 }
6930 run_test 56ab "lfs find --blocks"
6931
6932 test_56ba() {
6933         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6934                 skip "Need MDS version at least 2.10.50"
6935
6936         # Create composite files with one component
6937         local dir=$DIR/$tdir
6938
6939         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6940         # Create composite files with three components
6941         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6942         # Create non-composite files
6943         createmany -o $dir/${tfile}- 10
6944
6945         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6946
6947         [[ $nfiles == 10 ]] ||
6948                 error "lfs find -E 1M found $nfiles != 10 files"
6949
6950         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6951         [[ $nfiles == 25 ]] ||
6952                 error "lfs find ! -E 1M found $nfiles != 25 files"
6953
6954         # All files have a component that starts at 0
6955         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6956         [[ $nfiles == 35 ]] ||
6957                 error "lfs find --component-start 0 - $nfiles != 35 files"
6958
6959         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6960         [[ $nfiles == 15 ]] ||
6961                 error "lfs find --component-start 2M - $nfiles != 15 files"
6962
6963         # All files created here have a componenet that does not starts at 2M
6964         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6965         [[ $nfiles == 35 ]] ||
6966                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6967
6968         # Find files with a specified number of components
6969         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6970         [[ $nfiles == 15 ]] ||
6971                 error "lfs find --component-count 3 - $nfiles != 15 files"
6972
6973         # Remember non-composite files have a component count of zero
6974         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6975         [[ $nfiles == 10 ]] ||
6976                 error "lfs find --component-count 0 - $nfiles != 10 files"
6977
6978         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6979         [[ $nfiles == 20 ]] ||
6980                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6981
6982         # All files have a flag called "init"
6983         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6984         [[ $nfiles == 35 ]] ||
6985                 error "lfs find --component-flags init - $nfiles != 35 files"
6986
6987         # Multi-component files will have a component not initialized
6988         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6989         [[ $nfiles == 15 ]] ||
6990                 error "lfs find !--component-flags init - $nfiles != 15 files"
6991
6992         rm -rf $dir
6993
6994 }
6995 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6996
6997 test_56ca() {
6998         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6999                 skip "Need MDS version at least 2.10.57"
7000
7001         local td=$DIR/$tdir
7002         local tf=$td/$tfile
7003         local dir
7004         local nfiles
7005         local cmd
7006         local i
7007         local j
7008
7009         # create mirrored directories and mirrored files
7010         mkdir $td || error "mkdir $td failed"
7011         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7012         createmany -o $tf- 10 || error "create $tf- failed"
7013
7014         for i in $(seq 2); do
7015                 dir=$td/dir$i
7016                 mkdir $dir || error "mkdir $dir failed"
7017                 $LFS mirror create -N$((3 + i)) $dir ||
7018                         error "create mirrored dir $dir failed"
7019                 createmany -o $dir/$tfile- 10 ||
7020                         error "create $dir/$tfile- failed"
7021         done
7022
7023         # change the states of some mirrored files
7024         echo foo > $tf-6
7025         for i in $(seq 2); do
7026                 dir=$td/dir$i
7027                 for j in $(seq 4 9); do
7028                         echo foo > $dir/$tfile-$j
7029                 done
7030         done
7031
7032         # find mirrored files with specific mirror count
7033         cmd="$LFS find --mirror-count 3 --type f $td"
7034         nfiles=$($cmd | wc -l)
7035         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7036
7037         cmd="$LFS find ! --mirror-count 3 --type f $td"
7038         nfiles=$($cmd | wc -l)
7039         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7040
7041         cmd="$LFS find --mirror-count +2 --type f $td"
7042         nfiles=$($cmd | wc -l)
7043         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7044
7045         cmd="$LFS find --mirror-count -6 --type f $td"
7046         nfiles=$($cmd | wc -l)
7047         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7048
7049         # find mirrored files with specific file state
7050         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7051         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7052
7053         cmd="$LFS find --mirror-state=ro --type f $td"
7054         nfiles=$($cmd | wc -l)
7055         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7056
7057         cmd="$LFS find ! --mirror-state=ro --type f $td"
7058         nfiles=$($cmd | wc -l)
7059         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7060
7061         cmd="$LFS find --mirror-state=wp --type f $td"
7062         nfiles=$($cmd | wc -l)
7063         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7064
7065         cmd="$LFS find ! --mirror-state=sp --type f $td"
7066         nfiles=$($cmd | wc -l)
7067         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7068 }
7069 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7070
7071 test_57a() {
7072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7073         # note test will not do anything if MDS is not local
7074         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7075                 skip_env "ldiskfs only test"
7076         fi
7077         remote_mds_nodsh && skip "remote MDS with nodsh"
7078
7079         local MNTDEV="osd*.*MDT*.mntdev"
7080         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7081         [ -z "$DEV" ] && error "can't access $MNTDEV"
7082         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7083                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7084                         error "can't access $DEV"
7085                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7086                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7087                 rm $TMP/t57a.dump
7088         done
7089 }
7090 run_test 57a "verify MDS filesystem created with large inodes =="
7091
7092 test_57b() {
7093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7094         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7095                 skip_env "ldiskfs only test"
7096         fi
7097         remote_mds_nodsh && skip "remote MDS with nodsh"
7098
7099         local dir=$DIR/$tdir
7100         local filecount=100
7101         local file1=$dir/f1
7102         local fileN=$dir/f$filecount
7103
7104         rm -rf $dir || error "removing $dir"
7105         test_mkdir -c1 $dir
7106         local mdtidx=$($LFS getstripe -m $dir)
7107         local mdtname=MDT$(printf %04x $mdtidx)
7108         local facet=mds$((mdtidx + 1))
7109
7110         echo "mcreating $filecount files"
7111         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7112
7113         # verify that files do not have EAs yet
7114         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7115                 error "$file1 has an EA"
7116         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7117                 error "$fileN has an EA"
7118
7119         sync
7120         sleep 1
7121         df $dir  #make sure we get new statfs data
7122         local mdsfree=$(do_facet $facet \
7123                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7124         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7125         local file
7126
7127         echo "opening files to create objects/EAs"
7128         for file in $(seq -f $dir/f%g 1 $filecount); do
7129                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7130                         error "opening $file"
7131         done
7132
7133         # verify that files have EAs now
7134         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7135         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7136
7137         sleep 1  #make sure we get new statfs data
7138         df $dir
7139         local mdsfree2=$(do_facet $facet \
7140                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7141         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7142
7143         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7144                 if [ "$mdsfree" != "$mdsfree2" ]; then
7145                         error "MDC before $mdcfree != after $mdcfree2"
7146                 else
7147                         echo "MDC before $mdcfree != after $mdcfree2"
7148                         echo "unable to confirm if MDS has large inodes"
7149                 fi
7150         fi
7151         rm -rf $dir
7152 }
7153 run_test 57b "default LOV EAs are stored inside large inodes ==="
7154
7155 test_58() {
7156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7157         [ -z "$(which wiretest 2>/dev/null)" ] &&
7158                         skip_env "could not find wiretest"
7159
7160         wiretest
7161 }
7162 run_test 58 "verify cross-platform wire constants =============="
7163
7164 test_59() {
7165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7166
7167         echo "touch 130 files"
7168         createmany -o $DIR/f59- 130
7169         echo "rm 130 files"
7170         unlinkmany $DIR/f59- 130
7171         sync
7172         # wait for commitment of removal
7173         wait_delete_completed
7174 }
7175 run_test 59 "verify cancellation of llog records async ========="
7176
7177 TEST60_HEAD="test_60 run $RANDOM"
7178 test_60a() {
7179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7180         remote_mgs_nodsh && skip "remote MGS with nodsh"
7181         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7182                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7183                         skip_env "missing subtest run-llog.sh"
7184
7185         log "$TEST60_HEAD - from kernel mode"
7186         do_facet mgs "$LCTL dk > /dev/null"
7187         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7188         do_facet mgs $LCTL dk > $TMP/$tfile
7189
7190         # LU-6388: test llog_reader
7191         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7192         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7193         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7194                         skip_env "missing llog_reader"
7195         local fstype=$(facet_fstype mgs)
7196         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7197                 skip_env "Only for ldiskfs or zfs type mgs"
7198
7199         local mntpt=$(facet_mntpt mgs)
7200         local mgsdev=$(mgsdevname 1)
7201         local fid_list
7202         local fid
7203         local rec_list
7204         local rec
7205         local rec_type
7206         local obj_file
7207         local path
7208         local seq
7209         local oid
7210         local pass=true
7211
7212         #get fid and record list
7213         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7214                 tail -n 4))
7215         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7216                 tail -n 4))
7217         #remount mgs as ldiskfs or zfs type
7218         stop mgs || error "stop mgs failed"
7219         mount_fstype mgs || error "remount mgs failed"
7220         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7221                 fid=${fid_list[i]}
7222                 rec=${rec_list[i]}
7223                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7224                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7225                 oid=$((16#$oid))
7226
7227                 case $fstype in
7228                         ldiskfs )
7229                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7230                         zfs )
7231                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7232                 esac
7233                 echo "obj_file is $obj_file"
7234                 do_facet mgs $llog_reader $obj_file
7235
7236                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7237                         awk '{ print $3 }' | sed -e "s/^type=//g")
7238                 if [ $rec_type != $rec ]; then
7239                         echo "FAILED test_60a wrong record type $rec_type," \
7240                               "should be $rec"
7241                         pass=false
7242                         break
7243                 fi
7244
7245                 #check obj path if record type is LLOG_LOGID_MAGIC
7246                 if [ "$rec" == "1064553b" ]; then
7247                         path=$(do_facet mgs $llog_reader $obj_file |
7248                                 grep "path=" | awk '{ print $NF }' |
7249                                 sed -e "s/^path=//g")
7250                         if [ $obj_file != $mntpt/$path ]; then
7251                                 echo "FAILED test_60a wrong obj path" \
7252                                       "$montpt/$path, should be $obj_file"
7253                                 pass=false
7254                                 break
7255                         fi
7256                 fi
7257         done
7258         rm -f $TMP/$tfile
7259         #restart mgs before "error", otherwise it will block the next test
7260         stop mgs || error "stop mgs failed"
7261         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7262         $pass || error "test failed, see FAILED test_60a messages for specifics"
7263 }
7264 run_test 60a "llog_test run from kernel module and test llog_reader"
7265
7266 test_60b() { # bug 6411
7267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7268
7269         dmesg > $DIR/$tfile
7270         LLOG_COUNT=$(do_facet mgs dmesg |
7271                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7272                           /llog_[a-z]*.c:[0-9]/ {
7273                                 if (marker)
7274                                         from_marker++
7275                                 from_begin++
7276                           }
7277                           END {
7278                                 if (marker)
7279                                         print from_marker
7280                                 else
7281                                         print from_begin
7282                           }")
7283
7284         [[ $LLOG_COUNT -gt 120 ]] &&
7285                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7286 }
7287 run_test 60b "limit repeated messages from CERROR/CWARN"
7288
7289 test_60c() {
7290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7291
7292         echo "create 5000 files"
7293         createmany -o $DIR/f60c- 5000
7294 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7295         lctl set_param fail_loc=0x80000137
7296         unlinkmany $DIR/f60c- 5000
7297         lctl set_param fail_loc=0
7298 }
7299 run_test 60c "unlink file when mds full"
7300
7301 test_60d() {
7302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7303
7304         SAVEPRINTK=$(lctl get_param -n printk)
7305         # verify "lctl mark" is even working"
7306         MESSAGE="test message ID $RANDOM $$"
7307         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7308         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7309
7310         lctl set_param printk=0 || error "set lnet.printk failed"
7311         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7312         MESSAGE="new test message ID $RANDOM $$"
7313         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7314         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7315         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7316
7317         lctl set_param -n printk="$SAVEPRINTK"
7318 }
7319 run_test 60d "test printk console message masking"
7320
7321 test_60e() {
7322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7323         remote_mds_nodsh && skip "remote MDS with nodsh"
7324
7325         touch $DIR/$tfile
7326 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7327         do_facet mds1 lctl set_param fail_loc=0x15b
7328         rm $DIR/$tfile
7329 }
7330 run_test 60e "no space while new llog is being created"
7331
7332 test_60g() {
7333         local pid
7334         local i
7335
7336         test_mkdir -c $MDSCOUNT $DIR/$tdir
7337
7338         (
7339                 local index=0
7340                 while true; do
7341                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7342                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7343                                 2>/dev/null
7344                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7345                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7346                         index=$((index + 1))
7347                 done
7348         ) &
7349
7350         pid=$!
7351
7352         for i in {0..100}; do
7353                 # define OBD_FAIL_OSD_TXN_START    0x19a
7354                 local index=$((i % MDSCOUNT + 1))
7355
7356                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7357                         > /dev/null
7358                 usleep 100
7359         done
7360
7361         kill -9 $pid
7362
7363         for i in $(seq $MDSCOUNT); do
7364                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7365         done
7366
7367         mkdir $DIR/$tdir/new || error "mkdir failed"
7368         rmdir $DIR/$tdir/new || error "rmdir failed"
7369
7370         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7371                 -t namespace
7372         for i in $(seq $MDSCOUNT); do
7373                 wait_update_facet mds$i "$LCTL get_param -n \
7374                         mdd.$(facet_svc mds$i).lfsck_namespace |
7375                         awk '/^status/ { print \\\$2 }'" "completed"
7376         done
7377
7378         ls -R $DIR/$tdir || error "ls failed"
7379         rm -rf $DIR/$tdir || error "rmdir failed"
7380 }
7381 run_test 60g "transaction abort won't cause MDT hung"
7382
7383 test_60h() {
7384         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7385                 skip "Need MDS version at least 2.12.52"
7386         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7387
7388         local f
7389
7390         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7391         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7392         for fail_loc in 0x80000188 0x80000189; do
7393                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7394                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7395                         error "mkdir $dir-$fail_loc failed"
7396                 for i in {0..10}; do
7397                         # create may fail on missing stripe
7398                         echo $i > $DIR/$tdir-$fail_loc/$i
7399                 done
7400                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7401                         error "getdirstripe $tdir-$fail_loc failed"
7402                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7403                         error "migrate $tdir-$fail_loc failed"
7404                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7405                         error "getdirstripe $tdir-$fail_loc failed"
7406                 pushd $DIR/$tdir-$fail_loc
7407                 for f in *; do
7408                         echo $f | cmp $f - || error "$f data mismatch"
7409                 done
7410                 popd
7411                 rm -rf $DIR/$tdir-$fail_loc
7412         done
7413 }
7414 run_test 60h "striped directory with missing stripes can be accessed"
7415
7416 test_61a() {
7417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7418
7419         f="$DIR/f61"
7420         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7421         cancel_lru_locks osc
7422         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7423         sync
7424 }
7425 run_test 61a "mmap() writes don't make sync hang ================"
7426
7427 test_61b() {
7428         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7429 }
7430 run_test 61b "mmap() of unstriped file is successful"
7431
7432 # bug 2330 - insufficient obd_match error checking causes LBUG
7433 test_62() {
7434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7435
7436         f="$DIR/f62"
7437         echo foo > $f
7438         cancel_lru_locks osc
7439         lctl set_param fail_loc=0x405
7440         cat $f && error "cat succeeded, expect -EIO"
7441         lctl set_param fail_loc=0
7442 }
7443 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7444 # match every page all of the time.
7445 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7446
7447 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7448 # Though this test is irrelevant anymore, it helped to reveal some
7449 # other grant bugs (LU-4482), let's keep it.
7450 test_63a() {   # was test_63
7451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7452
7453         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7454
7455         for i in `seq 10` ; do
7456                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7457                 sleep 5
7458                 kill $!
7459                 sleep 1
7460         done
7461
7462         rm -f $DIR/f63 || true
7463 }
7464 run_test 63a "Verify oig_wait interruption does not crash ======="
7465
7466 # bug 2248 - async write errors didn't return to application on sync
7467 # bug 3677 - async write errors left page locked
7468 test_63b() {
7469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7470
7471         debugsave
7472         lctl set_param debug=-1
7473
7474         # ensure we have a grant to do async writes
7475         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7476         rm $DIR/$tfile
7477
7478         sync    # sync lest earlier test intercept the fail_loc
7479
7480         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7481         lctl set_param fail_loc=0x80000406
7482         $MULTIOP $DIR/$tfile Owy && \
7483                 error "sync didn't return ENOMEM"
7484         sync; sleep 2; sync     # do a real sync this time to flush page
7485         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7486                 error "locked page left in cache after async error" || true
7487         debugrestore
7488 }
7489 run_test 63b "async write errors should be returned to fsync ==="
7490
7491 test_64a () {
7492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7493
7494         df $DIR
7495         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
7496 }
7497 run_test 64a "verify filter grant calculations (in kernel) ====="
7498
7499 test_64b () {
7500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7501
7502         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7503 }
7504 run_test 64b "check out-of-space detection on client"
7505
7506 test_64c() {
7507         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7508 }
7509 run_test 64c "verify grant shrink"
7510
7511 # this does exactly what osc_request.c:osc_announce_cached() does in
7512 # order to calculate max amount of grants to ask from server
7513 want_grant() {
7514         local tgt=$1
7515
7516         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7517         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7518
7519         ((rpc_in_flight ++));
7520         nrpages=$((nrpages * rpc_in_flight))
7521
7522         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7523
7524         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7525
7526         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7527         local undirty=$((nrpages * PAGE_SIZE))
7528
7529         local max_extent_pages
7530         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7531             grep grant_max_extent_size | awk '{print $2}')
7532         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7533         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7534         local grant_extent_tax
7535         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7536             grep grant_extent_tax | awk '{print $2}')
7537
7538         undirty=$((undirty + nrextents * grant_extent_tax))
7539
7540         echo $undirty
7541 }
7542
7543 # this is size of unit for grant allocation. It should be equal to
7544 # what tgt_grant.c:tgt_grant_chunk() calculates
7545 grant_chunk() {
7546         local tgt=$1
7547         local max_brw_size
7548         local grant_extent_tax
7549
7550         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7551             grep max_brw_size | awk '{print $2}')
7552
7553         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7554             grep grant_extent_tax | awk '{print $2}')
7555
7556         echo $(((max_brw_size + grant_extent_tax) * 2))
7557 }
7558
7559 test_64d() {
7560         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7561                 skip "OST < 2.10.55 doesn't limit grants enough"
7562
7563         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7564         local file=$DIR/$tfile
7565
7566         [[ $($LCTL get_param osc.${tgt}.import |
7567              grep "connect_flags:.*grant_param") ]] ||
7568                 skip "no grant_param connect flag"
7569
7570         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7571
7572         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7573
7574         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7575         stack_trap "rm -f $file" EXIT
7576
7577         $LFS setstripe $file -i 0 -c 1
7578         dd if=/dev/zero of=$file bs=1M count=1000 &
7579         ddpid=$!
7580
7581         while true
7582         do
7583                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7584                 if [[ $cur_grant -gt $max_cur_granted ]]
7585                 then
7586                         kill $ddpid
7587                         error "cur_grant $cur_grant > $max_cur_granted"
7588                 fi
7589                 kill -0 $ddpid
7590                 [[ $? -ne 0 ]] && break;
7591                 sleep 2
7592         done
7593
7594         rm -f $DIR/$tfile
7595         wait_delete_completed
7596         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7597 }
7598 run_test 64d "check grant limit exceed"
7599
7600 # bug 1414 - set/get directories' stripe info
7601 test_65a() {
7602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7603
7604         test_mkdir $DIR/$tdir
7605         touch $DIR/$tdir/f1
7606         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7607 }
7608 run_test 65a "directory with no stripe info"
7609
7610 test_65b() {
7611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7612
7613         test_mkdir $DIR/$tdir
7614         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7615
7616         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7617                                                 error "setstripe"
7618         touch $DIR/$tdir/f2
7619         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7620 }
7621 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7622
7623 test_65c() {
7624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7625         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7626
7627         test_mkdir $DIR/$tdir
7628         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7629
7630         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7631                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7632         touch $DIR/$tdir/f3
7633         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7634 }
7635 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7636
7637 test_65d() {
7638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7639
7640         test_mkdir $DIR/$tdir
7641         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7642         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7643
7644         if [[ $STRIPECOUNT -le 0 ]]; then
7645                 sc=1
7646         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7647                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7648                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7649         else
7650                 sc=$(($STRIPECOUNT - 1))
7651         fi
7652         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7653         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7654         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7655                 error "lverify failed"
7656 }
7657 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7658
7659 test_65e() {
7660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7661
7662         test_mkdir $DIR/$tdir
7663
7664         $LFS setstripe $DIR/$tdir || error "setstripe"
7665         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7666                                         error "no stripe info failed"
7667         touch $DIR/$tdir/f6
7668         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7669 }
7670 run_test 65e "directory setstripe defaults"
7671
7672 test_65f() {
7673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7674
7675         test_mkdir $DIR/${tdir}f
7676         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7677                 error "setstripe succeeded" || true
7678 }
7679 run_test 65f "dir setstripe permission (should return error) ==="
7680
7681 test_65g() {
7682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7683
7684         test_mkdir $DIR/$tdir
7685         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7686
7687         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7688                 error "setstripe -S failed"
7689         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7690         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7691                 error "delete default stripe failed"
7692 }
7693 run_test 65g "directory setstripe -d"
7694
7695 test_65h() {
7696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7697
7698         test_mkdir $DIR/$tdir
7699         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7700
7701         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7702                 error "setstripe -S failed"
7703         test_mkdir $DIR/$tdir/dd1
7704         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7705                 error "stripe info inherit failed"
7706 }
7707 run_test 65h "directory stripe info inherit ===================="
7708
7709 test_65i() {
7710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7711
7712         save_layout_restore_at_exit $MOUNT
7713
7714         # bug6367: set non-default striping on root directory
7715         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7716
7717         # bug12836: getstripe on -1 default directory striping
7718         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7719
7720         # bug12836: getstripe -v on -1 default directory striping
7721         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7722
7723         # bug12836: new find on -1 default directory striping
7724         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7725 }
7726 run_test 65i "various tests to set root directory striping"
7727
7728 test_65j() { # bug6367
7729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7730
7731         sync; sleep 1
7732
7733         # if we aren't already remounting for each test, do so for this test
7734         if [ "$I_MOUNTED" = "yes" ]; then
7735                 cleanup || error "failed to unmount"
7736                 setup
7737         fi
7738
7739         save_layout_restore_at_exit $MOUNT
7740
7741         $LFS setstripe -d $MOUNT || error "setstripe failed"
7742 }
7743 run_test 65j "set default striping on root directory (bug 6367)="
7744
7745 cleanup_65k() {
7746         rm -rf $DIR/$tdir
7747         wait_delete_completed
7748         do_facet $SINGLEMDS "lctl set_param -n \
7749                 osp.$ost*MDT0000.max_create_count=$max_count"
7750         do_facet $SINGLEMDS "lctl set_param -n \
7751                 osp.$ost*MDT0000.create_count=$count"
7752         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7753         echo $INACTIVE_OSC "is Activate"
7754
7755         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7756 }
7757
7758 test_65k() { # bug11679
7759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7760         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7761         remote_mds_nodsh && skip "remote MDS with nodsh"
7762
7763         local disable_precreate=true
7764         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7765                 disable_precreate=false
7766
7767         echo "Check OST status: "
7768         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7769                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7770
7771         for OSC in $MDS_OSCS; do
7772                 echo $OSC "is active"
7773                 do_facet $SINGLEMDS lctl --device %$OSC activate
7774         done
7775
7776         for INACTIVE_OSC in $MDS_OSCS; do
7777                 local ost=$(osc_to_ost $INACTIVE_OSC)
7778                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
7779                                lov.*md*.target_obd |
7780                                awk -F: /$ost/'{ print $1 }' | head -n 1)
7781
7782                 mkdir -p $DIR/$tdir
7783                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
7784                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
7785
7786                 echo "Deactivate: " $INACTIVE_OSC
7787                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
7788
7789                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
7790                               osp.$ost*MDT0000.create_count")
7791                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
7792                                   osp.$ost*MDT0000.max_create_count")
7793                 $disable_precreate &&
7794                         do_facet $SINGLEMDS "lctl set_param -n \
7795                                 osp.$ost*MDT0000.max_create_count=0"
7796
7797                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
7798                         [ -f $DIR/$tdir/$idx ] && continue
7799                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
7800                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
7801                                 { cleanup_65k;
7802                                   error "setstripe $idx should succeed"; }
7803                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
7804                 done
7805                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
7806                 rmdir $DIR/$tdir
7807
7808                 do_facet $SINGLEMDS "lctl set_param -n \
7809                         osp.$ost*MDT0000.max_create_count=$max_count"
7810                 do_facet $SINGLEMDS "lctl set_param -n \
7811                         osp.$ost*MDT0000.create_count=$count"
7812                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7813                 echo $INACTIVE_OSC "is Activate"
7814
7815                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7816         done
7817 }
7818 run_test 65k "validate manual striping works properly with deactivated OSCs"
7819
7820 test_65l() { # bug 12836
7821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7822
7823         test_mkdir -p $DIR/$tdir/test_dir
7824         $LFS setstripe -c -1 $DIR/$tdir/test_dir
7825         $LFS find -mtime -1 $DIR/$tdir >/dev/null
7826 }
7827 run_test 65l "lfs find on -1 stripe dir ========================"
7828
7829 test_65m() {
7830         local layout=$(save_layout $MOUNT)
7831         $RUNAS $LFS setstripe -c 2 $MOUNT && {
7832                 restore_layout $MOUNT $layout
7833                 error "setstripe should fail by non-root users"
7834         }
7835         true
7836 }
7837 run_test 65m "normal user can't set filesystem default stripe"
7838
7839 test_65n() {
7840         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
7841         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
7842                 skip "Need MDS version at least 2.12.50"
7843         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7844
7845         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7846         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
7847         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
7848
7849         local root_layout=$(save_layout $MOUNT)
7850         stack_trap "restore_layout $MOUNT $root_layout" EXIT
7851
7852         # new subdirectory under root directory should not inherit
7853         # the default layout from root
7854         local dir1=$MOUNT/$tdir-1
7855         mkdir $dir1 || error "mkdir $dir1 failed"
7856         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
7857                 error "$dir1 shouldn't have LOV EA"
7858
7859         # delete the default layout on root directory
7860         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
7861
7862         local dir2=$MOUNT/$tdir-2
7863         mkdir $dir2 || error "mkdir $dir2 failed"
7864         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
7865                 error "$dir2 shouldn't have LOV EA"
7866
7867         # set a new striping pattern on root directory
7868         local def_stripe_size=$($LFS getstripe -S $MOUNT)
7869         local new_def_stripe_size=$((def_stripe_size * 2))
7870         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
7871                 error "set stripe size on $MOUNT failed"
7872
7873         # new file created in $dir2 should inherit the new stripe size from
7874         # the filesystem default
7875         local file2=$dir2/$tfile-2
7876         touch $file2 || error "touch $file2 failed"
7877
7878         local file2_stripe_size=$($LFS getstripe -S $file2)
7879         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
7880                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
7881
7882         local dir3=$MOUNT/$tdir-3
7883         mkdir $dir3 || error "mkdir $dir3 failed"
7884         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
7885                 error "$dir3 shouldn't have LOV EA"
7886
7887         # set OST pool on root directory
7888         local pool=$TESTNAME
7889         pool_add $pool || error "add $pool failed"
7890         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
7891                 error "add targets to $pool failed"
7892
7893         $LFS setstripe -p $pool $MOUNT ||
7894                 error "set OST pool on $MOUNT failed"
7895
7896         # new file created in $dir3 should inherit the pool from
7897         # the filesystem default
7898         local file3=$dir3/$tfile-3
7899         touch $file3 || error "touch $file3 failed"
7900
7901         local file3_pool=$($LFS getstripe -p $file3)
7902         [[ "$file3_pool" = "$pool" ]] ||
7903                 error "$file3 didn't inherit OST pool $pool"
7904
7905         local dir4=$MOUNT/$tdir-4
7906         mkdir $dir4 || error "mkdir $dir4 failed"
7907         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7908                 error "$dir4 shouldn't have LOV EA"
7909
7910         # new file created in $dir4 should inherit the pool from
7911         # the filesystem default
7912         local file4=$dir4/$tfile-4
7913         touch $file4 || error "touch $file4 failed"
7914
7915         local file4_pool=$($LFS getstripe -p $file4)
7916         [[ "$file4_pool" = "$pool" ]] ||
7917                 error "$file4 didn't inherit OST pool $pool"
7918
7919         # new subdirectory under non-root directory should inherit
7920         # the default layout from its parent directory
7921         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7922                 error "set directory layout on $dir4 failed"
7923
7924         local dir5=$dir4/$tdir-5
7925         mkdir $dir5 || error "mkdir $dir5 failed"
7926
7927         local dir4_layout=$(get_layout_param $dir4)
7928         local dir5_layout=$(get_layout_param $dir5)
7929         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7930                 error "$dir5 should inherit the default layout from $dir4"
7931
7932         # though subdir under ROOT doesn't inherit default layout, but
7933         # its sub dir/file should be created with default layout.
7934         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
7935         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
7936                 skip "Need MDS version at least 2.12.59"
7937
7938         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
7939         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
7940         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
7941
7942         if [ $default_lmv_hash == "none" ]; then
7943                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
7944         else
7945                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
7946                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
7947         fi
7948
7949         $LFS setdirstripe -D -c 2 $MOUNT ||
7950                 error "setdirstripe -D -c 2 failed"
7951         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
7952         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
7953         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
7954 }
7955 run_test 65n "don't inherit default layout from root for new subdirectories"
7956
7957 # bug 2543 - update blocks count on client
7958 test_66() {
7959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7960
7961         COUNT=${COUNT:-8}
7962         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7963         sync; sync_all_data; sync; sync_all_data
7964         cancel_lru_locks osc
7965         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7966         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7967 }
7968 run_test 66 "update inode blocks count on client ==============="
7969
7970 meminfo() {
7971         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7972 }
7973
7974 swap_used() {
7975         swapon -s | awk '($1 == "'$1'") { print $4 }'
7976 }
7977
7978 # bug5265, obdfilter oa2dentry return -ENOENT
7979 # #define OBD_FAIL_SRV_ENOENT 0x217
7980 test_69() {
7981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7982         remote_ost_nodsh && skip "remote OST with nodsh"
7983
7984         f="$DIR/$tfile"
7985         $LFS setstripe -c 1 -i 0 $f
7986
7987         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7988
7989         do_facet ost1 lctl set_param fail_loc=0x217
7990         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7991         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7992
7993         do_facet ost1 lctl set_param fail_loc=0
7994         $DIRECTIO write $f 0 2 || error "write error"
7995
7996         cancel_lru_locks osc
7997         $DIRECTIO read $f 0 1 || error "read error"
7998
7999         do_facet ost1 lctl set_param fail_loc=0x217
8000         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8001
8002         do_facet ost1 lctl set_param fail_loc=0
8003         rm -f $f
8004 }
8005 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8006
8007 test_71() {
8008         test_mkdir $DIR/$tdir
8009         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8010         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8011 }
8012 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8013
8014 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8016         [ "$RUNAS_ID" = "$UID" ] &&
8017                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8018         # Check that testing environment is properly set up. Skip if not
8019         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8020                 skip_env "User $RUNAS_ID does not exist - skipping"
8021
8022         touch $DIR/$tfile
8023         chmod 777 $DIR/$tfile
8024         chmod ug+s $DIR/$tfile
8025         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8026                 error "$RUNAS dd $DIR/$tfile failed"
8027         # See if we are still setuid/sgid
8028         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8029                 error "S/gid is not dropped on write"
8030         # Now test that MDS is updated too
8031         cancel_lru_locks mdc
8032         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8033                 error "S/gid is not dropped on MDS"
8034         rm -f $DIR/$tfile
8035 }
8036 run_test 72a "Test that remove suid works properly (bug5695) ===="
8037
8038 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8039         local perm
8040
8041         [ "$RUNAS_ID" = "$UID" ] &&
8042                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8043         [ "$RUNAS_ID" -eq 0 ] &&
8044                 skip_env "RUNAS_ID = 0 -- skipping"
8045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8046         # Check that testing environment is properly set up. Skip if not
8047         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8048                 skip_env "User $RUNAS_ID does not exist - skipping"
8049
8050         touch $DIR/${tfile}-f{g,u}
8051         test_mkdir $DIR/${tfile}-dg
8052         test_mkdir $DIR/${tfile}-du
8053         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8054         chmod g+s $DIR/${tfile}-{f,d}g
8055         chmod u+s $DIR/${tfile}-{f,d}u
8056         for perm in 777 2777 4777; do
8057                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8058                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8059                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8060                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8061         done
8062         true
8063 }
8064 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8065
8066 # bug 3462 - multiple simultaneous MDC requests
8067 test_73() {
8068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8069
8070         test_mkdir $DIR/d73-1
8071         test_mkdir $DIR/d73-2
8072         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8073         pid1=$!
8074
8075         lctl set_param fail_loc=0x80000129
8076         $MULTIOP $DIR/d73-1/f73-2 Oc &
8077         sleep 1
8078         lctl set_param fail_loc=0
8079
8080         $MULTIOP $DIR/d73-2/f73-3 Oc &
8081         pid3=$!
8082
8083         kill -USR1 $pid1
8084         wait $pid1 || return 1
8085
8086         sleep 25
8087
8088         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8089         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8090         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8091
8092         rm -rf $DIR/d73-*
8093 }
8094 run_test 73 "multiple MDC requests (should not deadlock)"
8095
8096 test_74a() { # bug 6149, 6184
8097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8098
8099         touch $DIR/f74a
8100         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8101         #
8102         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8103         # will spin in a tight reconnection loop
8104         $LCTL set_param fail_loc=0x8000030e
8105         # get any lock that won't be difficult - lookup works.
8106         ls $DIR/f74a
8107         $LCTL set_param fail_loc=0
8108         rm -f $DIR/f74a
8109         true
8110 }
8111 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8112
8113 test_74b() { # bug 13310
8114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8115
8116         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8117         #
8118         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8119         # will spin in a tight reconnection loop
8120         $LCTL set_param fail_loc=0x8000030e
8121         # get a "difficult" lock
8122         touch $DIR/f74b
8123         $LCTL set_param fail_loc=0
8124         rm -f $DIR/f74b
8125         true
8126 }
8127 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8128
8129 test_74c() {
8130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8131
8132         #define OBD_FAIL_LDLM_NEW_LOCK
8133         $LCTL set_param fail_loc=0x319
8134         touch $DIR/$tfile && error "touch successful"
8135         $LCTL set_param fail_loc=0
8136         true
8137 }
8138 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8139
8140 num_inodes() {
8141         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
8142 }
8143
8144 test_76() { # Now for bug 20433, added originally in bug 1443
8145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8146
8147         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8148
8149         cancel_lru_locks osc
8150         BEFORE_INODES=$(num_inodes)
8151         echo "before inodes: $BEFORE_INODES"
8152         local COUNT=1000
8153         [ "$SLOW" = "no" ] && COUNT=100
8154         for i in $(seq $COUNT); do
8155                 touch $DIR/$tfile
8156                 rm -f $DIR/$tfile
8157         done
8158         cancel_lru_locks osc
8159         AFTER_INODES=$(num_inodes)
8160         echo "after inodes: $AFTER_INODES"
8161         local wait=0
8162         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
8163                 sleep 2
8164                 AFTER_INODES=$(num_inodes)
8165                 wait=$((wait+2))
8166                 echo "wait $wait seconds inodes: $AFTER_INODES"
8167                 if [ $wait -gt 30 ]; then
8168                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
8169                 fi
8170         done
8171 }
8172 run_test 76 "confirm clients recycle inodes properly ===="
8173
8174
8175 export ORIG_CSUM=""
8176 set_checksums()
8177 {
8178         # Note: in sptlrpc modes which enable its own bulk checksum, the
8179         # original crc32_le bulk checksum will be automatically disabled,
8180         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8181         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8182         # In this case set_checksums() will not be no-op, because sptlrpc
8183         # bulk checksum will be enabled all through the test.
8184
8185         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8186         lctl set_param -n osc.*.checksums $1
8187         return 0
8188 }
8189
8190 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8191                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8192 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8193                              tr -d [] | head -n1)}
8194 set_checksum_type()
8195 {
8196         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8197         rc=$?
8198         log "set checksum type to $1, rc = $rc"
8199         return $rc
8200 }
8201
8202 get_osc_checksum_type()
8203 {
8204         # arugment 1: OST name, like OST0000
8205         ost=$1
8206         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8207                         sed 's/.*\[\(.*\)\].*/\1/g')
8208         rc=$?
8209         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8210         echo $checksum_type
8211 }
8212
8213 F77_TMP=$TMP/f77-temp
8214 F77SZ=8
8215 setup_f77() {
8216         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8217                 error "error writing to $F77_TMP"
8218 }
8219
8220 test_77a() { # bug 10889
8221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8222         $GSS && skip_env "could not run with gss"
8223
8224         [ ! -f $F77_TMP ] && setup_f77
8225         set_checksums 1
8226         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8227         set_checksums 0
8228         rm -f $DIR/$tfile
8229 }
8230 run_test 77a "normal checksum read/write operation"
8231
8232 test_77b() { # bug 10889
8233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8234         $GSS && skip_env "could not run with gss"
8235
8236         [ ! -f $F77_TMP ] && setup_f77
8237         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8238         $LCTL set_param fail_loc=0x80000409
8239         set_checksums 1
8240
8241         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8242                 error "dd error: $?"
8243         $LCTL set_param fail_loc=0
8244
8245         for algo in $CKSUM_TYPES; do
8246                 cancel_lru_locks osc
8247                 set_checksum_type $algo
8248                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8249                 $LCTL set_param fail_loc=0x80000408
8250                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8251                 $LCTL set_param fail_loc=0
8252         done
8253         set_checksums 0
8254         set_checksum_type $ORIG_CSUM_TYPE
8255         rm -f $DIR/$tfile
8256 }
8257 run_test 77b "checksum error on client write, read"
8258
8259 cleanup_77c() {
8260         trap 0
8261         set_checksums 0
8262         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8263         $check_ost &&
8264                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8265         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8266         $check_ost && [ -n "$ost_file_prefix" ] &&
8267                 do_facet ost1 rm -f ${ost_file_prefix}\*
8268 }
8269
8270 test_77c() {
8271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8272         $GSS && skip_env "could not run with gss"
8273         remote_ost_nodsh && skip "remote OST with nodsh"
8274
8275         local bad1
8276         local osc_file_prefix
8277         local osc_file
8278         local check_ost=false
8279         local ost_file_prefix
8280         local ost_file
8281         local orig_cksum
8282         local dump_cksum
8283         local fid
8284
8285         # ensure corruption will occur on first OSS/OST
8286         $LFS setstripe -i 0 $DIR/$tfile
8287
8288         [ ! -f $F77_TMP ] && setup_f77
8289         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8290                 error "dd write error: $?"
8291         fid=$($LFS path2fid $DIR/$tfile)
8292
8293         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8294         then
8295                 check_ost=true
8296                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8297                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8298         else
8299                 echo "OSS do not support bulk pages dump upon error"
8300         fi
8301
8302         osc_file_prefix=$($LCTL get_param -n debug_path)
8303         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8304
8305         trap cleanup_77c EXIT
8306
8307         set_checksums 1
8308         # enable bulk pages dump upon error on Client
8309         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8310         # enable bulk pages dump upon error on OSS
8311         $check_ost &&
8312                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8313
8314         # flush Client cache to allow next read to reach OSS
8315         cancel_lru_locks osc
8316
8317         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8318         $LCTL set_param fail_loc=0x80000408
8319         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8320         $LCTL set_param fail_loc=0
8321
8322         rm -f $DIR/$tfile
8323
8324         # check cksum dump on Client
8325         osc_file=$(ls ${osc_file_prefix}*)
8326         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8327         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8328         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8329         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8330         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8331                      cksum)
8332         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8333         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8334                 error "dump content does not match on Client"
8335
8336         $check_ost || skip "No need to check cksum dump on OSS"
8337
8338         # check cksum dump on OSS
8339         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8340         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8341         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8342         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8343         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8344                 error "dump content does not match on OSS"
8345
8346         cleanup_77c
8347 }
8348 run_test 77c "checksum error on client read with debug"
8349
8350 test_77d() { # bug 10889
8351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8352         $GSS && skip_env "could not run with gss"
8353
8354         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8355         $LCTL set_param fail_loc=0x80000409
8356         set_checksums 1
8357         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8358                 error "direct write: rc=$?"
8359         $LCTL set_param fail_loc=0
8360         set_checksums 0
8361
8362         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8363         $LCTL set_param fail_loc=0x80000408
8364         set_checksums 1
8365         cancel_lru_locks osc
8366         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8367                 error "direct read: rc=$?"
8368         $LCTL set_param fail_loc=0
8369         set_checksums 0
8370 }
8371 run_test 77d "checksum error on OST direct write, read"
8372
8373 test_77f() { # bug 10889
8374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8375         $GSS && skip_env "could not run with gss"
8376
8377         set_checksums 1
8378         for algo in $CKSUM_TYPES; do
8379                 cancel_lru_locks osc
8380                 set_checksum_type $algo
8381                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8382                 $LCTL set_param fail_loc=0x409
8383                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8384                         error "direct write succeeded"
8385                 $LCTL set_param fail_loc=0
8386         done
8387         set_checksum_type $ORIG_CSUM_TYPE
8388         set_checksums 0
8389 }
8390 run_test 77f "repeat checksum error on write (expect error)"
8391
8392 test_77g() { # bug 10889
8393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8394         $GSS && skip_env "could not run with gss"
8395         remote_ost_nodsh && skip "remote OST with nodsh"
8396
8397         [ ! -f $F77_TMP ] && setup_f77
8398
8399         local file=$DIR/$tfile
8400         stack_trap "rm -f $file" EXIT
8401
8402         $LFS setstripe -c 1 -i 0 $file
8403         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8404         do_facet ost1 lctl set_param fail_loc=0x8000021a
8405         set_checksums 1
8406         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8407                 error "write error: rc=$?"
8408         do_facet ost1 lctl set_param fail_loc=0
8409         set_checksums 0
8410
8411         cancel_lru_locks osc
8412         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8413         do_facet ost1 lctl set_param fail_loc=0x8000021b
8414         set_checksums 1
8415         cmp $F77_TMP $file || error "file compare failed"
8416         do_facet ost1 lctl set_param fail_loc=0
8417         set_checksums 0
8418 }
8419 run_test 77g "checksum error on OST write, read"
8420
8421 test_77k() { # LU-10906
8422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8423         $GSS && skip_env "could not run with gss"
8424
8425         local cksum_param="osc.$FSNAME*.checksums"
8426         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8427         local checksum
8428         local i
8429
8430         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8431         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
8432         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
8433                 EXIT
8434
8435         for i in 0 1; do
8436                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8437                         error "failed to set checksum=$i on MGS"
8438                 wait_update $HOSTNAME "$get_checksum" $i
8439                 #remount
8440                 echo "remount client, checksum should be $i"
8441                 remount_client $MOUNT || error "failed to remount client"
8442                 checksum=$(eval $get_checksum)
8443                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8444         done
8445         # remove persistent param to avoid races with checksum mountopt below
8446         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8447                 error "failed to delete checksum on MGS"
8448
8449         for opt in "checksum" "nochecksum"; do
8450                 #remount with mount option
8451                 echo "remount client with option $opt, checksum should be $i"
8452                 umount_client $MOUNT || error "failed to umount client"
8453                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8454                         error "failed to mount client with option '$opt'"
8455                 checksum=$(eval $get_checksum)
8456                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8457                 i=$((i - 1))
8458         done
8459
8460         remount_client $MOUNT || error "failed to remount client"
8461 }
8462 run_test 77k "enable/disable checksum correctly"
8463
8464 test_77l() {
8465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8466         $GSS && skip_env "could not run with gss"
8467
8468         set_checksums 1
8469         stack_trap "set_checksums $ORIG_CSUM" EXIT
8470         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8471
8472         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8473
8474         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8475         for algo in $CKSUM_TYPES; do
8476                 set_checksum_type $algo || error "fail to set checksum type $algo"
8477                 osc_algo=$(get_osc_checksum_type OST0000)
8478                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8479
8480                 # no locks, no reqs to let the connection idle
8481                 cancel_lru_locks osc
8482                 lru_resize_disable osc
8483                 wait_osc_import_state client ost1 IDLE
8484
8485                 # ensure ost1 is connected
8486                 stat $DIR/$tfile >/dev/null || error "can't stat"
8487                 wait_osc_import_state client ost1 FULL
8488
8489                 osc_algo=$(get_osc_checksum_type OST0000)
8490                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8491         done
8492         return 0
8493 }
8494 run_test 77l "preferred checksum type is remembered after reconnected"
8495
8496 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8497 rm -f $F77_TMP
8498 unset F77_TMP
8499
8500 cleanup_test_78() {
8501         trap 0
8502         rm -f $DIR/$tfile
8503 }
8504
8505 test_78() { # bug 10901
8506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8507         remote_ost || skip_env "local OST"
8508
8509         NSEQ=5
8510         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8511         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8512         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8513         echo "MemTotal: $MEMTOTAL"
8514
8515         # reserve 256MB of memory for the kernel and other running processes,
8516         # and then take 1/2 of the remaining memory for the read/write buffers.
8517         if [ $MEMTOTAL -gt 512 ] ;then
8518                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8519         else
8520                 # for those poor memory-starved high-end clusters...
8521                 MEMTOTAL=$((MEMTOTAL / 2))
8522         fi
8523         echo "Mem to use for directio: $MEMTOTAL"
8524
8525         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8526         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8527         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8528         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8529                 head -n1)
8530         echo "Smallest OST: $SMALLESTOST"
8531         [[ $SMALLESTOST -lt 10240 ]] &&
8532                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8533
8534         trap cleanup_test_78 EXIT
8535
8536         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8537                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8538
8539         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8540         echo "File size: $F78SIZE"
8541         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8542         for i in $(seq 1 $NSEQ); do
8543                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8544                 echo directIO rdwr round $i of $NSEQ
8545                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8546         done
8547
8548         cleanup_test_78
8549 }
8550 run_test 78 "handle large O_DIRECT writes correctly ============"
8551
8552 test_79() { # bug 12743
8553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8554
8555         wait_delete_completed
8556
8557         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8558         BKFREE=$(calc_osc_kbytes kbytesfree)
8559         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8560
8561         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8562         DFTOTAL=`echo $STRING | cut -d, -f1`
8563         DFUSED=`echo $STRING  | cut -d, -f2`
8564         DFAVAIL=`echo $STRING | cut -d, -f3`
8565         DFFREE=$(($DFTOTAL - $DFUSED))
8566
8567         ALLOWANCE=$((64 * $OSTCOUNT))
8568
8569         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8570            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8571                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8572         fi
8573         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8574            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8575                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8576         fi
8577         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8578            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8579                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8580         fi
8581 }
8582 run_test 79 "df report consistency check ======================="
8583
8584 test_80() { # bug 10718
8585         remote_ost_nodsh && skip "remote OST with nodsh"
8586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8587
8588         # relax strong synchronous semantics for slow backends like ZFS
8589         local soc="obdfilter.*.sync_on_lock_cancel"
8590         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
8591         local hosts=
8592         if [ "$soc_old" != "never" ] &&
8593                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8594                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
8595                                 facet_active_host $host; done | sort -u)
8596                         do_nodes $hosts lctl set_param $soc=never
8597         fi
8598
8599         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8600         sync; sleep 1; sync
8601         local BEFORE=`date +%s`
8602         cancel_lru_locks osc
8603         local AFTER=`date +%s`
8604         local DIFF=$((AFTER-BEFORE))
8605         if [ $DIFF -gt 1 ] ; then
8606                 error "elapsed for 1M@1T = $DIFF"
8607         fi
8608
8609         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
8610
8611         rm -f $DIR/$tfile
8612 }
8613 run_test 80 "Page eviction is equally fast at high offsets too  ===="
8614
8615 test_81a() { # LU-456
8616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8617         remote_ost_nodsh && skip "remote OST with nodsh"
8618
8619         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8620         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8621         do_facet ost1 lctl set_param fail_loc=0x80000228
8622
8623         # write should trigger a retry and success
8624         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8625         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8626         RC=$?
8627         if [ $RC -ne 0 ] ; then
8628                 error "write should success, but failed for $RC"
8629         fi
8630 }
8631 run_test 81a "OST should retry write when get -ENOSPC ==============="
8632
8633 test_81b() { # LU-456
8634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8635         remote_ost_nodsh && skip "remote OST with nodsh"
8636
8637         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8638         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8639         do_facet ost1 lctl set_param fail_loc=0x228
8640
8641         # write should retry several times and return -ENOSPC finally
8642         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8643         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8644         RC=$?
8645         ENOSPC=28
8646         if [ $RC -ne $ENOSPC ] ; then
8647                 error "dd should fail for -ENOSPC, but succeed."
8648         fi
8649 }
8650 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8651
8652 test_82() { # LU-1031
8653         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8654         local gid1=14091995
8655         local gid2=16022000
8656
8657         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8658         local MULTIPID1=$!
8659         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8660         local MULTIPID2=$!
8661         kill -USR1 $MULTIPID2
8662         sleep 2
8663         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8664                 error "First grouplock does not block second one"
8665         else
8666                 echo "Second grouplock blocks first one"
8667         fi
8668         kill -USR1 $MULTIPID1
8669         wait $MULTIPID1
8670         wait $MULTIPID2
8671 }
8672 run_test 82 "Basic grouplock test"
8673
8674 test_99() {
8675         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8676
8677         test_mkdir $DIR/$tdir.cvsroot
8678         chown $RUNAS_ID $DIR/$tdir.cvsroot
8679
8680         cd $TMP
8681         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8682
8683         cd /etc/init.d
8684         # some versions of cvs import exit(1) when asked to import links or
8685         # files they can't read.  ignore those files.
8686         local toignore=$(find . -type l -printf '-I %f\n' -o \
8687                          ! -perm /4 -printf '-I %f\n')
8688         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8689                 $tdir.reposname vtag rtag
8690
8691         cd $DIR
8692         test_mkdir $DIR/$tdir.reposname
8693         chown $RUNAS_ID $DIR/$tdir.reposname
8694         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8695
8696         cd $DIR/$tdir.reposname
8697         $RUNAS touch foo99
8698         $RUNAS cvs add -m 'addmsg' foo99
8699         $RUNAS cvs update
8700         $RUNAS cvs commit -m 'nomsg' foo99
8701         rm -fr $DIR/$tdir.cvsroot
8702 }
8703 run_test 99 "cvs strange file/directory operations"
8704
8705 test_100() {
8706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8707         [[ "$NETTYPE" =~ tcp ]] ||
8708                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8709         remote_ost_nodsh && skip "remote OST with nodsh"
8710         remote_mds_nodsh && skip "remote MDS with nodsh"
8711         remote_servers ||
8712                 skip "useless for local single node setup"
8713
8714         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8715                 [ "$PROT" != "tcp" ] && continue
8716                 RPORT=$(echo $REMOTE | cut -d: -f2)
8717                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8718
8719                 rc=0
8720                 LPORT=`echo $LOCAL | cut -d: -f2`
8721                 if [ $LPORT -ge 1024 ]; then
8722                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8723                         netstat -tna
8724                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8725                 fi
8726         done
8727         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8728 }
8729 run_test 100 "check local port using privileged port ==========="
8730
8731 function get_named_value()
8732 {
8733     local tag
8734
8735     tag=$1
8736     while read ;do
8737         line=$REPLY
8738         case $line in
8739         $tag*)
8740             echo $line | sed "s/^$tag[ ]*//"
8741             break
8742             ;;
8743         esac
8744     done
8745 }
8746
8747 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8748                    awk '/^max_cached_mb/ { print $2 }')
8749
8750 cleanup_101a() {
8751         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8752         trap 0
8753 }
8754
8755 test_101a() {
8756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8757
8758         local s
8759         local discard
8760         local nreads=10000
8761         local cache_limit=32
8762
8763         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8764         trap cleanup_101a EXIT
8765         $LCTL set_param -n llite.*.read_ahead_stats 0
8766         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8767
8768         #
8769         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8770         #
8771         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8772         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8773
8774         discard=0
8775         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8776                 get_named_value 'read but discarded' | cut -d" " -f1); do
8777                         discard=$(($discard + $s))
8778         done
8779         cleanup_101a
8780
8781         $LCTL get_param osc.*-osc*.rpc_stats
8782         $LCTL get_param llite.*.read_ahead_stats
8783
8784         # Discard is generally zero, but sometimes a few random reads line up
8785         # and trigger larger readahead, which is wasted & leads to discards.
8786         if [[ $(($discard)) -gt $nreads ]]; then
8787                 error "too many ($discard) discarded pages"
8788         fi
8789         rm -f $DIR/$tfile || true
8790 }
8791 run_test 101a "check read-ahead for random reads"
8792
8793 setup_test101bc() {
8794         test_mkdir $DIR/$tdir
8795         local ssize=$1
8796         local FILE_LENGTH=$2
8797         STRIPE_OFFSET=0
8798
8799         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
8800
8801         local list=$(comma_list $(osts_nodes))
8802         set_osd_param $list '' read_cache_enable 0
8803         set_osd_param $list '' writethrough_cache_enable 0
8804
8805         trap cleanup_test101bc EXIT
8806         # prepare the read-ahead file
8807         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
8808
8809         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
8810                                 count=$FILE_SIZE_MB 2> /dev/null
8811
8812 }
8813
8814 cleanup_test101bc() {
8815         trap 0
8816         rm -rf $DIR/$tdir
8817         rm -f $DIR/$tfile
8818
8819         local list=$(comma_list $(osts_nodes))
8820         set_osd_param $list '' read_cache_enable 1
8821         set_osd_param $list '' writethrough_cache_enable 1
8822 }
8823
8824 calc_total() {
8825         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
8826 }
8827
8828 ra_check_101() {
8829         local READ_SIZE=$1
8830         local STRIPE_SIZE=$2
8831         local FILE_LENGTH=$3
8832         local RA_INC=1048576
8833         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
8834         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
8835                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
8836         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
8837                         get_named_value 'read but discarded' |
8838                         cut -d" " -f1 | calc_total)
8839         if [[ $DISCARD -gt $discard_limit ]]; then
8840                 $LCTL get_param llite.*.read_ahead_stats
8841                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
8842         else
8843                 echo "Read-ahead success for size ${READ_SIZE}"
8844         fi
8845 }
8846
8847 test_101b() {
8848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8849         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8850
8851         local STRIPE_SIZE=1048576
8852         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
8853
8854         if [ $SLOW == "yes" ]; then
8855                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
8856         else
8857                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
8858         fi
8859
8860         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
8861
8862         # prepare the read-ahead file
8863         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8864         cancel_lru_locks osc
8865         for BIDX in 2 4 8 16 32 64 128 256
8866         do
8867                 local BSIZE=$((BIDX*4096))
8868                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
8869                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
8870                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
8871                 $LCTL set_param -n llite.*.read_ahead_stats 0
8872                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
8873                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
8874                 cancel_lru_locks osc
8875                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
8876         done
8877         cleanup_test101bc
8878         true
8879 }
8880 run_test 101b "check stride-io mode read-ahead ================="
8881
8882 test_101c() {
8883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8884
8885         local STRIPE_SIZE=1048576
8886         local FILE_LENGTH=$((STRIPE_SIZE*100))
8887         local nreads=10000
8888         local rsize=65536
8889         local osc_rpc_stats
8890
8891         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8892
8893         cancel_lru_locks osc
8894         $LCTL set_param osc.*.rpc_stats 0
8895         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
8896         $LCTL get_param osc.*.rpc_stats
8897         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
8898                 local stats=$($LCTL get_param -n $osc_rpc_stats)
8899                 local lines=$(echo "$stats" | awk 'END {print NR;}')
8900                 local size
8901
8902                 if [ $lines -le 20 ]; then
8903                         echo "continue debug"
8904                         continue
8905                 fi
8906                 for size in 1 2 4 8; do
8907                         local rpc=$(echo "$stats" |
8908                                     awk '($1 == "'$size':") {print $2; exit; }')
8909                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
8910                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
8911                 done
8912                 echo "$osc_rpc_stats check passed!"
8913         done
8914         cleanup_test101bc
8915         true
8916 }
8917 run_test 101c "check stripe_size aligned read-ahead ================="
8918
8919 set_read_ahead() {
8920         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
8921         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
8922 }
8923
8924 test_101d() {
8925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8926
8927         local file=$DIR/$tfile
8928         local sz_MB=${FILESIZE_101d:-500}
8929         local ra_MB=${READAHEAD_MB:-40}
8930
8931         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
8932         [ $free_MB -lt $sz_MB ] &&
8933                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
8934
8935         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
8936         $LFS setstripe -c -1 $file || error "setstripe failed"
8937
8938         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
8939         echo Cancel LRU locks on lustre client to flush the client cache
8940         cancel_lru_locks osc
8941
8942         echo Disable read-ahead
8943         local old_READAHEAD=$(set_read_ahead 0)
8944
8945         echo Reading the test file $file with read-ahead disabled
8946         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8947
8948         echo Cancel LRU locks on lustre client to flush the client cache
8949         cancel_lru_locks osc
8950         echo Enable read-ahead with ${ra_MB}MB
8951         set_read_ahead $ra_MB
8952
8953         echo Reading the test file $file with read-ahead enabled
8954         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8955
8956         echo "read-ahead disabled time read $raOFF"
8957         echo "read-ahead enabled  time read $raON"
8958
8959         set_read_ahead $old_READAHEAD
8960         rm -f $file
8961         wait_delete_completed
8962
8963         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
8964                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
8965 }
8966 run_test 101d "file read with and without read-ahead enabled"
8967
8968 test_101e() {
8969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8970
8971         local file=$DIR/$tfile
8972         local size_KB=500  #KB
8973         local count=100
8974         local bsize=1024
8975
8976         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8977         local need_KB=$((count * size_KB))
8978         [[ $free_KB -le $need_KB ]] &&
8979                 skip_env "Need free space $need_KB, have $free_KB"
8980
8981         echo "Creating $count ${size_KB}K test files"
8982         for ((i = 0; i < $count; i++)); do
8983                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8984         done
8985
8986         echo "Cancel LRU locks on lustre client to flush the client cache"
8987         cancel_lru_locks $OSC
8988
8989         echo "Reset readahead stats"
8990         $LCTL set_param -n llite.*.read_ahead_stats 0
8991
8992         for ((i = 0; i < $count; i++)); do
8993                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8994         done
8995
8996         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8997                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8998
8999         for ((i = 0; i < $count; i++)); do
9000                 rm -rf $file.$i 2>/dev/null
9001         done
9002
9003         #10000 means 20% reads are missing in readahead
9004         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9005 }
9006 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9007
9008 test_101f() {
9009         which iozone || skip_env "no iozone installed"
9010
9011         local old_debug=$($LCTL get_param debug)
9012         old_debug=${old_debug#*=}
9013         $LCTL set_param debug="reada mmap"
9014
9015         # create a test file
9016         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9017
9018         echo Cancel LRU locks on lustre client to flush the client cache
9019         cancel_lru_locks osc
9020
9021         echo Reset readahead stats
9022         $LCTL set_param -n llite.*.read_ahead_stats 0
9023
9024         echo mmap read the file with small block size
9025         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9026                 > /dev/null 2>&1
9027
9028         echo checking missing pages
9029         $LCTL get_param llite.*.read_ahead_stats
9030         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9031                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9032
9033         $LCTL set_param debug="$old_debug"
9034         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9035         rm -f $DIR/$tfile
9036 }
9037 run_test 101f "check mmap read performance"
9038
9039 test_101g_brw_size_test() {
9040         local mb=$1
9041         local pages=$((mb * 1048576 / PAGE_SIZE))
9042         local file=$DIR/$tfile
9043
9044         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9045                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9046         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9047                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9048                         return 2
9049         done
9050
9051         stack_trap "rm -f $file" EXIT
9052         $LCTL set_param -n osc.*.rpc_stats=0
9053
9054         # 10 RPCs should be enough for the test
9055         local count=10
9056         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9057                 { error "dd write ${mb} MB blocks failed"; return 3; }
9058         cancel_lru_locks osc
9059         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9060                 { error "dd write ${mb} MB blocks failed"; return 4; }
9061
9062         # calculate number of full-sized read and write RPCs
9063         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9064                 sed -n '/pages per rpc/,/^$/p' |
9065                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9066                 END { print reads,writes }'))
9067         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
9068                 return 5
9069         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
9070                 return 6
9071
9072         return 0
9073 }
9074
9075 test_101g() {
9076         remote_ost_nodsh && skip "remote OST with nodsh"
9077
9078         local rpcs
9079         local osts=$(get_facets OST)
9080         local list=$(comma_list $(osts_nodes))
9081         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9082         local brw_size="obdfilter.*.brw_size"
9083
9084         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9085
9086         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9087
9088         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9089                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9090                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9091            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9092                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9093                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9094
9095                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9096                         suffix="M"
9097
9098                 if [[ $orig_mb -lt 16 ]]; then
9099                         save_lustre_params $osts "$brw_size" > $p
9100                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9101                                 error "set 16MB RPC size failed"
9102
9103                         echo "remount client to enable new RPC size"
9104                         remount_client $MOUNT || error "remount_client failed"
9105                 fi
9106
9107                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9108                 # should be able to set brw_size=12, but no rpc_stats for that
9109                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9110         fi
9111
9112         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9113
9114         if [[ $orig_mb -lt 16 ]]; then
9115                 restore_lustre_params < $p
9116                 remount_client $MOUNT || error "remount_client restore failed"
9117         fi
9118
9119         rm -f $p $DIR/$tfile
9120 }
9121 run_test 101g "Big bulk(4/16 MiB) readahead"
9122
9123 test_101h() {
9124         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9125
9126         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9127                 error "dd 70M file failed"
9128         echo Cancel LRU locks on lustre client to flush the client cache
9129         cancel_lru_locks osc
9130
9131         echo "Reset readahead stats"
9132         $LCTL set_param -n llite.*.read_ahead_stats 0
9133
9134         echo "Read 10M of data but cross 64M bundary"
9135         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9136         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9137                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9138         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9139         rm -f $p $DIR/$tfile
9140 }
9141 run_test 101h "Readahead should cover current read window"
9142
9143 setup_test102() {
9144         test_mkdir $DIR/$tdir
9145         chown $RUNAS_ID $DIR/$tdir
9146         STRIPE_SIZE=65536
9147         STRIPE_OFFSET=1
9148         STRIPE_COUNT=$OSTCOUNT
9149         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9150
9151         trap cleanup_test102 EXIT
9152         cd $DIR
9153         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9154         cd $DIR/$tdir
9155         for num in 1 2 3 4; do
9156                 for count in $(seq 1 $STRIPE_COUNT); do
9157                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9158                                 local size=`expr $STRIPE_SIZE \* $num`
9159                                 local file=file"$num-$idx-$count"
9160                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9161                         done
9162                 done
9163         done
9164
9165         cd $DIR
9166         $1 tar cf $TMP/f102.tar $tdir --xattrs
9167 }
9168
9169 cleanup_test102() {
9170         trap 0
9171         rm -f $TMP/f102.tar
9172         rm -rf $DIR/d0.sanity/d102
9173 }
9174
9175 test_102a() {
9176         [ "$UID" != 0 ] && skip "must run as root"
9177         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9178                 skip_env "must have user_xattr"
9179
9180         [ -z "$(which setfattr 2>/dev/null)" ] &&
9181                 skip_env "could not find setfattr"
9182
9183         local testfile=$DIR/$tfile
9184
9185         touch $testfile
9186         echo "set/get xattr..."
9187         setfattr -n trusted.name1 -v value1 $testfile ||
9188                 error "setfattr -n trusted.name1=value1 $testfile failed"
9189         getfattr -n trusted.name1 $testfile 2> /dev/null |
9190           grep "trusted.name1=.value1" ||
9191                 error "$testfile missing trusted.name1=value1"
9192
9193         setfattr -n user.author1 -v author1 $testfile ||
9194                 error "setfattr -n user.author1=author1 $testfile failed"
9195         getfattr -n user.author1 $testfile 2> /dev/null |
9196           grep "user.author1=.author1" ||
9197                 error "$testfile missing trusted.author1=author1"
9198
9199         echo "listxattr..."
9200         setfattr -n trusted.name2 -v value2 $testfile ||
9201                 error "$testfile unable to set trusted.name2"
9202         setfattr -n trusted.name3 -v value3 $testfile ||
9203                 error "$testfile unable to set trusted.name3"
9204         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9205             grep "trusted.name" | wc -l) -eq 3 ] ||
9206                 error "$testfile missing 3 trusted.name xattrs"
9207
9208         setfattr -n user.author2 -v author2 $testfile ||
9209                 error "$testfile unable to set user.author2"
9210         setfattr -n user.author3 -v author3 $testfile ||
9211                 error "$testfile unable to set user.author3"
9212         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9213             grep "user.author" | wc -l) -eq 3 ] ||
9214                 error "$testfile missing 3 user.author xattrs"
9215
9216         echo "remove xattr..."
9217         setfattr -x trusted.name1 $testfile ||
9218                 error "$testfile error deleting trusted.name1"
9219         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9220                 error "$testfile did not delete trusted.name1 xattr"
9221
9222         setfattr -x user.author1 $testfile ||
9223                 error "$testfile error deleting user.author1"
9224         echo "set lustre special xattr ..."
9225         $LFS setstripe -c1 $testfile
9226         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9227                 awk -F "=" '/trusted.lov/ { print $2 }' )
9228         setfattr -n "trusted.lov" -v $lovea $testfile ||
9229                 error "$testfile doesn't ignore setting trusted.lov again"
9230         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9231                 error "$testfile allow setting invalid trusted.lov"
9232         rm -f $testfile
9233 }
9234 run_test 102a "user xattr test =================================="
9235
9236 test_102b() {
9237         [ -z "$(which setfattr 2>/dev/null)" ] &&
9238                 skip_env "could not find setfattr"
9239         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9240
9241         # b10930: get/set/list trusted.lov xattr
9242         echo "get/set/list trusted.lov xattr ..."
9243         local testfile=$DIR/$tfile
9244         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9245                 error "setstripe failed"
9246         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
9247                 error "getstripe failed"
9248         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
9249                 error "can't get trusted.lov from $testfile"
9250
9251         local testfile2=${testfile}2
9252         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
9253                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
9254
9255         $MCREATE $testfile2
9256         setfattr -n trusted.lov -v $value $testfile2
9257         local stripe_size=$($LFS getstripe -S $testfile2)
9258         local stripe_count=$($LFS getstripe -c $testfile2)
9259         [[ $stripe_size -eq 65536 ]] ||
9260                 error "stripe size $stripe_size != 65536"
9261         [[ $stripe_count -eq $STRIPECOUNT ]] ||
9262                 error "stripe count $stripe_count != $STRIPECOUNT"
9263         rm -f $DIR/$tfile
9264 }
9265 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
9266
9267 test_102c() {
9268         [ -z "$(which setfattr 2>/dev/null)" ] &&
9269                 skip_env "could not find setfattr"
9270         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9271
9272         # b10930: get/set/list lustre.lov xattr
9273         echo "get/set/list lustre.lov xattr ..."
9274         test_mkdir $DIR/$tdir
9275         chown $RUNAS_ID $DIR/$tdir
9276         local testfile=$DIR/$tdir/$tfile
9277         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9278                 error "setstripe failed"
9279         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9280                 error "getstripe failed"
9281         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9282         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9283
9284         local testfile2=${testfile}2
9285         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9286                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9287
9288         $RUNAS $MCREATE $testfile2
9289         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9290         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9291         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9292         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9293         [ $stripe_count -eq $STRIPECOUNT ] ||
9294                 error "stripe count $stripe_count != $STRIPECOUNT"
9295 }
9296 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9297
9298 compare_stripe_info1() {
9299         local stripe_index_all_zero=true
9300
9301         for num in 1 2 3 4; do
9302                 for count in $(seq 1 $STRIPE_COUNT); do
9303                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9304                                 local size=$((STRIPE_SIZE * num))
9305                                 local file=file"$num-$offset-$count"
9306                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9307                                 [[ $stripe_size -ne $size ]] &&
9308                                     error "$file: size $stripe_size != $size"
9309                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9310                                 # allow fewer stripes to be created, ORI-601
9311                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9312                                     error "$file: count $stripe_count != $count"
9313                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9314                                 [[ $stripe_index -ne 0 ]] &&
9315                                         stripe_index_all_zero=false
9316                         done
9317                 done
9318         done
9319         $stripe_index_all_zero &&
9320                 error "all files are being extracted starting from OST index 0"
9321         return 0
9322 }
9323
9324 have_xattrs_include() {
9325         tar --help | grep -q xattrs-include &&
9326                 echo --xattrs-include="lustre.*"
9327 }
9328
9329 test_102d() {
9330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9331         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9332
9333         XINC=$(have_xattrs_include)
9334         setup_test102
9335         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9336         cd $DIR/$tdir/$tdir
9337         compare_stripe_info1
9338 }
9339 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9340
9341 test_102f() {
9342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9343         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9344
9345         XINC=$(have_xattrs_include)
9346         setup_test102
9347         test_mkdir $DIR/$tdir.restore
9348         cd $DIR
9349         tar cf - --xattrs $tdir | tar xf - \
9350                 -C $DIR/$tdir.restore --xattrs $XINC
9351         cd $DIR/$tdir.restore/$tdir
9352         compare_stripe_info1
9353 }
9354 run_test 102f "tar copy files, not keep osts"
9355
9356 grow_xattr() {
9357         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9358                 skip "must have user_xattr"
9359         [ -z "$(which setfattr 2>/dev/null)" ] &&
9360                 skip_env "could not find setfattr"
9361         [ -z "$(which getfattr 2>/dev/null)" ] &&
9362                 skip_env "could not find getfattr"
9363
9364         local xsize=${1:-1024}  # in bytes
9365         local file=$DIR/$tfile
9366         local value="$(generate_string $xsize)"
9367         local xbig=trusted.big
9368         local toobig=$2
9369
9370         touch $file
9371         log "save $xbig on $file"
9372         if [ -z "$toobig" ]
9373         then
9374                 setfattr -n $xbig -v $value $file ||
9375                         error "saving $xbig on $file failed"
9376         else
9377                 setfattr -n $xbig -v $value $file &&
9378                         error "saving $xbig on $file succeeded"
9379                 return 0
9380         fi
9381
9382         local orig=$(get_xattr_value $xbig $file)
9383         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9384
9385         local xsml=trusted.sml
9386         log "save $xsml on $file"
9387         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9388
9389         local new=$(get_xattr_value $xbig $file)
9390         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9391
9392         log "grow $xsml on $file"
9393         setfattr -n $xsml -v "$value" $file ||
9394                 error "growing $xsml on $file failed"
9395
9396         new=$(get_xattr_value $xbig $file)
9397         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9398         log "$xbig still valid after growing $xsml"
9399
9400         rm -f $file
9401 }
9402
9403 test_102h() { # bug 15777
9404         grow_xattr 1024
9405 }
9406 run_test 102h "grow xattr from inside inode to external block"
9407
9408 test_102ha() {
9409         large_xattr_enabled || skip_env "ea_inode feature disabled"
9410
9411         echo "setting xattr of max xattr size: $(max_xattr_size)"
9412         grow_xattr $(max_xattr_size)
9413
9414         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9415         echo "This should fail:"
9416         grow_xattr $(($(max_xattr_size) + 10)) 1
9417 }
9418 run_test 102ha "grow xattr from inside inode to external inode"
9419
9420 test_102i() { # bug 17038
9421         [ -z "$(which getfattr 2>/dev/null)" ] &&
9422                 skip "could not find getfattr"
9423
9424         touch $DIR/$tfile
9425         ln -s $DIR/$tfile $DIR/${tfile}link
9426         getfattr -n trusted.lov $DIR/$tfile ||
9427                 error "lgetxattr on $DIR/$tfile failed"
9428         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9429                 grep -i "no such attr" ||
9430                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9431         rm -f $DIR/$tfile $DIR/${tfile}link
9432 }
9433 run_test 102i "lgetxattr test on symbolic link ============"
9434
9435 test_102j() {
9436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9437         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9438
9439         XINC=$(have_xattrs_include)
9440         setup_test102 "$RUNAS"
9441         chown $RUNAS_ID $DIR/$tdir
9442         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9443         cd $DIR/$tdir/$tdir
9444         compare_stripe_info1 "$RUNAS"
9445 }
9446 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9447
9448 test_102k() {
9449         [ -z "$(which setfattr 2>/dev/null)" ] &&
9450                 skip "could not find setfattr"
9451
9452         touch $DIR/$tfile
9453         # b22187 just check that does not crash for regular file.
9454         setfattr -n trusted.lov $DIR/$tfile
9455         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9456         local test_kdir=$DIR/$tdir
9457         test_mkdir $test_kdir
9458         local default_size=$($LFS getstripe -S $test_kdir)
9459         local default_count=$($LFS getstripe -c $test_kdir)
9460         local default_offset=$($LFS getstripe -i $test_kdir)
9461         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
9462                 error 'dir setstripe failed'
9463         setfattr -n trusted.lov $test_kdir
9464         local stripe_size=$($LFS getstripe -S $test_kdir)
9465         local stripe_count=$($LFS getstripe -c $test_kdir)
9466         local stripe_offset=$($LFS getstripe -i $test_kdir)
9467         [ $stripe_size -eq $default_size ] ||
9468                 error "stripe size $stripe_size != $default_size"
9469         [ $stripe_count -eq $default_count ] ||
9470                 error "stripe count $stripe_count != $default_count"
9471         [ $stripe_offset -eq $default_offset ] ||
9472                 error "stripe offset $stripe_offset != $default_offset"
9473         rm -rf $DIR/$tfile $test_kdir
9474 }
9475 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
9476
9477 test_102l() {
9478         [ -z "$(which getfattr 2>/dev/null)" ] &&
9479                 skip "could not find getfattr"
9480
9481         # LU-532 trusted. xattr is invisible to non-root
9482         local testfile=$DIR/$tfile
9483
9484         touch $testfile
9485
9486         echo "listxattr as user..."
9487         chown $RUNAS_ID $testfile
9488         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
9489             grep -q "trusted" &&
9490                 error "$testfile trusted xattrs are user visible"
9491
9492         return 0;
9493 }
9494 run_test 102l "listxattr size test =================================="
9495
9496 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
9497         local path=$DIR/$tfile
9498         touch $path
9499
9500         listxattr_size_check $path || error "listattr_size_check $path failed"
9501 }
9502 run_test 102m "Ensure listxattr fails on small bufffer ========"
9503
9504 cleanup_test102
9505
9506 getxattr() { # getxattr path name
9507         # Return the base64 encoding of the value of xattr name on path.
9508         local path=$1
9509         local name=$2
9510
9511         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
9512         # file: $path
9513         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9514         #
9515         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9516
9517         getfattr --absolute-names --encoding=base64 --name=$name $path |
9518                 awk -F= -v name=$name '$1 == name {
9519                         print substr($0, index($0, "=") + 1);
9520         }'
9521 }
9522
9523 test_102n() { # LU-4101 mdt: protect internal xattrs
9524         [ -z "$(which setfattr 2>/dev/null)" ] &&
9525                 skip "could not find setfattr"
9526         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
9527         then
9528                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
9529         fi
9530
9531         local file0=$DIR/$tfile.0
9532         local file1=$DIR/$tfile.1
9533         local xattr0=$TMP/$tfile.0
9534         local xattr1=$TMP/$tfile.1
9535         local namelist="lov lma lmv link fid version som hsm"
9536         local name
9537         local value
9538
9539         rm -rf $file0 $file1 $xattr0 $xattr1
9540         touch $file0 $file1
9541
9542         # Get 'before' xattrs of $file1.
9543         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9544
9545         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9546                 namelist+=" lfsck_namespace"
9547         for name in $namelist; do
9548                 # Try to copy xattr from $file0 to $file1.
9549                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9550
9551                 setfattr --name=trusted.$name --value="$value" $file1 ||
9552                         error "setxattr 'trusted.$name' failed"
9553
9554                 # Try to set a garbage xattr.
9555                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9556
9557                 if [[ x$name == "xlov" ]]; then
9558                         setfattr --name=trusted.lov --value="$value" $file1 &&
9559                         error "setxattr invalid 'trusted.lov' success"
9560                 else
9561                         setfattr --name=trusted.$name --value="$value" $file1 ||
9562                                 error "setxattr invalid 'trusted.$name' failed"
9563                 fi
9564
9565                 # Try to remove the xattr from $file1. We don't care if this
9566                 # appears to succeed or fail, we just don't want there to be
9567                 # any changes or crashes.
9568                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9569         done
9570
9571         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9572         then
9573                 name="lfsck_ns"
9574                 # Try to copy xattr from $file0 to $file1.
9575                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9576
9577                 setfattr --name=trusted.$name --value="$value" $file1 ||
9578                         error "setxattr 'trusted.$name' failed"
9579
9580                 # Try to set a garbage xattr.
9581                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9582
9583                 setfattr --name=trusted.$name --value="$value" $file1 ||
9584                         error "setxattr 'trusted.$name' failed"
9585
9586                 # Try to remove the xattr from $file1. We don't care if this
9587                 # appears to succeed or fail, we just don't want there to be
9588                 # any changes or crashes.
9589                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9590         fi
9591
9592         # Get 'after' xattrs of file1.
9593         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9594
9595         if ! diff $xattr0 $xattr1; then
9596                 error "before and after xattrs of '$file1' differ"
9597         fi
9598
9599         rm -rf $file0 $file1 $xattr0 $xattr1
9600
9601         return 0
9602 }
9603 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9604
9605 test_102p() { # LU-4703 setxattr did not check ownership
9606         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9607                 skip "MDS needs to be at least 2.5.56"
9608
9609         local testfile=$DIR/$tfile
9610
9611         touch $testfile
9612
9613         echo "setfacl as user..."
9614         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9615         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9616
9617         echo "setfattr as user..."
9618         setfacl -m "u:$RUNAS_ID:---" $testfile
9619         $RUNAS setfattr -x system.posix_acl_access $testfile
9620         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9621 }
9622 run_test 102p "check setxattr(2) correctly fails without permission"
9623
9624 test_102q() {
9625         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9626                 skip "MDS needs to be at least 2.6.92"
9627
9628         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9629 }
9630 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9631
9632 test_102r() {
9633         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9634                 skip "MDS needs to be at least 2.6.93"
9635
9636         touch $DIR/$tfile || error "touch"
9637         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9638         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9639         rm $DIR/$tfile || error "rm"
9640
9641         #normal directory
9642         mkdir -p $DIR/$tdir || error "mkdir"
9643         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9644         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9645         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9646                 error "$testfile error deleting user.author1"
9647         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9648                 grep "user.$(basename $tdir)" &&
9649                 error "$tdir did not delete user.$(basename $tdir)"
9650         rmdir $DIR/$tdir || error "rmdir"
9651
9652         #striped directory
9653         test_mkdir $DIR/$tdir
9654         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9655         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9656         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9657                 error "$testfile error deleting user.author1"
9658         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9659                 grep "user.$(basename $tdir)" &&
9660                 error "$tdir did not delete user.$(basename $tdir)"
9661         rmdir $DIR/$tdir || error "rm striped dir"
9662 }
9663 run_test 102r "set EAs with empty values"
9664
9665 test_102s() {
9666         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9667                 skip "MDS needs to be at least 2.11.52"
9668
9669         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9670
9671         save_lustre_params client "llite.*.xattr_cache" > $save
9672
9673         for cache in 0 1; do
9674                 lctl set_param llite.*.xattr_cache=$cache
9675
9676                 rm -f $DIR/$tfile
9677                 touch $DIR/$tfile || error "touch"
9678                 for prefix in lustre security system trusted user; do
9679                         # Note getxattr() may fail with 'Operation not
9680                         # supported' or 'No such attribute' depending
9681                         # on prefix and cache.
9682                         getfattr -n $prefix.n102s $DIR/$tfile &&
9683                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9684                 done
9685         done
9686
9687         restore_lustre_params < $save
9688 }
9689 run_test 102s "getting nonexistent xattrs should fail"
9690
9691 test_102t() {
9692         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9693                 skip "MDS needs to be at least 2.11.52"
9694
9695         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9696
9697         save_lustre_params client "llite.*.xattr_cache" > $save
9698
9699         for cache in 0 1; do
9700                 lctl set_param llite.*.xattr_cache=$cache
9701
9702                 for buf_size in 0 256; do
9703                         rm -f $DIR/$tfile
9704                         touch $DIR/$tfile || error "touch"
9705                         setfattr -n user.multiop $DIR/$tfile
9706                         $MULTIOP $DIR/$tfile oa$buf_size ||
9707                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9708                 done
9709         done
9710
9711         restore_lustre_params < $save
9712 }
9713 run_test 102t "zero length xattr values handled correctly"
9714
9715 run_acl_subtest()
9716 {
9717     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9718     return $?
9719 }
9720
9721 test_103a() {
9722         [ "$UID" != 0 ] && skip "must run as root"
9723         $GSS && skip_env "could not run under gss"
9724         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9725                 skip_env "must have acl enabled"
9726         [ -z "$(which setfacl 2>/dev/null)" ] &&
9727                 skip_env "could not find setfacl"
9728         remote_mds_nodsh && skip "remote MDS with nodsh"
9729
9730         gpasswd -a daemon bin                           # LU-5641
9731         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
9732
9733         declare -a identity_old
9734
9735         for num in $(seq $MDSCOUNT); do
9736                 switch_identity $num true || identity_old[$num]=$?
9737         done
9738
9739         SAVE_UMASK=$(umask)
9740         umask 0022
9741         mkdir -p $DIR/$tdir
9742         cd $DIR/$tdir
9743
9744         echo "performing cp ..."
9745         run_acl_subtest cp || error "run_acl_subtest cp failed"
9746         echo "performing getfacl-noacl..."
9747         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
9748         echo "performing misc..."
9749         run_acl_subtest misc || error  "misc test failed"
9750         echo "performing permissions..."
9751         run_acl_subtest permissions || error "permissions failed"
9752         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
9753         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
9754                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
9755                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
9756         then
9757                 echo "performing permissions xattr..."
9758                 run_acl_subtest permissions_xattr ||
9759                         error "permissions_xattr failed"
9760         fi
9761         echo "performing setfacl..."
9762         run_acl_subtest setfacl || error  "setfacl test failed"
9763
9764         # inheritance test got from HP
9765         echo "performing inheritance..."
9766         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
9767         chmod +x make-tree || error "chmod +x failed"
9768         run_acl_subtest inheritance || error "inheritance test failed"
9769         rm -f make-tree
9770
9771         echo "LU-974 ignore umask when acl is enabled..."
9772         run_acl_subtest 974 || error "LU-974 umask test failed"
9773         if [ $MDSCOUNT -ge 2 ]; then
9774                 run_acl_subtest 974_remote ||
9775                         error "LU-974 umask test failed under remote dir"
9776         fi
9777
9778         echo "LU-2561 newly created file is same size as directory..."
9779         if [ "$mds1_FSTYPE" != "zfs" ]; then
9780                 run_acl_subtest 2561 || error "LU-2561 test failed"
9781         else
9782                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
9783         fi
9784
9785         run_acl_subtest 4924 || error "LU-4924 test failed"
9786
9787         cd $SAVE_PWD
9788         umask $SAVE_UMASK
9789
9790         for num in $(seq $MDSCOUNT); do
9791                 if [ "${identity_old[$num]}" = 1 ]; then
9792                         switch_identity $num false || identity_old[$num]=$?
9793                 fi
9794         done
9795 }
9796 run_test 103a "acl test"
9797
9798 test_103b() {
9799         declare -a pids
9800         local U
9801
9802         for U in {0..511}; do
9803                 {
9804                 local O=$(printf "%04o" $U)
9805
9806                 umask $(printf "%04o" $((511 ^ $O)))
9807                 $LFS setstripe -c 1 $DIR/$tfile.s$O
9808                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
9809
9810                 (( $S == ($O & 0666) )) ||
9811                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
9812
9813                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
9814                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
9815                 (( $S == ($O & 0666) )) ||
9816                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
9817
9818                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
9819                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
9820                 (( $S == ($O & 0666) )) ||
9821                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
9822                 rm -f $DIR/$tfile.[smp]$0
9823                 } &
9824                 local pid=$!
9825
9826                 # limit the concurrently running threads to 64. LU-11878
9827                 local idx=$((U % 64))
9828                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
9829                 pids[idx]=$pid
9830         done
9831         wait
9832 }
9833 run_test 103b "umask lfs setstripe"
9834
9835 test_103c() {
9836         mkdir -p $DIR/$tdir
9837         cp -rp $DIR/$tdir $DIR/$tdir.bak
9838
9839         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
9840                 error "$DIR/$tdir shouldn't contain default ACL"
9841         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
9842                 error "$DIR/$tdir.bak shouldn't contain default ACL"
9843         true
9844 }
9845 run_test 103c "'cp -rp' won't set empty acl"
9846
9847 test_104a() {
9848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9849
9850         touch $DIR/$tfile
9851         lfs df || error "lfs df failed"
9852         lfs df -ih || error "lfs df -ih failed"
9853         lfs df -h $DIR || error "lfs df -h $DIR failed"
9854         lfs df -i $DIR || error "lfs df -i $DIR failed"
9855         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
9856         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
9857
9858         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
9859         lctl --device %$OSC deactivate
9860         lfs df || error "lfs df with deactivated OSC failed"
9861         lctl --device %$OSC activate
9862         # wait the osc back to normal
9863         wait_osc_import_ready client ost
9864
9865         lfs df || error "lfs df with reactivated OSC failed"
9866         rm -f $DIR/$tfile
9867 }
9868 run_test 104a "lfs df [-ih] [path] test ========================="
9869
9870 test_104b() {
9871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9872         [ $RUNAS_ID -eq $UID ] &&
9873                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9874
9875         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
9876                         grep "Permission denied" | wc -l)))
9877         if [ $denied_cnt -ne 0 ]; then
9878                 error "lfs check servers test failed"
9879         fi
9880 }
9881 run_test 104b "$RUNAS lfs check servers test ===================="
9882
9883 test_105a() {
9884         # doesn't work on 2.4 kernels
9885         touch $DIR/$tfile
9886         if $(flock_is_enabled); then
9887                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
9888         else
9889                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
9890         fi
9891         rm -f $DIR/$tfile
9892 }
9893 run_test 105a "flock when mounted without -o flock test ========"
9894
9895 test_105b() {
9896         touch $DIR/$tfile
9897         if $(flock_is_enabled); then
9898                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
9899         else
9900                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
9901         fi
9902         rm -f $DIR/$tfile
9903 }
9904 run_test 105b "fcntl when mounted without -o flock test ========"
9905
9906 test_105c() {
9907         touch $DIR/$tfile
9908         if $(flock_is_enabled); then
9909                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
9910         else
9911                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
9912         fi
9913         rm -f $DIR/$tfile
9914 }
9915 run_test 105c "lockf when mounted without -o flock test"
9916
9917 test_105d() { # bug 15924
9918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9919
9920         test_mkdir $DIR/$tdir
9921         flock_is_enabled || skip_env "mount w/o flock enabled"
9922         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
9923         $LCTL set_param fail_loc=0x80000315
9924         flocks_test 2 $DIR/$tdir
9925 }
9926 run_test 105d "flock race (should not freeze) ========"
9927
9928 test_105e() { # bug 22660 && 22040
9929         flock_is_enabled || skip_env "mount w/o flock enabled"
9930
9931         touch $DIR/$tfile
9932         flocks_test 3 $DIR/$tfile
9933 }
9934 run_test 105e "Two conflicting flocks from same process"
9935
9936 test_106() { #bug 10921
9937         test_mkdir $DIR/$tdir
9938         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
9939         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
9940 }
9941 run_test 106 "attempt exec of dir followed by chown of that dir"
9942
9943 test_107() {
9944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9945
9946         CDIR=`pwd`
9947         local file=core
9948
9949         cd $DIR
9950         rm -f $file
9951
9952         local save_pattern=$(sysctl -n kernel.core_pattern)
9953         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
9954         sysctl -w kernel.core_pattern=$file
9955         sysctl -w kernel.core_uses_pid=0
9956
9957         ulimit -c unlimited
9958         sleep 60 &
9959         SLEEPPID=$!
9960
9961         sleep 1
9962
9963         kill -s 11 $SLEEPPID
9964         wait $SLEEPPID
9965         if [ -e $file ]; then
9966                 size=`stat -c%s $file`
9967                 [ $size -eq 0 ] && error "Fail to create core file $file"
9968         else
9969                 error "Fail to create core file $file"
9970         fi
9971         rm -f $file
9972         sysctl -w kernel.core_pattern=$save_pattern
9973         sysctl -w kernel.core_uses_pid=$save_uses_pid
9974         cd $CDIR
9975 }
9976 run_test 107 "Coredump on SIG"
9977
9978 test_110() {
9979         test_mkdir $DIR/$tdir
9980         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
9981         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
9982                 error "mkdir with 256 char should fail, but did not"
9983         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
9984                 error "create with 255 char failed"
9985         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
9986                 error "create with 256 char should fail, but did not"
9987
9988         ls -l $DIR/$tdir
9989         rm -rf $DIR/$tdir
9990 }
9991 run_test 110 "filename length checking"
9992
9993 #
9994 # Purpose: To verify dynamic thread (OSS) creation.
9995 #
9996 test_115() {
9997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9998         remote_ost_nodsh && skip "remote OST with nodsh"
9999
10000         # Lustre does not stop service threads once they are started.
10001         # Reset number of running threads to default.
10002         stopall
10003         setupall
10004
10005         local OSTIO_pre
10006         local save_params="$TMP/sanity-$TESTNAME.parameters"
10007
10008         # Get ll_ost_io count before I/O
10009         OSTIO_pre=$(do_facet ost1 \
10010                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10011         # Exit if lustre is not running (ll_ost_io not running).
10012         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10013
10014         echo "Starting with $OSTIO_pre threads"
10015         local thread_max=$((OSTIO_pre * 2))
10016         local rpc_in_flight=$((thread_max * 2))
10017         # Number of I/O Process proposed to be started.
10018         local nfiles
10019         local facets=$(get_facets OST)
10020
10021         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10022         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10023
10024         # Set in_flight to $rpc_in_flight
10025         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10026                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10027         nfiles=${rpc_in_flight}
10028         # Set ost thread_max to $thread_max
10029         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10030
10031         # 5 Minutes should be sufficient for max number of OSS
10032         # threads(thread_max) to be created.
10033         local timeout=300
10034
10035         # Start I/O.
10036         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10037         test_mkdir $DIR/$tdir
10038         for i in $(seq $nfiles); do
10039                 local file=$DIR/$tdir/${tfile}-$i
10040                 $LFS setstripe -c -1 -i 0 $file
10041                 ($WTL $file $timeout)&
10042         done
10043
10044         # I/O Started - Wait for thread_started to reach thread_max or report
10045         # error if thread_started is more than thread_max.
10046         echo "Waiting for thread_started to reach thread_max"
10047         local thread_started=0
10048         local end_time=$((SECONDS + timeout))
10049
10050         while [ $SECONDS -le $end_time ] ; do
10051                 echo -n "."
10052                 # Get ost i/o thread_started count.
10053                 thread_started=$(do_facet ost1 \
10054                         "$LCTL get_param \
10055                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10056                 # Break out if thread_started is equal/greater than thread_max
10057                 if [[ $thread_started -ge $thread_max ]]; then
10058                         echo ll_ost_io thread_started $thread_started, \
10059                                 equal/greater than thread_max $thread_max
10060                         break
10061                 fi
10062                 sleep 1
10063         done
10064
10065         # Cleanup - We have the numbers, Kill i/o jobs if running.
10066         jobcount=($(jobs -p))
10067         for i in $(seq 0 $((${#jobcount[@]}-1)))
10068         do
10069                 kill -9 ${jobcount[$i]}
10070                 if [ $? -ne 0 ] ; then
10071                         echo Warning: \
10072                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10073                 fi
10074         done
10075
10076         # Cleanup files left by WTL binary.
10077         for i in $(seq $nfiles); do
10078                 local file=$DIR/$tdir/${tfile}-$i
10079                 rm -rf $file
10080                 if [ $? -ne 0 ] ; then
10081                         echo "Warning: Failed to delete file $file"
10082                 fi
10083         done
10084
10085         restore_lustre_params <$save_params
10086         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10087
10088         # Error out if no new thread has started or Thread started is greater
10089         # than thread max.
10090         if [[ $thread_started -le $OSTIO_pre ||
10091                         $thread_started -gt $thread_max ]]; then
10092                 error "ll_ost_io: thread_started $thread_started" \
10093                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10094                       "No new thread started or thread started greater " \
10095                       "than thread_max."
10096         fi
10097 }
10098 run_test 115 "verify dynamic thread creation===================="
10099
10100 free_min_max () {
10101         wait_delete_completed
10102         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10103         echo "OST kbytes available: ${AVAIL[@]}"
10104         MAXV=${AVAIL[0]}
10105         MAXI=0
10106         MINV=${AVAIL[0]}
10107         MINI=0
10108         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10109                 #echo OST $i: ${AVAIL[i]}kb
10110                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10111                         MAXV=${AVAIL[i]}
10112                         MAXI=$i
10113                 fi
10114                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10115                         MINV=${AVAIL[i]}
10116                         MINI=$i
10117                 fi
10118         done
10119         echo "Min free space: OST $MINI: $MINV"
10120         echo "Max free space: OST $MAXI: $MAXV"
10121 }
10122
10123 test_116a() { # was previously test_116()
10124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10125         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10126         remote_mds_nodsh && skip "remote MDS with nodsh"
10127
10128         echo -n "Free space priority "
10129         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10130                 head -n1
10131         declare -a AVAIL
10132         free_min_max
10133
10134         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10135         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10136         trap simple_cleanup_common EXIT
10137
10138         # Check if we need to generate uneven OSTs
10139         test_mkdir -p $DIR/$tdir/OST${MINI}
10140         local FILL=$((MINV / 4))
10141         local DIFF=$((MAXV - MINV))
10142         local DIFF2=$((DIFF * 100 / MINV))
10143
10144         local threshold=$(do_facet $SINGLEMDS \
10145                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10146         threshold=${threshold%%%}
10147         echo -n "Check for uneven OSTs: "
10148         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10149
10150         if [[ $DIFF2 -gt $threshold ]]; then
10151                 echo "ok"
10152                 echo "Don't need to fill OST$MINI"
10153         else
10154                 # generate uneven OSTs. Write 2% over the QOS threshold value
10155                 echo "no"
10156                 DIFF=$((threshold - DIFF2 + 2))
10157                 DIFF2=$((MINV * DIFF / 100))
10158                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10159                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10160                         error "setstripe failed"
10161                 DIFF=$((DIFF2 / 2048))
10162                 i=0
10163                 while [ $i -lt $DIFF ]; do
10164                         i=$((i + 1))
10165                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10166                                 bs=2M count=1 2>/dev/null
10167                         echo -n .
10168                 done
10169                 echo .
10170                 sync
10171                 sleep_maxage
10172                 free_min_max
10173         fi
10174
10175         DIFF=$((MAXV - MINV))
10176         DIFF2=$((DIFF * 100 / MINV))
10177         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10178         if [ $DIFF2 -gt $threshold ]; then
10179                 echo "ok"
10180         else
10181                 echo "failed - QOS mode won't be used"
10182                 simple_cleanup_common
10183                 skip "QOS imbalance criteria not met"
10184         fi
10185
10186         MINI1=$MINI
10187         MINV1=$MINV
10188         MAXI1=$MAXI
10189         MAXV1=$MAXV
10190
10191         # now fill using QOS
10192         $LFS setstripe -c 1 $DIR/$tdir
10193         FILL=$((FILL / 200))
10194         if [ $FILL -gt 600 ]; then
10195                 FILL=600
10196         fi
10197         echo "writing $FILL files to QOS-assigned OSTs"
10198         i=0
10199         while [ $i -lt $FILL ]; do
10200                 i=$((i + 1))
10201                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10202                         count=1 2>/dev/null
10203                 echo -n .
10204         done
10205         echo "wrote $i 200k files"
10206         sync
10207         sleep_maxage
10208
10209         echo "Note: free space may not be updated, so measurements might be off"
10210         free_min_max
10211         DIFF2=$((MAXV - MINV))
10212         echo "free space delta: orig $DIFF final $DIFF2"
10213         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10214         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10215         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10216         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10217         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10218         if [[ $DIFF -gt 0 ]]; then
10219                 FILL=$((DIFF2 * 100 / DIFF - 100))
10220                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10221         fi
10222
10223         # Figure out which files were written where
10224         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10225                awk '/'$MINI1': / {print $2; exit}')
10226         echo $UUID
10227         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10228         echo "$MINC files created on smaller OST $MINI1"
10229         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10230                awk '/'$MAXI1': / {print $2; exit}')
10231         echo $UUID
10232         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10233         echo "$MAXC files created on larger OST $MAXI1"
10234         if [[ $MINC -gt 0 ]]; then
10235                 FILL=$((MAXC * 100 / MINC - 100))
10236                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10237         fi
10238         [[ $MAXC -gt $MINC ]] ||
10239                 error_ignore LU-9 "stripe QOS didn't balance free space"
10240         simple_cleanup_common
10241 }
10242 run_test 116a "stripe QOS: free space balance ==================="
10243
10244 test_116b() { # LU-2093
10245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10246         remote_mds_nodsh && skip "remote MDS with nodsh"
10247
10248 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10249         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10250                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10251         [ -z "$old_rr" ] && skip "no QOS"
10252         do_facet $SINGLEMDS lctl set_param \
10253                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10254         mkdir -p $DIR/$tdir
10255         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10256         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10257         do_facet $SINGLEMDS lctl set_param fail_loc=0
10258         rm -rf $DIR/$tdir
10259         do_facet $SINGLEMDS lctl set_param \
10260                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10261 }
10262 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10263
10264 test_117() # bug 10891
10265 {
10266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10267
10268         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10269         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10270         lctl set_param fail_loc=0x21e
10271         > $DIR/$tfile || error "truncate failed"
10272         lctl set_param fail_loc=0
10273         echo "Truncate succeeded."
10274         rm -f $DIR/$tfile
10275 }
10276 run_test 117 "verify osd extend =========="
10277
10278 NO_SLOW_RESENDCOUNT=4
10279 export OLD_RESENDCOUNT=""
10280 set_resend_count () {
10281         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10282         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10283         lctl set_param -n $PROC_RESENDCOUNT $1
10284         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10285 }
10286
10287 # for reduce test_118* time (b=14842)
10288 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10289
10290 # Reset async IO behavior after error case
10291 reset_async() {
10292         FILE=$DIR/reset_async
10293
10294         # Ensure all OSCs are cleared
10295         $LFS setstripe -c -1 $FILE
10296         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10297         sync
10298         rm $FILE
10299 }
10300
10301 test_118a() #bug 11710
10302 {
10303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10304
10305         reset_async
10306
10307         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10308         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10309         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10310
10311         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10312                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10313                 return 1;
10314         fi
10315         rm -f $DIR/$tfile
10316 }
10317 run_test 118a "verify O_SYNC works =========="
10318
10319 test_118b()
10320 {
10321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10322         remote_ost_nodsh && skip "remote OST with nodsh"
10323
10324         reset_async
10325
10326         #define OBD_FAIL_SRV_ENOENT 0x217
10327         set_nodes_failloc "$(osts_nodes)" 0x217
10328         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10329         RC=$?
10330         set_nodes_failloc "$(osts_nodes)" 0
10331         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10332         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10333                     grep -c writeback)
10334
10335         if [[ $RC -eq 0 ]]; then
10336                 error "Must return error due to dropped pages, rc=$RC"
10337                 return 1;
10338         fi
10339
10340         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10341                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10342                 return 1;
10343         fi
10344
10345         echo "Dirty pages not leaked on ENOENT"
10346
10347         # Due to the above error the OSC will issue all RPCs syncronously
10348         # until a subsequent RPC completes successfully without error.
10349         $MULTIOP $DIR/$tfile Ow4096yc
10350         rm -f $DIR/$tfile
10351
10352         return 0
10353 }
10354 run_test 118b "Reclaim dirty pages on fatal error =========="
10355
10356 test_118c()
10357 {
10358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10359
10360         # for 118c, restore the original resend count, LU-1940
10361         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10362                                 set_resend_count $OLD_RESENDCOUNT
10363         remote_ost_nodsh && skip "remote OST with nodsh"
10364
10365         reset_async
10366
10367         #define OBD_FAIL_OST_EROFS               0x216
10368         set_nodes_failloc "$(osts_nodes)" 0x216
10369
10370         # multiop should block due to fsync until pages are written
10371         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10372         MULTIPID=$!
10373         sleep 1
10374
10375         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10376                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10377         fi
10378
10379         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10380                     grep -c writeback)
10381         if [[ $WRITEBACK -eq 0 ]]; then
10382                 error "No page in writeback, writeback=$WRITEBACK"
10383         fi
10384
10385         set_nodes_failloc "$(osts_nodes)" 0
10386         wait $MULTIPID
10387         RC=$?
10388         if [[ $RC -ne 0 ]]; then
10389                 error "Multiop fsync failed, rc=$RC"
10390         fi
10391
10392         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10393         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10394                     grep -c writeback)
10395         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10396                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10397         fi
10398
10399         rm -f $DIR/$tfile
10400         echo "Dirty pages flushed via fsync on EROFS"
10401         return 0
10402 }
10403 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10404
10405 # continue to use small resend count to reduce test_118* time (b=14842)
10406 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10407
10408 test_118d()
10409 {
10410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10411         remote_ost_nodsh && skip "remote OST with nodsh"
10412
10413         reset_async
10414
10415         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10416         set_nodes_failloc "$(osts_nodes)" 0x214
10417         # multiop should block due to fsync until pages are written
10418         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10419         MULTIPID=$!
10420         sleep 1
10421
10422         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10423                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10424         fi
10425
10426         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10427                     grep -c writeback)
10428         if [[ $WRITEBACK -eq 0 ]]; then
10429                 error "No page in writeback, writeback=$WRITEBACK"
10430         fi
10431
10432         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10433         set_nodes_failloc "$(osts_nodes)" 0
10434
10435         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10436         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10437                     grep -c writeback)
10438         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10439                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10440         fi
10441
10442         rm -f $DIR/$tfile
10443         echo "Dirty pages gaurenteed flushed via fsync"
10444         return 0
10445 }
10446 run_test 118d "Fsync validation inject a delay of the bulk =========="
10447
10448 test_118f() {
10449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10450
10451         reset_async
10452
10453         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10454         lctl set_param fail_loc=0x8000040a
10455
10456         # Should simulate EINVAL error which is fatal
10457         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10458         RC=$?
10459         if [[ $RC -eq 0 ]]; then
10460                 error "Must return error due to dropped pages, rc=$RC"
10461         fi
10462
10463         lctl set_param fail_loc=0x0
10464
10465         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10466         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10467         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10468                     grep -c writeback)
10469         if [[ $LOCKED -ne 0 ]]; then
10470                 error "Locked pages remain in cache, locked=$LOCKED"
10471         fi
10472
10473         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10474                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10475         fi
10476
10477         rm -f $DIR/$tfile
10478         echo "No pages locked after fsync"
10479
10480         reset_async
10481         return 0
10482 }
10483 run_test 118f "Simulate unrecoverable OSC side error =========="
10484
10485 test_118g() {
10486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10487
10488         reset_async
10489
10490         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
10491         lctl set_param fail_loc=0x406
10492
10493         # simulate local -ENOMEM
10494         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10495         RC=$?
10496
10497         lctl set_param fail_loc=0
10498         if [[ $RC -eq 0 ]]; then
10499                 error "Must return error due to dropped pages, rc=$RC"
10500         fi
10501
10502         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10503         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10504         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10505                         grep -c writeback)
10506         if [[ $LOCKED -ne 0 ]]; then
10507                 error "Locked pages remain in cache, locked=$LOCKED"
10508         fi
10509
10510         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10511                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10512         fi
10513
10514         rm -f $DIR/$tfile
10515         echo "No pages locked after fsync"
10516
10517         reset_async
10518         return 0
10519 }
10520 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
10521
10522 test_118h() {
10523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10524         remote_ost_nodsh && skip "remote OST with nodsh"
10525
10526         reset_async
10527
10528         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10529         set_nodes_failloc "$(osts_nodes)" 0x20e
10530         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10531         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10532         RC=$?
10533
10534         set_nodes_failloc "$(osts_nodes)" 0
10535         if [[ $RC -eq 0 ]]; then
10536                 error "Must return error due to dropped pages, rc=$RC"
10537         fi
10538
10539         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10540         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10541         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10542                     grep -c writeback)
10543         if [[ $LOCKED -ne 0 ]]; then
10544                 error "Locked pages remain in cache, locked=$LOCKED"
10545         fi
10546
10547         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10548                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10549         fi
10550
10551         rm -f $DIR/$tfile
10552         echo "No pages locked after fsync"
10553
10554         return 0
10555 }
10556 run_test 118h "Verify timeout in handling recoverables errors  =========="
10557
10558 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10559
10560 test_118i() {
10561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10562         remote_ost_nodsh && skip "remote OST with nodsh"
10563
10564         reset_async
10565
10566         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10567         set_nodes_failloc "$(osts_nodes)" 0x20e
10568
10569         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10570         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10571         PID=$!
10572         sleep 5
10573         set_nodes_failloc "$(osts_nodes)" 0
10574
10575         wait $PID
10576         RC=$?
10577         if [[ $RC -ne 0 ]]; then
10578                 error "got error, but should be not, rc=$RC"
10579         fi
10580
10581         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10582         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10583         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10584         if [[ $LOCKED -ne 0 ]]; then
10585                 error "Locked pages remain in cache, locked=$LOCKED"
10586         fi
10587
10588         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10589                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10590         fi
10591
10592         rm -f $DIR/$tfile
10593         echo "No pages locked after fsync"
10594
10595         return 0
10596 }
10597 run_test 118i "Fix error before timeout in recoverable error  =========="
10598
10599 [ "$SLOW" = "no" ] && set_resend_count 4
10600
10601 test_118j() {
10602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10603         remote_ost_nodsh && skip "remote OST with nodsh"
10604
10605         reset_async
10606
10607         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10608         set_nodes_failloc "$(osts_nodes)" 0x220
10609
10610         # return -EIO from OST
10611         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10612         RC=$?
10613         set_nodes_failloc "$(osts_nodes)" 0x0
10614         if [[ $RC -eq 0 ]]; then
10615                 error "Must return error due to dropped pages, rc=$RC"
10616         fi
10617
10618         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10619         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10620         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10621         if [[ $LOCKED -ne 0 ]]; then
10622                 error "Locked pages remain in cache, locked=$LOCKED"
10623         fi
10624
10625         # in recoverable error on OST we want resend and stay until it finished
10626         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10627                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10628         fi
10629
10630         rm -f $DIR/$tfile
10631         echo "No pages locked after fsync"
10632
10633         return 0
10634 }
10635 run_test 118j "Simulate unrecoverable OST side error =========="
10636
10637 test_118k()
10638 {
10639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10640         remote_ost_nodsh && skip "remote OSTs with nodsh"
10641
10642         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10643         set_nodes_failloc "$(osts_nodes)" 0x20e
10644         test_mkdir $DIR/$tdir
10645
10646         for ((i=0;i<10;i++)); do
10647                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10648                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10649                 SLEEPPID=$!
10650                 sleep 0.500s
10651                 kill $SLEEPPID
10652                 wait $SLEEPPID
10653         done
10654
10655         set_nodes_failloc "$(osts_nodes)" 0
10656         rm -rf $DIR/$tdir
10657 }
10658 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10659
10660 test_118l() # LU-646
10661 {
10662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10663
10664         test_mkdir $DIR/$tdir
10665         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10666         rm -rf $DIR/$tdir
10667 }
10668 run_test 118l "fsync dir"
10669
10670 test_118m() # LU-3066
10671 {
10672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10673
10674         test_mkdir $DIR/$tdir
10675         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10676         rm -rf $DIR/$tdir
10677 }
10678 run_test 118m "fdatasync dir ========="
10679
10680 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10681
10682 test_118n()
10683 {
10684         local begin
10685         local end
10686
10687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10688         remote_ost_nodsh && skip "remote OSTs with nodsh"
10689
10690         # Sleep to avoid a cached response.
10691         #define OBD_STATFS_CACHE_SECONDS 1
10692         sleep 2
10693
10694         # Inject a 10 second delay in the OST_STATFS handler.
10695         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10696         set_nodes_failloc "$(osts_nodes)" 0x242
10697
10698         begin=$SECONDS
10699         stat --file-system $MOUNT > /dev/null
10700         end=$SECONDS
10701
10702         set_nodes_failloc "$(osts_nodes)" 0
10703
10704         if ((end - begin > 20)); then
10705             error "statfs took $((end - begin)) seconds, expected 10"
10706         fi
10707 }
10708 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10709
10710 test_119a() # bug 11737
10711 {
10712         BSIZE=$((512 * 1024))
10713         directio write $DIR/$tfile 0 1 $BSIZE
10714         # We ask to read two blocks, which is more than a file size.
10715         # directio will indicate an error when requested and actual
10716         # sizes aren't equeal (a normal situation in this case) and
10717         # print actual read amount.
10718         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10719         if [ "$NOB" != "$BSIZE" ]; then
10720                 error "read $NOB bytes instead of $BSIZE"
10721         fi
10722         rm -f $DIR/$tfile
10723 }
10724 run_test 119a "Short directIO read must return actual read amount"
10725
10726 test_119b() # bug 11737
10727 {
10728         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10729
10730         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
10731         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
10732         sync
10733         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
10734                 error "direct read failed"
10735         rm -f $DIR/$tfile
10736 }
10737 run_test 119b "Sparse directIO read must return actual read amount"
10738
10739 test_119c() # bug 13099
10740 {
10741         BSIZE=1048576
10742         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
10743         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
10744         rm -f $DIR/$tfile
10745 }
10746 run_test 119c "Testing for direct read hitting hole"
10747
10748 test_119d() # bug 15950
10749 {
10750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10751
10752         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
10753         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
10754         BSIZE=1048576
10755         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
10756         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
10757         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
10758         lctl set_param fail_loc=0x40d
10759         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
10760         pid_dio=$!
10761         sleep 1
10762         cat $DIR/$tfile > /dev/null &
10763         lctl set_param fail_loc=0
10764         pid_reads=$!
10765         wait $pid_dio
10766         log "the DIO writes have completed, now wait for the reads (should not block very long)"
10767         sleep 2
10768         [ -n "`ps h -p $pid_reads -o comm`" ] && \
10769         error "the read rpcs have not completed in 2s"
10770         rm -f $DIR/$tfile
10771         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
10772 }
10773 run_test 119d "The DIO path should try to send a new rpc once one is completed"
10774
10775 test_120a() {
10776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10777         remote_mds_nodsh && skip "remote MDS with nodsh"
10778         test_mkdir -i0 -c1 $DIR/$tdir
10779         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10780                 skip_env "no early lock cancel on server"
10781
10782         lru_resize_disable mdc
10783         lru_resize_disable osc
10784         cancel_lru_locks mdc
10785         # asynchronous object destroy at MDT could cause bl ast to client
10786         cancel_lru_locks osc
10787
10788         stat $DIR/$tdir > /dev/null
10789         can1=$(do_facet mds1 \
10790                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10791                awk '/ldlm_cancel/ {print $2}')
10792         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10793                awk '/ldlm_bl_callback/ {print $2}')
10794         test_mkdir -i0 -c1 $DIR/$tdir/d1
10795         can2=$(do_facet mds1 \
10796                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10797                awk '/ldlm_cancel/ {print $2}')
10798         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10799                awk '/ldlm_bl_callback/ {print $2}')
10800         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10801         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10802         lru_resize_enable mdc
10803         lru_resize_enable osc
10804 }
10805 run_test 120a "Early Lock Cancel: mkdir test"
10806
10807 test_120b() {
10808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10809         remote_mds_nodsh && skip "remote MDS with nodsh"
10810         test_mkdir $DIR/$tdir
10811         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10812                 skip_env "no early lock cancel on server"
10813
10814         lru_resize_disable mdc
10815         lru_resize_disable osc
10816         cancel_lru_locks mdc
10817         stat $DIR/$tdir > /dev/null
10818         can1=$(do_facet $SINGLEMDS \
10819                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10820                awk '/ldlm_cancel/ {print $2}')
10821         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10822                awk '/ldlm_bl_callback/ {print $2}')
10823         touch $DIR/$tdir/f1
10824         can2=$(do_facet $SINGLEMDS \
10825                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10826                awk '/ldlm_cancel/ {print $2}')
10827         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10828                awk '/ldlm_bl_callback/ {print $2}')
10829         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10830         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10831         lru_resize_enable mdc
10832         lru_resize_enable osc
10833 }
10834 run_test 120b "Early Lock Cancel: create test"
10835
10836 test_120c() {
10837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10838         remote_mds_nodsh && skip "remote MDS with nodsh"
10839         test_mkdir -i0 -c1 $DIR/$tdir
10840         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10841                 skip "no early lock cancel on server"
10842
10843         lru_resize_disable mdc
10844         lru_resize_disable osc
10845         test_mkdir -i0 -c1 $DIR/$tdir/d1
10846         test_mkdir -i0 -c1 $DIR/$tdir/d2
10847         touch $DIR/$tdir/d1/f1
10848         cancel_lru_locks mdc
10849         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
10850         can1=$(do_facet mds1 \
10851                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10852                awk '/ldlm_cancel/ {print $2}')
10853         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10854                awk '/ldlm_bl_callback/ {print $2}')
10855         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10856         can2=$(do_facet mds1 \
10857                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10858                awk '/ldlm_cancel/ {print $2}')
10859         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10860                awk '/ldlm_bl_callback/ {print $2}')
10861         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10862         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10863         lru_resize_enable mdc
10864         lru_resize_enable osc
10865 }
10866 run_test 120c "Early Lock Cancel: link test"
10867
10868 test_120d() {
10869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10870         remote_mds_nodsh && skip "remote MDS with nodsh"
10871         test_mkdir -i0 -c1 $DIR/$tdir
10872         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10873                 skip_env "no early lock cancel on server"
10874
10875         lru_resize_disable mdc
10876         lru_resize_disable osc
10877         touch $DIR/$tdir
10878         cancel_lru_locks mdc
10879         stat $DIR/$tdir > /dev/null
10880         can1=$(do_facet mds1 \
10881                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10882                awk '/ldlm_cancel/ {print $2}')
10883         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10884                awk '/ldlm_bl_callback/ {print $2}')
10885         chmod a+x $DIR/$tdir
10886         can2=$(do_facet mds1 \
10887                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10888                awk '/ldlm_cancel/ {print $2}')
10889         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10890                awk '/ldlm_bl_callback/ {print $2}')
10891         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10892         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10893         lru_resize_enable mdc
10894         lru_resize_enable osc
10895 }
10896 run_test 120d "Early Lock Cancel: setattr test"
10897
10898 test_120e() {
10899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10900         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10901                 skip_env "no early lock cancel on server"
10902         remote_mds_nodsh && skip "remote MDS with nodsh"
10903
10904         local dlmtrace_set=false
10905
10906         test_mkdir -i0 -c1 $DIR/$tdir
10907         lru_resize_disable mdc
10908         lru_resize_disable osc
10909         ! $LCTL get_param debug | grep -q dlmtrace &&
10910                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
10911         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
10912         cancel_lru_locks mdc
10913         cancel_lru_locks osc
10914         dd if=$DIR/$tdir/f1 of=/dev/null
10915         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
10916         # XXX client can not do early lock cancel of OST lock
10917         # during unlink (LU-4206), so cancel osc lock now.
10918         sleep 2
10919         cancel_lru_locks osc
10920         can1=$(do_facet mds1 \
10921                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10922                awk '/ldlm_cancel/ {print $2}')
10923         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10924                awk '/ldlm_bl_callback/ {print $2}')
10925         unlink $DIR/$tdir/f1
10926         sleep 5
10927         can2=$(do_facet mds1 \
10928                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10929                awk '/ldlm_cancel/ {print $2}')
10930         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10931                awk '/ldlm_bl_callback/ {print $2}')
10932         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
10933                 $LCTL dk $TMP/cancel.debug.txt
10934         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
10935                 $LCTL dk $TMP/blocking.debug.txt
10936         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
10937         lru_resize_enable mdc
10938         lru_resize_enable osc
10939 }
10940 run_test 120e "Early Lock Cancel: unlink test"
10941
10942 test_120f() {
10943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10944         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10945                 skip_env "no early lock cancel on server"
10946         remote_mds_nodsh && skip "remote MDS with nodsh"
10947
10948         test_mkdir -i0 -c1 $DIR/$tdir
10949         lru_resize_disable mdc
10950         lru_resize_disable osc
10951         test_mkdir -i0 -c1 $DIR/$tdir/d1
10952         test_mkdir -i0 -c1 $DIR/$tdir/d2
10953         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
10954         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
10955         cancel_lru_locks mdc
10956         cancel_lru_locks osc
10957         dd if=$DIR/$tdir/d1/f1 of=/dev/null
10958         dd if=$DIR/$tdir/d2/f2 of=/dev/null
10959         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
10960         # XXX client can not do early lock cancel of OST lock
10961         # during rename (LU-4206), so cancel osc lock now.
10962         sleep 2
10963         cancel_lru_locks osc
10964         can1=$(do_facet mds1 \
10965                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10966                awk '/ldlm_cancel/ {print $2}')
10967         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10968                awk '/ldlm_bl_callback/ {print $2}')
10969         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10970         sleep 5
10971         can2=$(do_facet mds1 \
10972                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10973                awk '/ldlm_cancel/ {print $2}')
10974         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10975                awk '/ldlm_bl_callback/ {print $2}')
10976         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10977         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10978         lru_resize_enable mdc
10979         lru_resize_enable osc
10980 }
10981 run_test 120f "Early Lock Cancel: rename test"
10982
10983 test_120g() {
10984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10985         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10986                 skip_env "no early lock cancel on server"
10987         remote_mds_nodsh && skip "remote MDS with nodsh"
10988
10989         lru_resize_disable mdc
10990         lru_resize_disable osc
10991         count=10000
10992         echo create $count files
10993         test_mkdir $DIR/$tdir
10994         cancel_lru_locks mdc
10995         cancel_lru_locks osc
10996         t0=$(date +%s)
10997
10998         can0=$(do_facet $SINGLEMDS \
10999                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11000                awk '/ldlm_cancel/ {print $2}')
11001         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11002                awk '/ldlm_bl_callback/ {print $2}')
11003         createmany -o $DIR/$tdir/f $count
11004         sync
11005         can1=$(do_facet $SINGLEMDS \
11006                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11007                awk '/ldlm_cancel/ {print $2}')
11008         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11009                awk '/ldlm_bl_callback/ {print $2}')
11010         t1=$(date +%s)
11011         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11012         echo rm $count files
11013         rm -r $DIR/$tdir
11014         sync
11015         can2=$(do_facet $SINGLEMDS \
11016                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11017                awk '/ldlm_cancel/ {print $2}')
11018         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11019                awk '/ldlm_bl_callback/ {print $2}')
11020         t2=$(date +%s)
11021         echo total: $count removes in $((t2-t1))
11022         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11023         sleep 2
11024         # wait for commitment of removal
11025         lru_resize_enable mdc
11026         lru_resize_enable osc
11027 }
11028 run_test 120g "Early Lock Cancel: performance test"
11029
11030 test_121() { #bug #10589
11031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11032
11033         rm -rf $DIR/$tfile
11034         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11035 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11036         lctl set_param fail_loc=0x310
11037         cancel_lru_locks osc > /dev/null
11038         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11039         lctl set_param fail_loc=0
11040         [[ $reads -eq $writes ]] ||
11041                 error "read $reads blocks, must be $writes blocks"
11042 }
11043 run_test 121 "read cancel race ========="
11044
11045 test_123a() { # was test 123, statahead(bug 11401)
11046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11047
11048         SLOWOK=0
11049         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11050                 log "testing UP system. Performance may be lower than expected."
11051                 SLOWOK=1
11052         fi
11053
11054         rm -rf $DIR/$tdir
11055         test_mkdir $DIR/$tdir
11056         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11057         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11058         MULT=10
11059         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11060                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11061
11062                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
11063                 lctl set_param -n llite.*.statahead_max 0
11064                 lctl get_param llite.*.statahead_max
11065                 cancel_lru_locks mdc
11066                 cancel_lru_locks osc
11067                 stime=`date +%s`
11068                 time ls -l $DIR/$tdir | wc -l
11069                 etime=`date +%s`
11070                 delta=$((etime - stime))
11071                 log "ls $i files without statahead: $delta sec"
11072                 lctl set_param llite.*.statahead_max=$max
11073
11074                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
11075                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11076                 cancel_lru_locks mdc
11077                 cancel_lru_locks osc
11078                 stime=`date +%s`
11079                 time ls -l $DIR/$tdir | wc -l
11080                 etime=`date +%s`
11081                 delta_sa=$((etime - stime))
11082                 log "ls $i files with statahead: $delta_sa sec"
11083                 lctl get_param -n llite.*.statahead_stats
11084                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
11085
11086                 [[ $swrong -lt $ewrong ]] &&
11087                         log "statahead was stopped, maybe too many locks held!"
11088                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11089
11090                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11091                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
11092                     lctl set_param -n llite.*.statahead_max 0
11093                     lctl get_param llite.*.statahead_max
11094                     cancel_lru_locks mdc
11095                     cancel_lru_locks osc
11096                     stime=`date +%s`
11097                     time ls -l $DIR/$tdir | wc -l
11098                     etime=`date +%s`
11099                     delta=$((etime - stime))
11100                     log "ls $i files again without statahead: $delta sec"
11101                     lctl set_param llite.*.statahead_max=$max
11102                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11103                         if [  $SLOWOK -eq 0 ]; then
11104                                 error "ls $i files is slower with statahead!"
11105                         else
11106                                 log "ls $i files is slower with statahead!"
11107                         fi
11108                         break
11109                     fi
11110                 fi
11111
11112                 [ $delta -gt 20 ] && break
11113                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11114                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11115         done
11116         log "ls done"
11117
11118         stime=`date +%s`
11119         rm -r $DIR/$tdir
11120         sync
11121         etime=`date +%s`
11122         delta=$((etime - stime))
11123         log "rm -r $DIR/$tdir/: $delta seconds"
11124         log "rm done"
11125         lctl get_param -n llite.*.statahead_stats
11126 }
11127 run_test 123a "verify statahead work"
11128
11129 test_123b () { # statahead(bug 15027)
11130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11131
11132         test_mkdir $DIR/$tdir
11133         createmany -o $DIR/$tdir/$tfile-%d 1000
11134
11135         cancel_lru_locks mdc
11136         cancel_lru_locks osc
11137
11138 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11139         lctl set_param fail_loc=0x80000803
11140         ls -lR $DIR/$tdir > /dev/null
11141         log "ls done"
11142         lctl set_param fail_loc=0x0
11143         lctl get_param -n llite.*.statahead_stats
11144         rm -r $DIR/$tdir
11145         sync
11146
11147 }
11148 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11149
11150 test_124a() {
11151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11152         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11153                 skip_env "no lru resize on server"
11154
11155         local NR=2000
11156
11157         test_mkdir $DIR/$tdir
11158
11159         log "create $NR files at $DIR/$tdir"
11160         createmany -o $DIR/$tdir/f $NR ||
11161                 error "failed to create $NR files in $DIR/$tdir"
11162
11163         cancel_lru_locks mdc
11164         ls -l $DIR/$tdir > /dev/null
11165
11166         local NSDIR=""
11167         local LRU_SIZE=0
11168         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11169                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11170                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11171                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11172                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11173                         log "NSDIR=$NSDIR"
11174                         log "NS=$(basename $NSDIR)"
11175                         break
11176                 fi
11177         done
11178
11179         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11180                 skip "Not enough cached locks created!"
11181         fi
11182         log "LRU=$LRU_SIZE"
11183
11184         local SLEEP=30
11185
11186         # We know that lru resize allows one client to hold $LIMIT locks
11187         # for 10h. After that locks begin to be killed by client.
11188         local MAX_HRS=10
11189         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11190         log "LIMIT=$LIMIT"
11191         if [ $LIMIT -lt $LRU_SIZE ]; then
11192                 skip "Limit is too small $LIMIT"
11193         fi
11194
11195         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11196         # killing locks. Some time was spent for creating locks. This means
11197         # that up to the moment of sleep finish we must have killed some of
11198         # them (10-100 locks). This depends on how fast ther were created.
11199         # Many of them were touched in almost the same moment and thus will
11200         # be killed in groups.
11201         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11202
11203         # Use $LRU_SIZE_B here to take into account real number of locks
11204         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11205         local LRU_SIZE_B=$LRU_SIZE
11206         log "LVF=$LVF"
11207         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11208         log "OLD_LVF=$OLD_LVF"
11209         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11210
11211         # Let's make sure that we really have some margin. Client checks
11212         # cached locks every 10 sec.
11213         SLEEP=$((SLEEP+20))
11214         log "Sleep ${SLEEP} sec"
11215         local SEC=0
11216         while ((SEC<$SLEEP)); do
11217                 echo -n "..."
11218                 sleep 5
11219                 SEC=$((SEC+5))
11220                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11221                 echo -n "$LRU_SIZE"
11222         done
11223         echo ""
11224         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11225         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11226
11227         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11228                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11229                 unlinkmany $DIR/$tdir/f $NR
11230                 return
11231         }
11232
11233         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11234         log "unlink $NR files at $DIR/$tdir"
11235         unlinkmany $DIR/$tdir/f $NR
11236 }
11237 run_test 124a "lru resize ======================================="
11238
11239 get_max_pool_limit()
11240 {
11241         local limit=$($LCTL get_param \
11242                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11243         local max=0
11244         for l in $limit; do
11245                 if [[ $l -gt $max ]]; then
11246                         max=$l
11247                 fi
11248         done
11249         echo $max
11250 }
11251
11252 test_124b() {
11253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11254         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11255                 skip_env "no lru resize on server"
11256
11257         LIMIT=$(get_max_pool_limit)
11258
11259         NR=$(($(default_lru_size)*20))
11260         if [[ $NR -gt $LIMIT ]]; then
11261                 log "Limit lock number by $LIMIT locks"
11262                 NR=$LIMIT
11263         fi
11264
11265         IFree=$(mdsrate_inodes_available)
11266         if [ $IFree -lt $NR ]; then
11267                 log "Limit lock number by $IFree inodes"
11268                 NR=$IFree
11269         fi
11270
11271         lru_resize_disable mdc
11272         test_mkdir -p $DIR/$tdir/disable_lru_resize
11273
11274         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11275         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11276         cancel_lru_locks mdc
11277         stime=`date +%s`
11278         PID=""
11279         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11280         PID="$PID $!"
11281         sleep 2
11282         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11283         PID="$PID $!"
11284         sleep 2
11285         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11286         PID="$PID $!"
11287         wait $PID
11288         etime=`date +%s`
11289         nolruresize_delta=$((etime-stime))
11290         log "ls -la time: $nolruresize_delta seconds"
11291         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11292         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11293
11294         lru_resize_enable mdc
11295         test_mkdir -p $DIR/$tdir/enable_lru_resize
11296
11297         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11298         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11299         cancel_lru_locks mdc
11300         stime=`date +%s`
11301         PID=""
11302         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11303         PID="$PID $!"
11304         sleep 2
11305         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11306         PID="$PID $!"
11307         sleep 2
11308         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11309         PID="$PID $!"
11310         wait $PID
11311         etime=`date +%s`
11312         lruresize_delta=$((etime-stime))
11313         log "ls -la time: $lruresize_delta seconds"
11314         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11315
11316         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11317                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11318         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11319                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11320         else
11321                 log "lru resize performs the same with no lru resize"
11322         fi
11323         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11324 }
11325 run_test 124b "lru resize (performance test) ======================="
11326
11327 test_124c() {
11328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11329         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11330                 skip_env "no lru resize on server"
11331
11332         # cache ununsed locks on client
11333         local nr=100
11334         cancel_lru_locks mdc
11335         test_mkdir $DIR/$tdir
11336         createmany -o $DIR/$tdir/f $nr ||
11337                 error "failed to create $nr files in $DIR/$tdir"
11338         ls -l $DIR/$tdir > /dev/null
11339
11340         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11341         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11342         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11343         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11344         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11345
11346         # set lru_max_age to 1 sec
11347         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11348         echo "sleep $((recalc_p * 2)) seconds..."
11349         sleep $((recalc_p * 2))
11350
11351         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11352         # restore lru_max_age
11353         $LCTL set_param -n $nsdir.lru_max_age $max_age
11354         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11355         unlinkmany $DIR/$tdir/f $nr
11356 }
11357 run_test 124c "LRUR cancel very aged locks"
11358
11359 test_124d() {
11360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11361         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11362                 skip_env "no lru resize on server"
11363
11364         # cache ununsed locks on client
11365         local nr=100
11366
11367         lru_resize_disable mdc
11368         stack_trap "lru_resize_enable mdc" EXIT
11369
11370         cancel_lru_locks mdc
11371
11372         # asynchronous object destroy at MDT could cause bl ast to client
11373         test_mkdir $DIR/$tdir
11374         createmany -o $DIR/$tdir/f $nr ||
11375                 error "failed to create $nr files in $DIR/$tdir"
11376         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11377
11378         ls -l $DIR/$tdir > /dev/null
11379
11380         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11381         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11382         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11383         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11384
11385         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11386
11387         # set lru_max_age to 1 sec
11388         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11389         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
11390
11391         echo "sleep $((recalc_p * 2)) seconds..."
11392         sleep $((recalc_p * 2))
11393
11394         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11395
11396         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11397 }
11398 run_test 124d "cancel very aged locks if lru-resize diasbaled"
11399
11400 test_125() { # 13358
11401         $LCTL get_param -n llite.*.client_type | grep -q local ||
11402                 skip "must run as local client"
11403         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
11404                 skip_env "must have acl enabled"
11405         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11406
11407         test_mkdir $DIR/$tdir
11408         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
11409         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
11410         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
11411 }
11412 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
11413
11414 test_126() { # bug 12829/13455
11415         $GSS && skip_env "must run as gss disabled"
11416         $LCTL get_param -n llite.*.client_type | grep -q local ||
11417                 skip "must run as local client"
11418         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
11419
11420         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
11421         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
11422         rm -f $DIR/$tfile
11423         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
11424 }
11425 run_test 126 "check that the fsgid provided by the client is taken into account"
11426
11427 test_127a() { # bug 15521
11428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11429         local name count samp unit min max sum sumsq
11430
11431         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
11432         echo "stats before reset"
11433         $LCTL get_param osc.*.stats
11434         $LCTL set_param osc.*.stats=0
11435         local fsize=$((2048 * 1024))
11436
11437         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
11438         cancel_lru_locks osc
11439         dd if=$DIR/$tfile of=/dev/null bs=$fsize
11440
11441         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
11442         stack_trap "rm -f $TMP/$tfile.tmp"
11443         while read name count samp unit min max sum sumsq; do
11444                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
11445                 [ ! $min ] && error "Missing min value for $name proc entry"
11446                 eval $name=$count || error "Wrong proc format"
11447
11448                 case $name in
11449                 read_bytes|write_bytes)
11450                         [[ "$unit" =~ "bytes" ]] ||
11451                                 error "unit is not 'bytes': $unit"
11452                         (( $min >= 4096 )) || error "min is too small: $min"
11453                         (( $min <= $fsize )) || error "min is too big: $min"
11454                         (( $max >= 4096 )) || error "max is too small: $max"
11455                         (( $max <= $fsize )) || error "max is too big: $max"
11456                         (( $sum == $fsize )) || error "sum is wrong: $sum"
11457                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
11458                                 error "sumsquare is too small: $sumsq"
11459                         (( $sumsq <= $fsize * $fsize )) ||
11460                                 error "sumsquare is too big: $sumsq"
11461                         ;;
11462                 ost_read|ost_write)
11463                         [[ "$unit" =~ "usec" ]] ||
11464                                 error "unit is not 'usec': $unit"
11465                         ;;
11466                 *)      ;;
11467                 esac
11468         done < $DIR/$tfile.tmp
11469
11470         #check that we actually got some stats
11471         [ "$read_bytes" ] || error "Missing read_bytes stats"
11472         [ "$write_bytes" ] || error "Missing write_bytes stats"
11473         [ "$read_bytes" != 0 ] || error "no read done"
11474         [ "$write_bytes" != 0 ] || error "no write done"
11475 }
11476 run_test 127a "verify the client stats are sane"
11477
11478 test_127b() { # bug LU-333
11479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11480         local name count samp unit min max sum sumsq
11481
11482         echo "stats before reset"
11483         $LCTL get_param llite.*.stats
11484         $LCTL set_param llite.*.stats=0
11485
11486         # perform 2 reads and writes so MAX is different from SUM.
11487         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11488         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11489         cancel_lru_locks osc
11490         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11491         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11492
11493         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
11494         stack_trap "rm -f $TMP/$tfile.tmp"
11495         while read name count samp unit min max sum sumsq; do
11496                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
11497                 eval $name=$count || error "Wrong proc format"
11498
11499                 case $name in
11500                 read_bytes|write_bytes)
11501                         [[ "$unit" =~ "bytes" ]] ||
11502                                 error "unit is not 'bytes': $unit"
11503                         (( $count == 2 )) || error "count is not 2: $count"
11504                         (( $min == $PAGE_SIZE )) ||
11505                                 error "min is not $PAGE_SIZE: $min"
11506                         (( $max == $PAGE_SIZE )) ||
11507                                 error "max is not $PAGE_SIZE: $max"
11508                         (( $sum == $PAGE_SIZE * 2 )) ||
11509                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
11510                         ;;
11511                 read|write)
11512                         [[ "$unit" =~ "usec" ]] ||
11513                                 error "unit is not 'usec': $unit"
11514                         ;;
11515                 *)      ;;
11516                 esac
11517         done < $TMP/$tfile.tmp
11518
11519         #check that we actually got some stats
11520         [ "$read_bytes" ] || error "Missing read_bytes stats"
11521         [ "$write_bytes" ] || error "Missing write_bytes stats"
11522         [ "$read_bytes" != 0 ] || error "no read done"
11523         [ "$write_bytes" != 0 ] || error "no write done"
11524 }
11525 run_test 127b "verify the llite client stats are sane"
11526
11527 test_127c() { # LU-12394
11528         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11529         local size
11530         local bsize
11531         local reads
11532         local writes
11533         local count
11534
11535         $LCTL set_param llite.*.extents_stats=1
11536         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
11537
11538         # Use two stripes so there is enough space in default config
11539         $LFS setstripe -c 2 $DIR/$tfile
11540
11541         # Extent stats start at 0-4K and go in power of two buckets
11542         # LL_HIST_START = 12 --> 2^12 = 4K
11543         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
11544         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
11545         # small configs
11546         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
11547                 do
11548                 # Write and read, 2x each, second time at a non-zero offset
11549                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
11550                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
11551                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
11552                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
11553                 rm -f $DIR/$tfile
11554         done
11555
11556         $LCTL get_param llite.*.extents_stats
11557
11558         count=2
11559         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
11560                 do
11561                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
11562                                 grep -m 1 $bsize)
11563                 reads=$(echo $bucket | awk '{print $5}')
11564                 writes=$(echo $bucket | awk '{print $9}')
11565                 [ "$reads" -eq $count ] ||
11566                         error "$reads reads in < $bsize bucket, expect $count"
11567                 [ "$writes" -eq $count ] ||
11568                         error "$writes writes in < $bsize bucket, expect $count"
11569         done
11570
11571         # Test mmap write and read
11572         $LCTL set_param llite.*.extents_stats=c
11573         size=512
11574         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
11575         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
11576         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
11577
11578         $LCTL get_param llite.*.extents_stats
11579
11580         count=$(((size*1024) / PAGE_SIZE))
11581
11582         bsize=$((2 * PAGE_SIZE / 1024))K
11583
11584         bucket=$($LCTL get_param -n llite.*.extents_stats |
11585                         grep -m 1 $bsize)
11586         reads=$(echo $bucket | awk '{print $5}')
11587         writes=$(echo $bucket | awk '{print $9}')
11588         # mmap writes fault in the page first, creating an additonal read
11589         [ "$reads" -eq $((2 * count)) ] ||
11590                 error "$reads reads in < $bsize bucket, expect $count"
11591         [ "$writes" -eq $count ] ||
11592                 error "$writes writes in < $bsize bucket, expect $count"
11593 }
11594 run_test 127c "test llite extent stats with regular & mmap i/o"
11595
11596 test_128() { # bug 15212
11597         touch $DIR/$tfile
11598         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
11599                 find $DIR/$tfile
11600                 find $DIR/$tfile
11601         EOF
11602
11603         result=$(grep error $TMP/$tfile.log)
11604         rm -f $DIR/$tfile $TMP/$tfile.log
11605         [ -z "$result" ] ||
11606                 error "consecutive find's under interactive lfs failed"
11607 }
11608 run_test 128 "interactive lfs for 2 consecutive find's"
11609
11610 set_dir_limits () {
11611         local mntdev
11612         local canondev
11613         local node
11614
11615         local ldproc=/proc/fs/ldiskfs
11616         local facets=$(get_facets MDS)
11617
11618         for facet in ${facets//,/ }; do
11619                 canondev=$(ldiskfs_canon \
11620                            *.$(convert_facet2label $facet).mntdev $facet)
11621                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
11622                         ldproc=/sys/fs/ldiskfs
11623                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
11624                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
11625         done
11626 }
11627
11628 check_mds_dmesg() {
11629         local facets=$(get_facets MDS)
11630         for facet in ${facets//,/ }; do
11631                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
11632         done
11633         return 1
11634 }
11635
11636 test_129() {
11637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11638         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
11639                 skip "Need MDS version with at least 2.5.56"
11640         if [ "$mds1_FSTYPE" != ldiskfs ]; then
11641                 skip_env "ldiskfs only test"
11642         fi
11643         remote_mds_nodsh && skip "remote MDS with nodsh"
11644
11645         local ENOSPC=28
11646         local EFBIG=27
11647         local has_warning=false
11648
11649         rm -rf $DIR/$tdir
11650         mkdir -p $DIR/$tdir
11651
11652         # block size of mds1
11653         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
11654         set_dir_limits $maxsize $maxsize
11655         local dirsize=$(stat -c%s "$DIR/$tdir")
11656         local nfiles=0
11657         while [[ $dirsize -le $maxsize ]]; do
11658                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
11659                 rc=$?
11660                 if ! $has_warning; then
11661                         check_mds_dmesg '"is approaching"' && has_warning=true
11662                 fi
11663                 # check two errors:
11664                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11665                 # EFBIG for previous versions included in ldiskfs series
11666                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11667                         set_dir_limits 0 0
11668                         echo "return code $rc received as expected"
11669
11670                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11671                                 error_exit "create failed w/o dir size limit"
11672
11673                         check_mds_dmesg '"has reached"' ||
11674                                 error_exit "reached message should be output"
11675
11676                         [ $has_warning = "false" ] &&
11677                                 error_exit "warning message should be output"
11678
11679                         dirsize=$(stat -c%s "$DIR/$tdir")
11680
11681                         [[ $dirsize -ge $maxsize ]] && return 0
11682                         error_exit "current dir size $dirsize, " \
11683                                    "previous limit $maxsize"
11684                 elif [ $rc -ne 0 ]; then
11685                         set_dir_limits 0 0
11686                         error_exit "return $rc received instead of expected " \
11687                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11688                 fi
11689                 nfiles=$((nfiles + 1))
11690                 dirsize=$(stat -c%s "$DIR/$tdir")
11691         done
11692
11693         set_dir_limits 0 0
11694         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11695 }
11696 run_test 129 "test directory size limit ========================"
11697
11698 OLDIFS="$IFS"
11699 cleanup_130() {
11700         trap 0
11701         IFS="$OLDIFS"
11702 }
11703
11704 test_130a() {
11705         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11706         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11707
11708         trap cleanup_130 EXIT RETURN
11709
11710         local fm_file=$DIR/$tfile
11711         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
11712         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
11713                 error "dd failed for $fm_file"
11714
11715         # LU-1795: test filefrag/FIEMAP once, even if unsupported
11716         filefrag -ves $fm_file
11717         RC=$?
11718         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11719                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11720         [ $RC != 0 ] && error "filefrag $fm_file failed"
11721
11722         filefrag_op=$(filefrag -ve -k $fm_file |
11723                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11724         lun=$($LFS getstripe -i $fm_file)
11725
11726         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
11727         IFS=$'\n'
11728         tot_len=0
11729         for line in $filefrag_op
11730         do
11731                 frag_lun=`echo $line | cut -d: -f5`
11732                 ext_len=`echo $line | cut -d: -f4`
11733                 if (( $frag_lun != $lun )); then
11734                         cleanup_130
11735                         error "FIEMAP on 1-stripe file($fm_file) failed"
11736                         return
11737                 fi
11738                 (( tot_len += ext_len ))
11739         done
11740
11741         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
11742                 cleanup_130
11743                 error "FIEMAP on 1-stripe file($fm_file) failed;"
11744                 return
11745         fi
11746
11747         cleanup_130
11748
11749         echo "FIEMAP on single striped file succeeded"
11750 }
11751 run_test 130a "FIEMAP (1-stripe file)"
11752
11753 test_130b() {
11754         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11755
11756         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11757         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11758
11759         trap cleanup_130 EXIT RETURN
11760
11761         local fm_file=$DIR/$tfile
11762         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11763                         error "setstripe on $fm_file"
11764         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11765                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11766
11767         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
11768                 error "dd failed on $fm_file"
11769
11770         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11771         filefrag_op=$(filefrag -ve -k $fm_file |
11772                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11773
11774         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11775                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11776
11777         IFS=$'\n'
11778         tot_len=0
11779         num_luns=1
11780         for line in $filefrag_op
11781         do
11782                 frag_lun=$(echo $line | cut -d: -f5 |
11783                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11784                 ext_len=$(echo $line | cut -d: -f4)
11785                 if (( $frag_lun != $last_lun )); then
11786                         if (( tot_len != 1024 )); then
11787                                 cleanup_130
11788                                 error "FIEMAP on $fm_file failed; returned " \
11789                                 "len $tot_len for OST $last_lun instead of 1024"
11790                                 return
11791                         else
11792                                 (( num_luns += 1 ))
11793                                 tot_len=0
11794                         fi
11795                 fi
11796                 (( tot_len += ext_len ))
11797                 last_lun=$frag_lun
11798         done
11799         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
11800                 cleanup_130
11801                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11802                         "luns or wrong len for OST $last_lun"
11803                 return
11804         fi
11805
11806         cleanup_130
11807
11808         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
11809 }
11810 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
11811
11812 test_130c() {
11813         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11814
11815         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11816         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11817
11818         trap cleanup_130 EXIT RETURN
11819
11820         local fm_file=$DIR/$tfile
11821         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
11822         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11823                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11824
11825         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
11826                         error "dd failed on $fm_file"
11827
11828         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11829         filefrag_op=$(filefrag -ve -k $fm_file |
11830                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11831
11832         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11833                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11834
11835         IFS=$'\n'
11836         tot_len=0
11837         num_luns=1
11838         for line in $filefrag_op
11839         do
11840                 frag_lun=$(echo $line | cut -d: -f5 |
11841                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11842                 ext_len=$(echo $line | cut -d: -f4)
11843                 if (( $frag_lun != $last_lun )); then
11844                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
11845                         if (( logical != 512 )); then
11846                                 cleanup_130
11847                                 error "FIEMAP on $fm_file failed; returned " \
11848                                 "logical start for lun $logical instead of 512"
11849                                 return
11850                         fi
11851                         if (( tot_len != 512 )); then
11852                                 cleanup_130
11853                                 error "FIEMAP on $fm_file failed; returned " \
11854                                 "len $tot_len for OST $last_lun instead of 1024"
11855                                 return
11856                         else
11857                                 (( num_luns += 1 ))
11858                                 tot_len=0
11859                         fi
11860                 fi
11861                 (( tot_len += ext_len ))
11862                 last_lun=$frag_lun
11863         done
11864         if (( num_luns != 2 || tot_len != 512 )); then
11865                 cleanup_130
11866                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11867                         "luns or wrong len for OST $last_lun"
11868                 return
11869         fi
11870
11871         cleanup_130
11872
11873         echo "FIEMAP on 2-stripe file with hole succeeded"
11874 }
11875 run_test 130c "FIEMAP (2-stripe file with hole)"
11876
11877 test_130d() {
11878         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
11879
11880         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11881         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11882
11883         trap cleanup_130 EXIT RETURN
11884
11885         local fm_file=$DIR/$tfile
11886         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11887                         error "setstripe on $fm_file"
11888         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11889                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11890
11891         local actual_stripe_count=$($LFS getstripe -c $fm_file)
11892         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
11893                 error "dd failed on $fm_file"
11894
11895         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11896         filefrag_op=$(filefrag -ve -k $fm_file |
11897                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11898
11899         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11900                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11901
11902         IFS=$'\n'
11903         tot_len=0
11904         num_luns=1
11905         for line in $filefrag_op
11906         do
11907                 frag_lun=$(echo $line | cut -d: -f5 |
11908                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11909                 ext_len=$(echo $line | cut -d: -f4)
11910                 if (( $frag_lun != $last_lun )); then
11911                         if (( tot_len != 1024 )); then
11912                                 cleanup_130
11913                                 error "FIEMAP on $fm_file failed; returned " \
11914                                 "len $tot_len for OST $last_lun instead of 1024"
11915                                 return
11916                         else
11917                                 (( num_luns += 1 ))
11918                                 tot_len=0
11919                         fi
11920                 fi
11921                 (( tot_len += ext_len ))
11922                 last_lun=$frag_lun
11923         done
11924         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
11925                 cleanup_130
11926                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11927                         "luns or wrong len for OST $last_lun"
11928                 return
11929         fi
11930
11931         cleanup_130
11932
11933         echo "FIEMAP on N-stripe file succeeded"
11934 }
11935 run_test 130d "FIEMAP (N-stripe file)"
11936
11937 test_130e() {
11938         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11939
11940         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11941         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11942
11943         trap cleanup_130 EXIT RETURN
11944
11945         local fm_file=$DIR/$tfile
11946         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
11947         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11948                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11949
11950         NUM_BLKS=512
11951         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
11952         for ((i = 0; i < $NUM_BLKS; i++))
11953         do
11954                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
11955         done
11956
11957         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11958         filefrag_op=$(filefrag -ve -k $fm_file |
11959                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11960
11961         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11962                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11963
11964         IFS=$'\n'
11965         tot_len=0
11966         num_luns=1
11967         for line in $filefrag_op
11968         do
11969                 frag_lun=$(echo $line | cut -d: -f5 |
11970                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11971                 ext_len=$(echo $line | cut -d: -f4)
11972                 if (( $frag_lun != $last_lun )); then
11973                         if (( tot_len != $EXPECTED_LEN )); then
11974                                 cleanup_130
11975                                 error "FIEMAP on $fm_file failed; returned " \
11976                                 "len $tot_len for OST $last_lun instead " \
11977                                 "of $EXPECTED_LEN"
11978                                 return
11979                         else
11980                                 (( num_luns += 1 ))
11981                                 tot_len=0
11982                         fi
11983                 fi
11984                 (( tot_len += ext_len ))
11985                 last_lun=$frag_lun
11986         done
11987         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
11988                 cleanup_130
11989                 error "FIEMAP on $fm_file failed; returned wrong number " \
11990                         "of luns or wrong len for OST $last_lun"
11991                 return
11992         fi
11993
11994         cleanup_130
11995
11996         echo "FIEMAP with continuation calls succeeded"
11997 }
11998 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
11999
12000 test_130f() {
12001         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12002         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12003
12004         local fm_file=$DIR/$tfile
12005         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12006                 error "multiop create with lov_delay_create on $fm_file"
12007
12008         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12009         filefrag_extents=$(filefrag -vek $fm_file |
12010                            awk '/extents? found/ { print $2 }')
12011         if [[ "$filefrag_extents" != "0" ]]; then
12012                 error "FIEMAP on $fm_file failed; " \
12013                       "returned $filefrag_extents expected 0"
12014         fi
12015
12016         rm -f $fm_file
12017 }
12018 run_test 130f "FIEMAP (unstriped file)"
12019
12020 # Test for writev/readv
12021 test_131a() {
12022         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12023                 error "writev test failed"
12024         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12025                 error "readv failed"
12026         rm -f $DIR/$tfile
12027 }
12028 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12029
12030 test_131b() {
12031         local fsize=$((524288 + 1048576 + 1572864))
12032         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12033                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12034                         error "append writev test failed"
12035
12036         ((fsize += 1572864 + 1048576))
12037         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12038                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12039                         error "append writev test failed"
12040         rm -f $DIR/$tfile
12041 }
12042 run_test 131b "test append writev"
12043
12044 test_131c() {
12045         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12046         error "NOT PASS"
12047 }
12048 run_test 131c "test read/write on file w/o objects"
12049
12050 test_131d() {
12051         rwv -f $DIR/$tfile -w -n 1 1572864
12052         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12053         if [ "$NOB" != 1572864 ]; then
12054                 error "Short read filed: read $NOB bytes instead of 1572864"
12055         fi
12056         rm -f $DIR/$tfile
12057 }
12058 run_test 131d "test short read"
12059
12060 test_131e() {
12061         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12062         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12063         error "read hitting hole failed"
12064         rm -f $DIR/$tfile
12065 }
12066 run_test 131e "test read hitting hole"
12067
12068 check_stats() {
12069         local facet=$1
12070         local op=$2
12071         local want=${3:-0}
12072         local res
12073
12074         case $facet in
12075         mds*) res=$(do_facet $facet \
12076                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12077                  ;;
12078         ost*) res=$(do_facet $facet \
12079                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12080                  ;;
12081         *) error "Wrong facet '$facet'" ;;
12082         esac
12083         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12084         # if the argument $3 is zero, it means any stat increment is ok.
12085         if [[ $want -gt 0 ]]; then
12086                 local count=$(echo $res | awk '{ print $2 }')
12087                 [[ $count -ne $want ]] &&
12088                         error "The $op counter on $facet is $count, not $want"
12089         fi
12090 }
12091
12092 test_133a() {
12093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12094         remote_ost_nodsh && skip "remote OST with nodsh"
12095         remote_mds_nodsh && skip "remote MDS with nodsh"
12096         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12097                 skip_env "MDS doesn't support rename stats"
12098
12099         local testdir=$DIR/${tdir}/stats_testdir
12100
12101         mkdir -p $DIR/${tdir}
12102
12103         # clear stats.
12104         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12105         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12106
12107         # verify mdt stats first.
12108         mkdir ${testdir} || error "mkdir failed"
12109         check_stats $SINGLEMDS "mkdir" 1
12110         touch ${testdir}/${tfile} || error "touch failed"
12111         check_stats $SINGLEMDS "open" 1
12112         check_stats $SINGLEMDS "close" 1
12113         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12114                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12115                 check_stats $SINGLEMDS "mknod" 2
12116         }
12117         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12118         check_stats $SINGLEMDS "unlink" 1
12119         rm -f ${testdir}/${tfile} || error "file remove failed"
12120         check_stats $SINGLEMDS "unlink" 2
12121
12122         # remove working dir and check mdt stats again.
12123         rmdir ${testdir} || error "rmdir failed"
12124         check_stats $SINGLEMDS "rmdir" 1
12125
12126         local testdir1=$DIR/${tdir}/stats_testdir1
12127         mkdir -p ${testdir}
12128         mkdir -p ${testdir1}
12129         touch ${testdir1}/test1
12130         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12131         check_stats $SINGLEMDS "crossdir_rename" 1
12132
12133         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12134         check_stats $SINGLEMDS "samedir_rename" 1
12135
12136         rm -rf $DIR/${tdir}
12137 }
12138 run_test 133a "Verifying MDT stats ========================================"
12139
12140 test_133b() {
12141         local res
12142
12143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12144         remote_ost_nodsh && skip "remote OST with nodsh"
12145         remote_mds_nodsh && skip "remote MDS with nodsh"
12146
12147         local testdir=$DIR/${tdir}/stats_testdir
12148
12149         mkdir -p ${testdir} || error "mkdir failed"
12150         touch ${testdir}/${tfile} || error "touch failed"
12151         cancel_lru_locks mdc
12152
12153         # clear stats.
12154         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12155         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12156
12157         # extra mdt stats verification.
12158         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12159         check_stats $SINGLEMDS "setattr" 1
12160         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12161         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12162         then            # LU-1740
12163                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12164                 check_stats $SINGLEMDS "getattr" 1
12165         fi
12166         rm -rf $DIR/${tdir}
12167
12168         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12169         # so the check below is not reliable
12170         [ $MDSCOUNT -eq 1 ] || return 0
12171
12172         # Sleep to avoid a cached response.
12173         #define OBD_STATFS_CACHE_SECONDS 1
12174         sleep 2
12175         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12176         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12177         $LFS df || error "lfs failed"
12178         check_stats $SINGLEMDS "statfs" 1
12179
12180         # check aggregated statfs (LU-10018)
12181         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12182                 return 0
12183         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12184                 return 0
12185         sleep 2
12186         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12187         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12188         df $DIR
12189         check_stats $SINGLEMDS "statfs" 1
12190
12191         # We want to check that the client didn't send OST_STATFS to
12192         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12193         # extra care is needed here.
12194         if remote_mds; then
12195                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12196                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12197
12198                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12199                 [ "$res" ] && error "OST got STATFS"
12200         fi
12201
12202         return 0
12203 }
12204 run_test 133b "Verifying extra MDT stats =================================="
12205
12206 test_133c() {
12207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12208         remote_ost_nodsh && skip "remote OST with nodsh"
12209         remote_mds_nodsh && skip "remote MDS with nodsh"
12210
12211         local testdir=$DIR/$tdir/stats_testdir
12212
12213         test_mkdir -p $testdir
12214
12215         # verify obdfilter stats.
12216         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12217         sync
12218         cancel_lru_locks osc
12219         wait_delete_completed
12220
12221         # clear stats.
12222         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12223         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12224
12225         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12226                 error "dd failed"
12227         sync
12228         cancel_lru_locks osc
12229         check_stats ost1 "write" 1
12230
12231         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12232         check_stats ost1 "read" 1
12233
12234         > $testdir/$tfile || error "truncate failed"
12235         check_stats ost1 "punch" 1
12236
12237         rm -f $testdir/$tfile || error "file remove failed"
12238         wait_delete_completed
12239         check_stats ost1 "destroy" 1
12240
12241         rm -rf $DIR/$tdir
12242 }
12243 run_test 133c "Verifying OST stats ========================================"
12244
12245 order_2() {
12246         local value=$1
12247         local orig=$value
12248         local order=1
12249
12250         while [ $value -ge 2 ]; do
12251                 order=$((order*2))
12252                 value=$((value/2))
12253         done
12254
12255         if [ $orig -gt $order ]; then
12256                 order=$((order*2))
12257         fi
12258         echo $order
12259 }
12260
12261 size_in_KMGT() {
12262     local value=$1
12263     local size=('K' 'M' 'G' 'T');
12264     local i=0
12265     local size_string=$value
12266
12267     while [ $value -ge 1024 ]; do
12268         if [ $i -gt 3 ]; then
12269             #T is the biggest unit we get here, if that is bigger,
12270             #just return XXXT
12271             size_string=${value}T
12272             break
12273         fi
12274         value=$((value >> 10))
12275         if [ $value -lt 1024 ]; then
12276             size_string=${value}${size[$i]}
12277             break
12278         fi
12279         i=$((i + 1))
12280     done
12281
12282     echo $size_string
12283 }
12284
12285 get_rename_size() {
12286         local size=$1
12287         local context=${2:-.}
12288         local sample=$(do_facet $SINGLEMDS $LCTL \
12289                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12290                 grep -A1 $context |
12291                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12292         echo $sample
12293 }
12294
12295 test_133d() {
12296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12297         remote_ost_nodsh && skip "remote OST with nodsh"
12298         remote_mds_nodsh && skip "remote MDS with nodsh"
12299         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12300                 skip_env "MDS doesn't support rename stats"
12301
12302         local testdir1=$DIR/${tdir}/stats_testdir1
12303         local testdir2=$DIR/${tdir}/stats_testdir2
12304         mkdir -p $DIR/${tdir}
12305
12306         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12307
12308         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12309         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12310
12311         createmany -o $testdir1/test 512 || error "createmany failed"
12312
12313         # check samedir rename size
12314         mv ${testdir1}/test0 ${testdir1}/test_0
12315
12316         local testdir1_size=$(ls -l $DIR/${tdir} |
12317                 awk '/stats_testdir1/ {print $5}')
12318         local testdir2_size=$(ls -l $DIR/${tdir} |
12319                 awk '/stats_testdir2/ {print $5}')
12320
12321         testdir1_size=$(order_2 $testdir1_size)
12322         testdir2_size=$(order_2 $testdir2_size)
12323
12324         testdir1_size=$(size_in_KMGT $testdir1_size)
12325         testdir2_size=$(size_in_KMGT $testdir2_size)
12326
12327         echo "source rename dir size: ${testdir1_size}"
12328         echo "target rename dir size: ${testdir2_size}"
12329
12330         local cmd="do_facet $SINGLEMDS $LCTL "
12331         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12332
12333         eval $cmd || error "$cmd failed"
12334         local samedir=$($cmd | grep 'same_dir')
12335         local same_sample=$(get_rename_size $testdir1_size)
12336         [ -z "$samedir" ] && error "samedir_rename_size count error"
12337         [[ $same_sample -eq 1 ]] ||
12338                 error "samedir_rename_size error $same_sample"
12339         echo "Check same dir rename stats success"
12340
12341         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12342
12343         # check crossdir rename size
12344         mv ${testdir1}/test_0 ${testdir2}/test_0
12345
12346         testdir1_size=$(ls -l $DIR/${tdir} |
12347                 awk '/stats_testdir1/ {print $5}')
12348         testdir2_size=$(ls -l $DIR/${tdir} |
12349                 awk '/stats_testdir2/ {print $5}')
12350
12351         testdir1_size=$(order_2 $testdir1_size)
12352         testdir2_size=$(order_2 $testdir2_size)
12353
12354         testdir1_size=$(size_in_KMGT $testdir1_size)
12355         testdir2_size=$(size_in_KMGT $testdir2_size)
12356
12357         echo "source rename dir size: ${testdir1_size}"
12358         echo "target rename dir size: ${testdir2_size}"
12359
12360         eval $cmd || error "$cmd failed"
12361         local crossdir=$($cmd | grep 'crossdir')
12362         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12363         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12364         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12365         [[ $src_sample -eq 1 ]] ||
12366                 error "crossdir_rename_size error $src_sample"
12367         [[ $tgt_sample -eq 1 ]] ||
12368                 error "crossdir_rename_size error $tgt_sample"
12369         echo "Check cross dir rename stats success"
12370         rm -rf $DIR/${tdir}
12371 }
12372 run_test 133d "Verifying rename_stats ========================================"
12373
12374 test_133e() {
12375         remote_mds_nodsh && skip "remote MDS with nodsh"
12376         remote_ost_nodsh && skip "remote OST with nodsh"
12377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12378
12379         local testdir=$DIR/${tdir}/stats_testdir
12380         local ctr f0 f1 bs=32768 count=42 sum
12381
12382         mkdir -p ${testdir} || error "mkdir failed"
12383
12384         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12385
12386         for ctr in {write,read}_bytes; do
12387                 sync
12388                 cancel_lru_locks osc
12389
12390                 do_facet ost1 $LCTL set_param -n \
12391                         "obdfilter.*.exports.clear=clear"
12392
12393                 if [ $ctr = write_bytes ]; then
12394                         f0=/dev/zero
12395                         f1=${testdir}/${tfile}
12396                 else
12397                         f0=${testdir}/${tfile}
12398                         f1=/dev/null
12399                 fi
12400
12401                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
12402                         error "dd failed"
12403                 sync
12404                 cancel_lru_locks osc
12405
12406                 sum=$(do_facet ost1 $LCTL get_param \
12407                         "obdfilter.*.exports.*.stats" |
12408                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
12409                                 $1 == ctr { sum += $7 }
12410                                 END { printf("%0.0f", sum) }')
12411
12412                 if ((sum != bs * count)); then
12413                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
12414                 fi
12415         done
12416
12417         rm -rf $DIR/${tdir}
12418 }
12419 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
12420
12421 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
12422
12423 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
12424 # not honor the -ignore_readdir_race option correctly. So we call
12425 # error_ignore() rather than error() in these cases. See LU-11152.
12426 error_133() {
12427         if (find --version; do_facet mds1 find --version) |
12428                 grep -q '\b4\.5\.1[1-4]\b'; then
12429                 error_ignore LU-11152 "$@"
12430         else
12431                 error "$@"
12432         fi
12433 }
12434
12435 test_133f() {
12436         # First without trusting modes.
12437         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
12438         echo "proc_dirs='$proc_dirs'"
12439         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
12440         find $proc_dirs -exec cat '{}' \; &> /dev/null
12441
12442         # Second verifying readability.
12443         $LCTL get_param -R '*' &> /dev/null
12444
12445         # Verifing writability with badarea_io.
12446         find $proc_dirs \
12447                 -ignore_readdir_race \
12448                 -type f \
12449                 -not -name force_lbug \
12450                 -not -name changelog_mask \
12451                 -exec badarea_io '{}' \; ||
12452                         error_133 "find $proc_dirs failed"
12453 }
12454 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
12455
12456 test_133g() {
12457         remote_mds_nodsh && skip "remote MDS with nodsh"
12458         remote_ost_nodsh && skip "remote OST with nodsh"
12459
12460         # eventually, this can also be replaced with "lctl get_param -R",
12461         # but not until that option is always available on the server
12462         local facet
12463         for facet in mds1 ost1; do
12464                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
12465                         skip_noexit "Too old lustre on $facet"
12466                 local facet_proc_dirs=$(do_facet $facet \
12467                                         \\\ls -d $proc_regexp 2>/dev/null)
12468                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12469                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12470                 do_facet $facet find $facet_proc_dirs \
12471                         ! -name req_history \
12472                         -exec cat '{}' \\\; &> /dev/null
12473
12474                 do_facet $facet find $facet_proc_dirs \
12475                         ! -name req_history \
12476                         -type f \
12477                         -exec cat '{}' \\\; &> /dev/null ||
12478                                 error "proc file read failed"
12479
12480                 do_facet $facet find $facet_proc_dirs \
12481                         -ignore_readdir_race \
12482                         -type f \
12483                         -not -name force_lbug \
12484                         -not -name changelog_mask \
12485                         -exec badarea_io '{}' \\\; ||
12486                                 error_133 "$facet find $facet_proc_dirs failed"
12487         done
12488
12489         # remount the FS in case writes/reads /proc break the FS
12490         cleanup || error "failed to unmount"
12491         setup || error "failed to setup"
12492         true
12493 }
12494 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
12495
12496 test_133h() {
12497         remote_mds_nodsh && skip "remote MDS with nodsh"
12498         remote_ost_nodsh && skip "remote OST with nodsh"
12499         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
12500                 skip "Need MDS version at least 2.9.54"
12501
12502         local facet
12503
12504         for facet in client mds1 ost1; do
12505                 local facet_proc_dirs=$(do_facet $facet \
12506                                         \\\ls -d $proc_regexp 2> /dev/null)
12507                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12508                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12509                 # Get the list of files that are missing the terminating newline
12510                 local missing=($(do_facet $facet \
12511                         find ${facet_proc_dirs} -type f \|              \
12512                                 while read F\; do                       \
12513                                         awk -v FS='\v' -v RS='\v\v'     \
12514                                         "'END { if(NR>0 &&              \
12515                                         \\\$NF !~ /.*\\\n\$/)           \
12516                                                 print FILENAME}'"       \
12517                                         '\$F'\;                         \
12518                                 done 2>/dev/null))
12519                 [ ${#missing[*]} -eq 0 ] ||
12520                         error "files do not end with newline: ${missing[*]}"
12521         done
12522 }
12523 run_test 133h "Proc files should end with newlines"
12524
12525 test_134a() {
12526         remote_mds_nodsh && skip "remote MDS with nodsh"
12527         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12528                 skip "Need MDS version at least 2.7.54"
12529
12530         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12531         cancel_lru_locks mdc
12532
12533         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12534         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12535         [ $unused -eq 0 ] || error "$unused locks are not cleared"
12536
12537         local nr=1000
12538         createmany -o $DIR/$tdir/f $nr ||
12539                 error "failed to create $nr files in $DIR/$tdir"
12540         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12541
12542         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
12543         do_facet mds1 $LCTL set_param fail_loc=0x327
12544         do_facet mds1 $LCTL set_param fail_val=500
12545         touch $DIR/$tdir/m
12546
12547         echo "sleep 10 seconds ..."
12548         sleep 10
12549         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
12550
12551         do_facet mds1 $LCTL set_param fail_loc=0
12552         do_facet mds1 $LCTL set_param fail_val=0
12553         [ $lck_cnt -lt $unused ] ||
12554                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
12555
12556         rm $DIR/$tdir/m
12557         unlinkmany $DIR/$tdir/f $nr
12558 }
12559 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
12560
12561 test_134b() {
12562         remote_mds_nodsh && skip "remote MDS with nodsh"
12563         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12564                 skip "Need MDS version at least 2.7.54"
12565
12566         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12567         cancel_lru_locks mdc
12568
12569         local low_wm=$(do_facet mds1 $LCTL get_param -n \
12570                         ldlm.lock_reclaim_threshold_mb)
12571         # disable reclaim temporarily
12572         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
12573
12574         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
12575         do_facet mds1 $LCTL set_param fail_loc=0x328
12576         do_facet mds1 $LCTL set_param fail_val=500
12577
12578         $LCTL set_param debug=+trace
12579
12580         local nr=600
12581         createmany -o $DIR/$tdir/f $nr &
12582         local create_pid=$!
12583
12584         echo "Sleep $TIMEOUT seconds ..."
12585         sleep $TIMEOUT
12586         if ! ps -p $create_pid  > /dev/null 2>&1; then
12587                 do_facet mds1 $LCTL set_param fail_loc=0
12588                 do_facet mds1 $LCTL set_param fail_val=0
12589                 do_facet mds1 $LCTL set_param \
12590                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
12591                 error "createmany finished incorrectly!"
12592         fi
12593         do_facet mds1 $LCTL set_param fail_loc=0
12594         do_facet mds1 $LCTL set_param fail_val=0
12595         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
12596         wait $create_pid || return 1
12597
12598         unlinkmany $DIR/$tdir/f $nr
12599 }
12600 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
12601
12602 test_140() { #bug-17379
12603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12604
12605         test_mkdir $DIR/$tdir
12606         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
12607         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
12608
12609         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
12610         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
12611         local i=0
12612         while i=$((i + 1)); do
12613                 test_mkdir $i
12614                 cd $i || error "Changing to $i"
12615                 ln -s ../stat stat || error "Creating stat symlink"
12616                 # Read the symlink until ELOOP present,
12617                 # not LBUGing the system is considered success,
12618                 # we didn't overrun the stack.
12619                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
12620                 if [ $ret -ne 0 ]; then
12621                         if [ $ret -eq 40 ]; then
12622                                 break  # -ELOOP
12623                         else
12624                                 error "Open stat symlink"
12625                                         return
12626                         fi
12627                 fi
12628         done
12629         i=$((i - 1))
12630         echo "The symlink depth = $i"
12631         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
12632                 error "Invalid symlink depth"
12633
12634         # Test recursive symlink
12635         ln -s symlink_self symlink_self
12636         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
12637         echo "open symlink_self returns $ret"
12638         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
12639 }
12640 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
12641
12642 test_150() {
12643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12644
12645         local TF="$TMP/$tfile"
12646
12647         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12648         cp $TF $DIR/$tfile
12649         cancel_lru_locks $OSC
12650         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
12651         remount_client $MOUNT
12652         df -P $MOUNT
12653         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
12654
12655         $TRUNCATE $TF 6000
12656         $TRUNCATE $DIR/$tfile 6000
12657         cancel_lru_locks $OSC
12658         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
12659
12660         echo "12345" >>$TF
12661         echo "12345" >>$DIR/$tfile
12662         cancel_lru_locks $OSC
12663         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
12664
12665         echo "12345" >>$TF
12666         echo "12345" >>$DIR/$tfile
12667         cancel_lru_locks $OSC
12668         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
12669
12670         rm -f $TF
12671         true
12672 }
12673 run_test 150 "truncate/append tests"
12674
12675 #LU-2902 roc_hit was not able to read all values from lproc
12676 function roc_hit_init() {
12677         local list=$(comma_list $(osts_nodes))
12678         local dir=$DIR/$tdir-check
12679         local file=$dir/$tfile
12680         local BEFORE
12681         local AFTER
12682         local idx
12683
12684         test_mkdir $dir
12685         #use setstripe to do a write to every ost
12686         for i in $(seq 0 $((OSTCOUNT-1))); do
12687                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
12688                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
12689                 idx=$(printf %04x $i)
12690                 BEFORE=$(get_osd_param $list *OST*$idx stats |
12691                         awk '$1 == "cache_access" {sum += $7}
12692                                 END { printf("%0.0f", sum) }')
12693
12694                 cancel_lru_locks osc
12695                 cat $file >/dev/null
12696
12697                 AFTER=$(get_osd_param $list *OST*$idx stats |
12698                         awk '$1 == "cache_access" {sum += $7}
12699                                 END { printf("%0.0f", sum) }')
12700
12701                 echo BEFORE:$BEFORE AFTER:$AFTER
12702                 if ! let "AFTER - BEFORE == 4"; then
12703                         rm -rf $dir
12704                         error "roc_hit is not safe to use"
12705                 fi
12706                 rm $file
12707         done
12708
12709         rm -rf $dir
12710 }
12711
12712 function roc_hit() {
12713         local list=$(comma_list $(osts_nodes))
12714         echo $(get_osd_param $list '' stats |
12715                 awk '$1 == "cache_hit" {sum += $7}
12716                         END { printf("%0.0f", sum) }')
12717 }
12718
12719 function set_cache() {
12720         local on=1
12721
12722         if [ "$2" == "off" ]; then
12723                 on=0;
12724         fi
12725         local list=$(comma_list $(osts_nodes))
12726         set_osd_param $list '' $1_cache_enable $on
12727
12728         cancel_lru_locks osc
12729 }
12730
12731 test_151() {
12732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12733         remote_ost_nodsh && skip "remote OST with nodsh"
12734
12735         local CPAGES=3
12736         local list=$(comma_list $(osts_nodes))
12737
12738         # check whether obdfilter is cache capable at all
12739         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
12740                 skip "not cache-capable obdfilter"
12741         fi
12742
12743         # check cache is enabled on all obdfilters
12744         if get_osd_param $list '' read_cache_enable | grep 0; then
12745                 skip "oss cache is disabled"
12746         fi
12747
12748         set_osd_param $list '' writethrough_cache_enable 1
12749
12750         # check write cache is enabled on all obdfilters
12751         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
12752                 skip "oss write cache is NOT enabled"
12753         fi
12754
12755         roc_hit_init
12756
12757         #define OBD_FAIL_OBD_NO_LRU  0x609
12758         do_nodes $list $LCTL set_param fail_loc=0x609
12759
12760         # pages should be in the case right after write
12761         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
12762                 error "dd failed"
12763
12764         local BEFORE=$(roc_hit)
12765         cancel_lru_locks osc
12766         cat $DIR/$tfile >/dev/null
12767         local AFTER=$(roc_hit)
12768
12769         do_nodes $list $LCTL set_param fail_loc=0
12770
12771         if ! let "AFTER - BEFORE == CPAGES"; then
12772                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12773         fi
12774
12775         cancel_lru_locks osc
12776         # invalidates OST cache
12777         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
12778         set_osd_param $list '' read_cache_enable 0
12779         cat $DIR/$tfile >/dev/null
12780
12781         # now data shouldn't be found in the cache
12782         BEFORE=$(roc_hit)
12783         cancel_lru_locks osc
12784         cat $DIR/$tfile >/dev/null
12785         AFTER=$(roc_hit)
12786         if let "AFTER - BEFORE != 0"; then
12787                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12788         fi
12789
12790         set_osd_param $list '' read_cache_enable 1
12791         rm -f $DIR/$tfile
12792 }
12793 run_test 151 "test cache on oss and controls ==============================="
12794
12795 test_152() {
12796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12797
12798         local TF="$TMP/$tfile"
12799
12800         # simulate ENOMEM during write
12801 #define OBD_FAIL_OST_NOMEM      0x226
12802         lctl set_param fail_loc=0x80000226
12803         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12804         cp $TF $DIR/$tfile
12805         sync || error "sync failed"
12806         lctl set_param fail_loc=0
12807
12808         # discard client's cache
12809         cancel_lru_locks osc
12810
12811         # simulate ENOMEM during read
12812         lctl set_param fail_loc=0x80000226
12813         cmp $TF $DIR/$tfile || error "cmp failed"
12814         lctl set_param fail_loc=0
12815
12816         rm -f $TF
12817 }
12818 run_test 152 "test read/write with enomem ============================"
12819
12820 test_153() {
12821         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
12822 }
12823 run_test 153 "test if fdatasync does not crash ======================="
12824
12825 dot_lustre_fid_permission_check() {
12826         local fid=$1
12827         local ffid=$MOUNT/.lustre/fid/$fid
12828         local test_dir=$2
12829
12830         echo "stat fid $fid"
12831         stat $ffid > /dev/null || error "stat $ffid failed."
12832         echo "touch fid $fid"
12833         touch $ffid || error "touch $ffid failed."
12834         echo "write to fid $fid"
12835         cat /etc/hosts > $ffid || error "write $ffid failed."
12836         echo "read fid $fid"
12837         diff /etc/hosts $ffid || error "read $ffid failed."
12838         echo "append write to fid $fid"
12839         cat /etc/hosts >> $ffid || error "append write $ffid failed."
12840         echo "rename fid $fid"
12841         mv $ffid $test_dir/$tfile.1 &&
12842                 error "rename $ffid to $tfile.1 should fail."
12843         touch $test_dir/$tfile.1
12844         mv $test_dir/$tfile.1 $ffid &&
12845                 error "rename $tfile.1 to $ffid should fail."
12846         rm -f $test_dir/$tfile.1
12847         echo "truncate fid $fid"
12848         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
12849         echo "link fid $fid"
12850         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
12851         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
12852                 echo "setfacl fid $fid"
12853                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
12854                 echo "getfacl fid $fid"
12855                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
12856         fi
12857         echo "unlink fid $fid"
12858         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
12859         echo "mknod fid $fid"
12860         mknod $ffid c 1 3 && error "mknod $ffid should fail."
12861
12862         fid=[0xf00000400:0x1:0x0]
12863         ffid=$MOUNT/.lustre/fid/$fid
12864
12865         echo "stat non-exist fid $fid"
12866         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
12867         echo "write to non-exist fid $fid"
12868         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
12869         echo "link new fid $fid"
12870         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
12871
12872         mkdir -p $test_dir/$tdir
12873         touch $test_dir/$tdir/$tfile
12874         fid=$($LFS path2fid $test_dir/$tdir)
12875         rc=$?
12876         [ $rc -ne 0 ] &&
12877                 error "error: could not get fid for $test_dir/$dir/$tfile."
12878
12879         ffid=$MOUNT/.lustre/fid/$fid
12880
12881         echo "ls $fid"
12882         ls $ffid > /dev/null || error "ls $ffid failed."
12883         echo "touch $fid/$tfile.1"
12884         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
12885
12886         echo "touch $MOUNT/.lustre/fid/$tfile"
12887         touch $MOUNT/.lustre/fid/$tfile && \
12888                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
12889
12890         echo "setxattr to $MOUNT/.lustre/fid"
12891         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
12892
12893         echo "listxattr for $MOUNT/.lustre/fid"
12894         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
12895
12896         echo "delxattr from $MOUNT/.lustre/fid"
12897         setfattr -x trusted.name1 $MOUNT/.lustre/fid
12898
12899         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
12900         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
12901                 error "touch invalid fid should fail."
12902
12903         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
12904         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
12905                 error "touch non-normal fid should fail."
12906
12907         echo "rename $tdir to $MOUNT/.lustre/fid"
12908         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
12909                 error "rename to $MOUNT/.lustre/fid should fail."
12910
12911         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
12912         then            # LU-3547
12913                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
12914                 local new_obf_mode=777
12915
12916                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
12917                 chmod $new_obf_mode $DIR/.lustre/fid ||
12918                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
12919
12920                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
12921                 [ $obf_mode -eq $new_obf_mode ] ||
12922                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
12923
12924                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
12925                 chmod $old_obf_mode $DIR/.lustre/fid ||
12926                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
12927         fi
12928
12929         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
12930         fid=$($LFS path2fid $test_dir/$tfile-2)
12931
12932         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
12933         then # LU-5424
12934                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
12935                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
12936                         error "create lov data thru .lustre failed"
12937         fi
12938         echo "cp /etc/passwd $test_dir/$tfile-2"
12939         cp /etc/passwd $test_dir/$tfile-2 ||
12940                 error "copy to $test_dir/$tfile-2 failed."
12941         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
12942         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
12943                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
12944
12945         rm -rf $test_dir/tfile.lnk
12946         rm -rf $test_dir/$tfile-2
12947 }
12948
12949 test_154A() {
12950         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12951                 skip "Need MDS version at least 2.4.1"
12952
12953         local tf=$DIR/$tfile
12954         touch $tf
12955
12956         local fid=$($LFS path2fid $tf)
12957         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
12958
12959         # check that we get the same pathname back
12960         local found=$($LFS fid2path $MOUNT "$fid")
12961         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
12962         [ "$found" == "$tf" ] ||
12963                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
12964 }
12965 run_test 154A "lfs path2fid and fid2path basic checks"
12966
12967 test_154B() {
12968         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12969                 skip "Need MDS version at least 2.4.1"
12970
12971         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
12972         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
12973         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
12974         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
12975
12976         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
12977         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
12978
12979         # check that we get the same pathname
12980         echo "PFID: $PFID, name: $name"
12981         local FOUND=$($LFS fid2path $MOUNT "$PFID")
12982         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
12983         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
12984                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
12985
12986         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
12987 }
12988 run_test 154B "verify the ll_decode_linkea tool"
12989
12990 test_154a() {
12991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12992         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12993         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12994                 skip "Need MDS version at least 2.2.51"
12995         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12996
12997         cp /etc/hosts $DIR/$tfile
12998
12999         fid=$($LFS path2fid $DIR/$tfile)
13000         rc=$?
13001         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13002
13003         dot_lustre_fid_permission_check "$fid" $DIR ||
13004                 error "dot lustre permission check $fid failed"
13005
13006         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13007
13008         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13009
13010         touch $MOUNT/.lustre/file &&
13011                 error "creation is not allowed under .lustre"
13012
13013         mkdir $MOUNT/.lustre/dir &&
13014                 error "mkdir is not allowed under .lustre"
13015
13016         rm -rf $DIR/$tfile
13017 }
13018 run_test 154a "Open-by-FID"
13019
13020 test_154b() {
13021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13022         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13023         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13024         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13025                 skip "Need MDS version at least 2.2.51"
13026
13027         local remote_dir=$DIR/$tdir/remote_dir
13028         local MDTIDX=1
13029         local rc=0
13030
13031         mkdir -p $DIR/$tdir
13032         $LFS mkdir -i $MDTIDX $remote_dir ||
13033                 error "create remote directory failed"
13034
13035         cp /etc/hosts $remote_dir/$tfile
13036
13037         fid=$($LFS path2fid $remote_dir/$tfile)
13038         rc=$?
13039         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13040
13041         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13042                 error "dot lustre permission check $fid failed"
13043         rm -rf $DIR/$tdir
13044 }
13045 run_test 154b "Open-by-FID for remote directory"
13046
13047 test_154c() {
13048         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13049                 skip "Need MDS version at least 2.4.1"
13050
13051         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13052         local FID1=$($LFS path2fid $DIR/$tfile.1)
13053         local FID2=$($LFS path2fid $DIR/$tfile.2)
13054         local FID3=$($LFS path2fid $DIR/$tfile.3)
13055
13056         local N=1
13057         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13058                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13059                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13060                 local want=FID$N
13061                 [ "$FID" = "${!want}" ] ||
13062                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13063                 N=$((N + 1))
13064         done
13065
13066         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13067         do
13068                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13069                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13070                 N=$((N + 1))
13071         done
13072 }
13073 run_test 154c "lfs path2fid and fid2path multiple arguments"
13074
13075 test_154d() {
13076         remote_mds_nodsh && skip "remote MDS with nodsh"
13077         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13078                 skip "Need MDS version at least 2.5.53"
13079
13080         if remote_mds; then
13081                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13082         else
13083                 nid="0@lo"
13084         fi
13085         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13086         local fd
13087         local cmd
13088
13089         rm -f $DIR/$tfile
13090         touch $DIR/$tfile
13091
13092         local fid=$($LFS path2fid $DIR/$tfile)
13093         # Open the file
13094         fd=$(free_fd)
13095         cmd="exec $fd<$DIR/$tfile"
13096         eval $cmd
13097         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13098         echo "$fid_list" | grep "$fid"
13099         rc=$?
13100
13101         cmd="exec $fd>/dev/null"
13102         eval $cmd
13103         if [ $rc -ne 0 ]; then
13104                 error "FID $fid not found in open files list $fid_list"
13105         fi
13106 }
13107 run_test 154d "Verify open file fid"
13108
13109 test_154e()
13110 {
13111         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13112                 skip "Need MDS version at least 2.6.50"
13113
13114         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13115                 error ".lustre returned by readdir"
13116         fi
13117 }
13118 run_test 154e ".lustre is not returned by readdir"
13119
13120 test_154f() {
13121         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13122
13123         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13124         test_mkdir -p -c1 $DIR/$tdir/d
13125         # test dirs inherit from its stripe
13126         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13127         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13128         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13129         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13130         touch $DIR/f
13131
13132         # get fid of parents
13133         local FID0=$($LFS path2fid $DIR/$tdir/d)
13134         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13135         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13136         local FID3=$($LFS path2fid $DIR)
13137
13138         # check that path2fid --parents returns expected <parent_fid>/name
13139         # 1) test for a directory (single parent)
13140         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13141         [ "$parent" == "$FID0/foo1" ] ||
13142                 error "expected parent: $FID0/foo1, got: $parent"
13143
13144         # 2) test for a file with nlink > 1 (multiple parents)
13145         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13146         echo "$parent" | grep -F "$FID1/$tfile" ||
13147                 error "$FID1/$tfile not returned in parent list"
13148         echo "$parent" | grep -F "$FID2/link" ||
13149                 error "$FID2/link not returned in parent list"
13150
13151         # 3) get parent by fid
13152         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13153         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13154         echo "$parent" | grep -F "$FID1/$tfile" ||
13155                 error "$FID1/$tfile not returned in parent list (by fid)"
13156         echo "$parent" | grep -F "$FID2/link" ||
13157                 error "$FID2/link not returned in parent list (by fid)"
13158
13159         # 4) test for entry in root directory
13160         parent=$($LFS path2fid --parents $DIR/f)
13161         echo "$parent" | grep -F "$FID3/f" ||
13162                 error "$FID3/f not returned in parent list"
13163
13164         # 5) test it on root directory
13165         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13166                 error "$MOUNT should not have parents"
13167
13168         # enable xattr caching and check that linkea is correctly updated
13169         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13170         save_lustre_params client "llite.*.xattr_cache" > $save
13171         lctl set_param llite.*.xattr_cache 1
13172
13173         # 6.1) linkea update on rename
13174         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13175
13176         # get parents by fid
13177         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13178         # foo1 should no longer be returned in parent list
13179         echo "$parent" | grep -F "$FID1" &&
13180                 error "$FID1 should no longer be in parent list"
13181         # the new path should appear
13182         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13183                 error "$FID2/$tfile.moved is not in parent list"
13184
13185         # 6.2) linkea update on unlink
13186         rm -f $DIR/$tdir/d/foo2/link
13187         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13188         # foo2/link should no longer be returned in parent list
13189         echo "$parent" | grep -F "$FID2/link" &&
13190                 error "$FID2/link should no longer be in parent list"
13191         true
13192
13193         rm -f $DIR/f
13194         restore_lustre_params < $save
13195         rm -f $save
13196 }
13197 run_test 154f "get parent fids by reading link ea"
13198
13199 test_154g()
13200 {
13201         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13202         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13203            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13204                 skip "Need MDS version at least 2.6.92"
13205
13206         mkdir -p $DIR/$tdir
13207         llapi_fid_test -d $DIR/$tdir
13208 }
13209 run_test 154g "various llapi FID tests"
13210
13211 test_155_small_load() {
13212     local temp=$TMP/$tfile
13213     local file=$DIR/$tfile
13214
13215     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13216         error "dd of=$temp bs=6096 count=1 failed"
13217     cp $temp $file
13218     cancel_lru_locks $OSC
13219     cmp $temp $file || error "$temp $file differ"
13220
13221     $TRUNCATE $temp 6000
13222     $TRUNCATE $file 6000
13223     cmp $temp $file || error "$temp $file differ (truncate1)"
13224
13225     echo "12345" >>$temp
13226     echo "12345" >>$file
13227     cmp $temp $file || error "$temp $file differ (append1)"
13228
13229     echo "12345" >>$temp
13230     echo "12345" >>$file
13231     cmp $temp $file || error "$temp $file differ (append2)"
13232
13233     rm -f $temp $file
13234     true
13235 }
13236
13237 test_155_big_load() {
13238         remote_ost_nodsh && skip "remote OST with nodsh"
13239
13240         local temp=$TMP/$tfile
13241         local file=$DIR/$tfile
13242
13243         free_min_max
13244         local cache_size=$(do_facet ost$((MAXI+1)) \
13245                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13246         local large_file_size=$((cache_size * 2))
13247
13248         echo "OSS cache size: $cache_size KB"
13249         echo "Large file size: $large_file_size KB"
13250
13251         [ $MAXV -le $large_file_size ] &&
13252                 skip_env "max available OST size needs > $large_file_size KB"
13253
13254         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13255
13256         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13257                 error "dd of=$temp bs=$large_file_size count=1k failed"
13258         cp $temp $file
13259         ls -lh $temp $file
13260         cancel_lru_locks osc
13261         cmp $temp $file || error "$temp $file differ"
13262
13263         rm -f $temp $file
13264         true
13265 }
13266
13267 save_writethrough() {
13268         local facets=$(get_facets OST)
13269
13270         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13271 }
13272
13273 test_155a() {
13274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13275
13276         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13277
13278         save_writethrough $p
13279
13280         set_cache read on
13281         set_cache writethrough on
13282         test_155_small_load
13283         restore_lustre_params < $p
13284         rm -f $p
13285 }
13286 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13287
13288 test_155b() {
13289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13290
13291         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13292
13293         save_writethrough $p
13294
13295         set_cache read on
13296         set_cache writethrough off
13297         test_155_small_load
13298         restore_lustre_params < $p
13299         rm -f $p
13300 }
13301 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
13302
13303 test_155c() {
13304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13305
13306         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13307
13308         save_writethrough $p
13309
13310         set_cache read off
13311         set_cache writethrough on
13312         test_155_small_load
13313         restore_lustre_params < $p
13314         rm -f $p
13315 }
13316 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
13317
13318 test_155d() {
13319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13320
13321         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13322
13323         save_writethrough $p
13324
13325         set_cache read off
13326         set_cache writethrough off
13327         test_155_small_load
13328         restore_lustre_params < $p
13329         rm -f $p
13330 }
13331 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
13332
13333 test_155e() {
13334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13335
13336         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13337
13338         save_writethrough $p
13339
13340         set_cache read on
13341         set_cache writethrough on
13342         test_155_big_load
13343         restore_lustre_params < $p
13344         rm -f $p
13345 }
13346 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
13347
13348 test_155f() {
13349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13350
13351         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13352
13353         save_writethrough $p
13354
13355         set_cache read on
13356         set_cache writethrough off
13357         test_155_big_load
13358         restore_lustre_params < $p
13359         rm -f $p
13360 }
13361 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
13362
13363 test_155g() {
13364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13365
13366         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13367
13368         save_writethrough $p
13369
13370         set_cache read off
13371         set_cache writethrough on
13372         test_155_big_load
13373         restore_lustre_params < $p
13374         rm -f $p
13375 }
13376 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
13377
13378 test_155h() {
13379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13380
13381         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13382
13383         save_writethrough $p
13384
13385         set_cache read off
13386         set_cache writethrough off
13387         test_155_big_load
13388         restore_lustre_params < $p
13389         rm -f $p
13390 }
13391 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
13392
13393 test_156() {
13394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13395         remote_ost_nodsh && skip "remote OST with nodsh"
13396         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
13397                 skip "stats not implemented on old servers"
13398         [ "$ost1_FSTYPE" = "zfs" ] &&
13399                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
13400
13401         local CPAGES=3
13402         local BEFORE
13403         local AFTER
13404         local file="$DIR/$tfile"
13405         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13406
13407         save_writethrough $p
13408         roc_hit_init
13409
13410         log "Turn on read and write cache"
13411         set_cache read on
13412         set_cache writethrough on
13413
13414         log "Write data and read it back."
13415         log "Read should be satisfied from the cache."
13416         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13417         BEFORE=$(roc_hit)
13418         cancel_lru_locks osc
13419         cat $file >/dev/null
13420         AFTER=$(roc_hit)
13421         if ! let "AFTER - BEFORE == CPAGES"; then
13422                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
13423         else
13424                 log "cache hits: before: $BEFORE, after: $AFTER"
13425         fi
13426
13427         log "Read again; it should be satisfied from the cache."
13428         BEFORE=$AFTER
13429         cancel_lru_locks osc
13430         cat $file >/dev/null
13431         AFTER=$(roc_hit)
13432         if ! let "AFTER - BEFORE == CPAGES"; then
13433                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
13434         else
13435                 log "cache hits:: before: $BEFORE, after: $AFTER"
13436         fi
13437
13438         log "Turn off the read cache and turn on the write cache"
13439         set_cache read off
13440         set_cache writethrough on
13441
13442         log "Read again; it should be satisfied from the cache."
13443         BEFORE=$(roc_hit)
13444         cancel_lru_locks osc
13445         cat $file >/dev/null
13446         AFTER=$(roc_hit)
13447         if ! let "AFTER - BEFORE == CPAGES"; then
13448                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
13449         else
13450                 log "cache hits:: before: $BEFORE, after: $AFTER"
13451         fi
13452
13453         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
13454                 # > 2.12.56 uses pagecache if cached
13455                 log "Read again; it should not be satisfied from the cache."
13456                 BEFORE=$AFTER
13457                 cancel_lru_locks osc
13458                 cat $file >/dev/null
13459                 AFTER=$(roc_hit)
13460                 if ! let "AFTER - BEFORE == 0"; then
13461                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
13462                 else
13463                         log "cache hits:: before: $BEFORE, after: $AFTER"
13464                 fi
13465         fi
13466
13467         log "Write data and read it back."
13468         log "Read should be satisfied from the cache."
13469         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13470         BEFORE=$(roc_hit)
13471         cancel_lru_locks osc
13472         cat $file >/dev/null
13473         AFTER=$(roc_hit)
13474         if ! let "AFTER - BEFORE == CPAGES"; then
13475                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
13476         else
13477                 log "cache hits:: before: $BEFORE, after: $AFTER"
13478         fi
13479
13480         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
13481                 # > 2.12.56 uses pagecache if cached
13482                 log "Read again; it should not be satisfied from the cache."
13483                 BEFORE=$AFTER
13484                 cancel_lru_locks osc
13485                 cat $file >/dev/null
13486                 AFTER=$(roc_hit)
13487                 if ! let "AFTER - BEFORE == 0"; then
13488                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
13489                 else
13490                         log "cache hits:: before: $BEFORE, after: $AFTER"
13491                 fi
13492         fi
13493
13494         log "Turn off read and write cache"
13495         set_cache read off
13496         set_cache writethrough off
13497
13498         log "Write data and read it back"
13499         log "It should not be satisfied from the cache."
13500         rm -f $file
13501         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13502         cancel_lru_locks osc
13503         BEFORE=$(roc_hit)
13504         cat $file >/dev/null
13505         AFTER=$(roc_hit)
13506         if ! let "AFTER - BEFORE == 0"; then
13507                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
13508         else
13509                 log "cache hits:: before: $BEFORE, after: $AFTER"
13510         fi
13511
13512         log "Turn on the read cache and turn off the write cache"
13513         set_cache read on
13514         set_cache writethrough off
13515
13516         log "Write data and read it back"
13517         log "It should not be satisfied from the cache."
13518         rm -f $file
13519         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13520         BEFORE=$(roc_hit)
13521         cancel_lru_locks osc
13522         cat $file >/dev/null
13523         AFTER=$(roc_hit)
13524         if ! let "AFTER - BEFORE == 0"; then
13525                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
13526         else
13527                 log "cache hits:: before: $BEFORE, after: $AFTER"
13528         fi
13529
13530         log "Read again; it should be satisfied from the cache."
13531         BEFORE=$(roc_hit)
13532         cancel_lru_locks osc
13533         cat $file >/dev/null
13534         AFTER=$(roc_hit)
13535         if ! let "AFTER - BEFORE == CPAGES"; then
13536                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
13537         else
13538                 log "cache hits:: before: $BEFORE, after: $AFTER"
13539         fi
13540
13541         restore_lustre_params < $p
13542         rm -f $p $file
13543 }
13544 run_test 156 "Verification of tunables"
13545
13546 test_160a() {
13547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13548         remote_mds_nodsh && skip "remote MDS with nodsh"
13549         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13550                 skip "Need MDS version at least 2.2.0"
13551
13552         changelog_register || error "changelog_register failed"
13553         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13554         changelog_users $SINGLEMDS | grep -q $cl_user ||
13555                 error "User $cl_user not found in changelog_users"
13556
13557         # change something
13558         test_mkdir -p $DIR/$tdir/pics/2008/zachy
13559         changelog_clear 0 || error "changelog_clear failed"
13560         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
13561         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
13562         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
13563         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
13564         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
13565         rm $DIR/$tdir/pics/desktop.jpg
13566
13567         changelog_dump | tail -10
13568
13569         echo "verifying changelog mask"
13570         changelog_chmask "-MKDIR"
13571         changelog_chmask "-CLOSE"
13572
13573         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
13574         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
13575
13576         changelog_chmask "+MKDIR"
13577         changelog_chmask "+CLOSE"
13578
13579         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
13580         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
13581
13582         changelog_dump | tail -10
13583         MKDIRS=$(changelog_dump | grep -c "MKDIR")
13584         CLOSES=$(changelog_dump | grep -c "CLOSE")
13585         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
13586         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
13587
13588         # verify contents
13589         echo "verifying target fid"
13590         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
13591         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
13592         [ "$fidc" == "$fidf" ] ||
13593                 error "changelog '$tfile' fid $fidc != file fid $fidf"
13594         echo "verifying parent fid"
13595         # The FID returned from the Changelog may be the directory shard on
13596         # a different MDT, and not the FID returned by path2fid on the parent.
13597         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
13598         # since this is what will matter when recreating this file in the tree.
13599         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
13600         local pathp=$($LFS fid2path $MOUNT "$fidp")
13601         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
13602                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
13603
13604         echo "getting records for $cl_user"
13605         changelog_users $SINGLEMDS
13606         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
13607         local nclr=3
13608         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
13609                 error "changelog_clear failed"
13610         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
13611         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
13612         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
13613                 error "user index expect $user_rec1 + $nclr != $user_rec2"
13614
13615         local min0_rec=$(changelog_users $SINGLEMDS |
13616                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
13617         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
13618                           awk '{ print $1; exit; }')
13619
13620         changelog_dump | tail -n 5
13621         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
13622         [ $first_rec == $((min0_rec + 1)) ] ||
13623                 error "first index should be $min0_rec + 1 not $first_rec"
13624
13625         # LU-3446 changelog index reset on MDT restart
13626         local cur_rec1=$(changelog_users $SINGLEMDS |
13627                          awk '/^current.index:/ { print $NF }')
13628         changelog_clear 0 ||
13629                 error "clear all changelog records for $cl_user failed"
13630         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
13631         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
13632                 error "Fail to start $SINGLEMDS"
13633         local cur_rec2=$(changelog_users $SINGLEMDS |
13634                          awk '/^current.index:/ { print $NF }')
13635         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
13636         [ $cur_rec1 == $cur_rec2 ] ||
13637                 error "current index should be $cur_rec1 not $cur_rec2"
13638
13639         echo "verifying users from this test are deregistered"
13640         changelog_deregister || error "changelog_deregister failed"
13641         changelog_users $SINGLEMDS | grep -q $cl_user &&
13642                 error "User '$cl_user' still in changelog_users"
13643
13644         # lctl get_param -n mdd.*.changelog_users
13645         # current index: 144
13646         # ID    index (idle seconds)
13647         # cl3   144 (2)
13648         if ! changelog_users $SINGLEMDS | grep "^cl"; then
13649                 # this is the normal case where all users were deregistered
13650                 # make sure no new records are added when no users are present
13651                 local last_rec1=$(changelog_users $SINGLEMDS |
13652                                   awk '/^current.index:/ { print $NF }')
13653                 touch $DIR/$tdir/chloe
13654                 local last_rec2=$(changelog_users $SINGLEMDS |
13655                                   awk '/^current.index:/ { print $NF }')
13656                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
13657                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
13658         else
13659                 # any changelog users must be leftovers from a previous test
13660                 changelog_users $SINGLEMDS
13661                 echo "other changelog users; can't verify off"
13662         fi
13663 }
13664 run_test 160a "changelog sanity"
13665
13666 test_160b() { # LU-3587
13667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13668         remote_mds_nodsh && skip "remote MDS with nodsh"
13669         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13670                 skip "Need MDS version at least 2.2.0"
13671
13672         changelog_register || error "changelog_register failed"
13673         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13674         changelog_users $SINGLEMDS | grep -q $cl_user ||
13675                 error "User '$cl_user' not found in changelog_users"
13676
13677         local longname1=$(str_repeat a 255)
13678         local longname2=$(str_repeat b 255)
13679
13680         cd $DIR
13681         echo "creating very long named file"
13682         touch $longname1 || error "create of '$longname1' failed"
13683         echo "renaming very long named file"
13684         mv $longname1 $longname2
13685
13686         changelog_dump | grep RENME | tail -n 5
13687         rm -f $longname2
13688 }
13689 run_test 160b "Verify that very long rename doesn't crash in changelog"
13690
13691 test_160c() {
13692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13693         remote_mds_nodsh && skip "remote MDS with nodsh"
13694
13695         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
13696                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
13697                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
13698                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
13699
13700         local rc=0
13701
13702         # Registration step
13703         changelog_register || error "changelog_register failed"
13704
13705         rm -rf $DIR/$tdir
13706         mkdir -p $DIR/$tdir
13707         $MCREATE $DIR/$tdir/foo_160c
13708         changelog_chmask "-TRUNC"
13709         $TRUNCATE $DIR/$tdir/foo_160c 200
13710         changelog_chmask "+TRUNC"
13711         $TRUNCATE $DIR/$tdir/foo_160c 199
13712         changelog_dump | tail -n 5
13713         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
13714         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
13715 }
13716 run_test 160c "verify that changelog log catch the truncate event"
13717
13718 test_160d() {
13719         remote_mds_nodsh && skip "remote MDS with nodsh"
13720         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13722         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
13723                 skip "Need MDS version at least 2.7.60"
13724
13725         # Registration step
13726         changelog_register || error "changelog_register failed"
13727
13728         mkdir -p $DIR/$tdir/migrate_dir
13729         changelog_clear 0 || error "changelog_clear failed"
13730
13731         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
13732         changelog_dump | tail -n 5
13733         local migrates=$(changelog_dump | grep -c "MIGRT")
13734         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
13735 }
13736 run_test 160d "verify that changelog log catch the migrate event"
13737
13738 test_160e() {
13739         remote_mds_nodsh && skip "remote MDS with nodsh"
13740
13741         # Create a user
13742         changelog_register || error "changelog_register failed"
13743
13744         # Delete a future user (expect fail)
13745         local MDT0=$(facet_svc $SINGLEMDS)
13746         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
13747         local rc=$?
13748
13749         if [ $rc -eq 0 ]; then
13750                 error "Deleted non-existant user cl77"
13751         elif [ $rc -ne 2 ]; then
13752                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
13753         fi
13754
13755         # Clear to a bad index (1 billion should be safe)
13756         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
13757         rc=$?
13758
13759         if [ $rc -eq 0 ]; then
13760                 error "Successfully cleared to invalid CL index"
13761         elif [ $rc -ne 22 ]; then
13762                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
13763         fi
13764 }
13765 run_test 160e "changelog negative testing (should return errors)"
13766
13767 test_160f() {
13768         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13769         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13770                 skip "Need MDS version at least 2.10.56"
13771
13772         local mdts=$(comma_list $(mdts_nodes))
13773
13774         # Create a user
13775         changelog_register || error "first changelog_register failed"
13776         changelog_register || error "second changelog_register failed"
13777         local cl_users
13778         declare -A cl_user1
13779         declare -A cl_user2
13780         local user_rec1
13781         local user_rec2
13782         local i
13783
13784         # generate some changelog records to accumulate on each MDT
13785         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13786         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13787                 error "create $DIR/$tdir/$tfile failed"
13788
13789         # check changelogs have been generated
13790         local nbcl=$(changelog_dump | wc -l)
13791         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13792
13793         for param in "changelog_max_idle_time=10" \
13794                      "changelog_gc=1" \
13795                      "changelog_min_gc_interval=2" \
13796                      "changelog_min_free_cat_entries=3"; do
13797                 local MDT0=$(facet_svc $SINGLEMDS)
13798                 local var="${param%=*}"
13799                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13800
13801                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13802                 do_nodes $mdts $LCTL set_param mdd.*.$param
13803         done
13804
13805         # force cl_user2 to be idle (1st part)
13806         sleep 9
13807
13808         # simulate changelog catalog almost full
13809         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13810         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13811
13812         for i in $(seq $MDSCOUNT); do
13813                 cl_users=(${CL_USERS[mds$i]})
13814                 cl_user1[mds$i]="${cl_users[0]}"
13815                 cl_user2[mds$i]="${cl_users[1]}"
13816
13817                 [ -n "${cl_user1[mds$i]}" ] ||
13818                         error "mds$i: no user registered"
13819                 [ -n "${cl_user2[mds$i]}" ] ||
13820                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13821
13822                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13823                 [ -n "$user_rec1" ] ||
13824                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13825                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13826                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13827                 [ -n "$user_rec2" ] ||
13828                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13829                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13830                      "$user_rec1 + 2 == $user_rec2"
13831                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13832                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13833                               "$user_rec1 + 2, but is $user_rec2"
13834                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13835                 [ -n "$user_rec2" ] ||
13836                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13837                 [ $user_rec1 == $user_rec2 ] ||
13838                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13839                               "$user_rec1, but is $user_rec2"
13840         done
13841
13842         # force cl_user2 to be idle (2nd part) and to reach
13843         # changelog_max_idle_time
13844         sleep 2
13845
13846         # generate one more changelog to trigger fail_loc
13847         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13848                 error "create $DIR/$tdir/${tfile}bis failed"
13849
13850         # ensure gc thread is done
13851         for i in $(mdts_nodes); do
13852                 wait_update $i \
13853                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13854                         error "$i: GC-thread not done"
13855         done
13856
13857         local first_rec
13858         for i in $(seq $MDSCOUNT); do
13859                 # check cl_user1 still registered
13860                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13861                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13862                 # check cl_user2 unregistered
13863                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13864                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13865
13866                 # check changelogs are present and starting at $user_rec1 + 1
13867                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13868                 [ -n "$user_rec1" ] ||
13869                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13870                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13871                             awk '{ print $1; exit; }')
13872
13873                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13874                 [ $((user_rec1 + 1)) == $first_rec ] ||
13875                         error "mds$i: first index should be $user_rec1 + 1, " \
13876                               "but is $first_rec"
13877         done
13878 }
13879 run_test 160f "changelog garbage collect (timestamped users)"
13880
13881 test_160g() {
13882         remote_mds_nodsh && skip "remote MDS with nodsh"
13883         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13884                 skip "Need MDS version at least 2.10.56"
13885
13886         local mdts=$(comma_list $(mdts_nodes))
13887
13888         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
13889         do_nodes $mdts $LCTL set_param fail_loc=0x1314
13890
13891         # Create a user
13892         changelog_register || error "first changelog_register failed"
13893         changelog_register || error "second changelog_register failed"
13894         local cl_users
13895         declare -A cl_user1
13896         declare -A cl_user2
13897         local user_rec1
13898         local user_rec2
13899         local i
13900
13901         # generate some changelog records to accumulate on each MDT
13902         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13903         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13904                 error "create $DIR/$tdir/$tfile failed"
13905
13906         # check changelogs have been generated
13907         local nbcl=$(changelog_dump | wc -l)
13908         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13909
13910         # reduce the max_idle_indexes value to make sure we exceed it
13911         max_ndx=$((nbcl / 2 - 1))
13912
13913         for param in "changelog_max_idle_indexes=$max_ndx" \
13914                      "changelog_gc=1" \
13915                      "changelog_min_gc_interval=2" \
13916                      "changelog_min_free_cat_entries=3"; do
13917                 local MDT0=$(facet_svc $SINGLEMDS)
13918                 local var="${param%=*}"
13919                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13920
13921                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13922                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
13923                         error "unable to set mdd.*.$param"
13924         done
13925
13926         # simulate changelog catalog almost full
13927         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13928         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13929
13930         for i in $(seq $MDSCOUNT); do
13931                 cl_users=(${CL_USERS[mds$i]})
13932                 cl_user1[mds$i]="${cl_users[0]}"
13933                 cl_user2[mds$i]="${cl_users[1]}"
13934
13935                 [ -n "${cl_user1[mds$i]}" ] ||
13936                         error "mds$i: no user registered"
13937                 [ -n "${cl_user2[mds$i]}" ] ||
13938                         error "mds$i: only ${cl_user1[mds$i]} is registered"
13939
13940                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13941                 [ -n "$user_rec1" ] ||
13942                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13943                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13944                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13945                 [ -n "$user_rec2" ] ||
13946                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13947                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13948                      "$user_rec1 + 2 == $user_rec2"
13949                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13950                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13951                               "$user_rec1 + 2, but is $user_rec2"
13952                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13953                 [ -n "$user_rec2" ] ||
13954                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13955                 [ $user_rec1 == $user_rec2 ] ||
13956                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13957                               "$user_rec1, but is $user_rec2"
13958         done
13959
13960         # ensure we are past the previous changelog_min_gc_interval set above
13961         sleep 2
13962
13963         # generate one more changelog to trigger fail_loc
13964         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13965                 error "create $DIR/$tdir/${tfile}bis failed"
13966
13967         # ensure gc thread is done
13968         for i in $(mdts_nodes); do
13969                 wait_update $i \
13970                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13971                         error "$i: GC-thread not done"
13972         done
13973
13974         local first_rec
13975         for i in $(seq $MDSCOUNT); do
13976                 # check cl_user1 still registered
13977                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13978                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13979                 # check cl_user2 unregistered
13980                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13981                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13982
13983                 # check changelogs are present and starting at $user_rec1 + 1
13984                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13985                 [ -n "$user_rec1" ] ||
13986                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13987                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13988                             awk '{ print $1; exit; }')
13989
13990                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13991                 [ $((user_rec1 + 1)) == $first_rec ] ||
13992                         error "mds$i: first index should be $user_rec1 + 1, " \
13993                               "but is $first_rec"
13994         done
13995 }
13996 run_test 160g "changelog garbage collect (old users)"
13997
13998 test_160h() {
13999         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14000         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14001                 skip "Need MDS version at least 2.10.56"
14002
14003         local mdts=$(comma_list $(mdts_nodes))
14004
14005         # Create a user
14006         changelog_register || error "first changelog_register failed"
14007         changelog_register || error "second changelog_register failed"
14008         local cl_users
14009         declare -A cl_user1
14010         declare -A cl_user2
14011         local user_rec1
14012         local user_rec2
14013         local i
14014
14015         # generate some changelog records to accumulate on each MDT
14016         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
14017         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14018                 error "create $DIR/$tdir/$tfile failed"
14019
14020         # check changelogs have been generated
14021         local nbcl=$(changelog_dump | wc -l)
14022         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14023
14024         for param in "changelog_max_idle_time=10" \
14025                      "changelog_gc=1" \
14026                      "changelog_min_gc_interval=2"; do
14027                 local MDT0=$(facet_svc $SINGLEMDS)
14028                 local var="${param%=*}"
14029                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14030
14031                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14032                 do_nodes $mdts $LCTL set_param mdd.*.$param
14033         done
14034
14035         # force cl_user2 to be idle (1st part)
14036         sleep 9
14037
14038         for i in $(seq $MDSCOUNT); do
14039                 cl_users=(${CL_USERS[mds$i]})
14040                 cl_user1[mds$i]="${cl_users[0]}"
14041                 cl_user2[mds$i]="${cl_users[1]}"
14042
14043                 [ -n "${cl_user1[mds$i]}" ] ||
14044                         error "mds$i: no user registered"
14045                 [ -n "${cl_user2[mds$i]}" ] ||
14046                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14047
14048                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14049                 [ -n "$user_rec1" ] ||
14050                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14051                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14052                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14053                 [ -n "$user_rec2" ] ||
14054                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14055                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14056                      "$user_rec1 + 2 == $user_rec2"
14057                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14058                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14059                               "$user_rec1 + 2, but is $user_rec2"
14060                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14061                 [ -n "$user_rec2" ] ||
14062                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14063                 [ $user_rec1 == $user_rec2 ] ||
14064                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14065                               "$user_rec1, but is $user_rec2"
14066         done
14067
14068         # force cl_user2 to be idle (2nd part) and to reach
14069         # changelog_max_idle_time
14070         sleep 2
14071
14072         # force each GC-thread start and block then
14073         # one per MDT/MDD, set fail_val accordingly
14074         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14075         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14076
14077         # generate more changelogs to trigger fail_loc
14078         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14079                 error "create $DIR/$tdir/${tfile}bis failed"
14080
14081         # stop MDT to stop GC-thread, should be done in back-ground as it will
14082         # block waiting for the thread to be released and exit
14083         declare -A stop_pids
14084         for i in $(seq $MDSCOUNT); do
14085                 stop mds$i &
14086                 stop_pids[mds$i]=$!
14087         done
14088
14089         for i in $(mdts_nodes); do
14090                 local facet
14091                 local nb=0
14092                 local facets=$(facets_up_on_host $i)
14093
14094                 for facet in ${facets//,/ }; do
14095                         if [[ $facet == mds* ]]; then
14096                                 nb=$((nb + 1))
14097                         fi
14098                 done
14099                 # ensure each MDS's gc threads are still present and all in "R"
14100                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14101                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14102                         error "$i: expected $nb GC-thread"
14103                 wait_update $i \
14104                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14105                         "R" 20 ||
14106                         error "$i: GC-thread not found in R-state"
14107                 # check umounts of each MDT on MDS have reached kthread_stop()
14108                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14109                         error "$i: expected $nb umount"
14110                 wait_update $i \
14111                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14112                         error "$i: umount not found in D-state"
14113         done
14114
14115         # release all GC-threads
14116         do_nodes $mdts $LCTL set_param fail_loc=0
14117
14118         # wait for MDT stop to complete
14119         for i in $(seq $MDSCOUNT); do
14120                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14121         done
14122
14123         # XXX
14124         # may try to check if any orphan changelog records are present
14125         # via ldiskfs/zfs and llog_reader...
14126
14127         # re-start/mount MDTs
14128         for i in $(seq $MDSCOUNT); do
14129                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14130                         error "Fail to start mds$i"
14131         done
14132
14133         local first_rec
14134         for i in $(seq $MDSCOUNT); do
14135                 # check cl_user1 still registered
14136                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14137                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14138                 # check cl_user2 unregistered
14139                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14140                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14141
14142                 # check changelogs are present and starting at $user_rec1 + 1
14143                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14144                 [ -n "$user_rec1" ] ||
14145                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14146                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14147                             awk '{ print $1; exit; }')
14148
14149                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14150                 [ $((user_rec1 + 1)) == $first_rec ] ||
14151                         error "mds$i: first index should be $user_rec1 + 1, " \
14152                               "but is $first_rec"
14153         done
14154 }
14155 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14156               "during mount"
14157
14158 test_160i() {
14159
14160         local mdts=$(comma_list $(mdts_nodes))
14161
14162         changelog_register || error "first changelog_register failed"
14163
14164         # generate some changelog records to accumulate on each MDT
14165         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
14166         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14167                 error "create $DIR/$tdir/$tfile failed"
14168
14169         # check changelogs have been generated
14170         local nbcl=$(changelog_dump | wc -l)
14171         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14172
14173         # simulate race between register and unregister
14174         # XXX as fail_loc is set per-MDS, with DNE configs the race
14175         # simulation will only occur for one MDT per MDS and for the
14176         # others the normal race scenario will take place
14177         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14178         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14179         do_nodes $mdts $LCTL set_param fail_val=1
14180
14181         # unregister 1st user
14182         changelog_deregister &
14183         local pid1=$!
14184         # wait some time for deregister work to reach race rdv
14185         sleep 2
14186         # register 2nd user
14187         changelog_register || error "2nd user register failed"
14188
14189         wait $pid1 || error "1st user deregister failed"
14190
14191         local i
14192         local last_rec
14193         declare -A LAST_REC
14194         for i in $(seq $MDSCOUNT); do
14195                 if changelog_users mds$i | grep "^cl"; then
14196                         # make sure new records are added with one user present
14197                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14198                                           awk '/^current.index:/ { print $NF }')
14199                 else
14200                         error "mds$i has no user registered"
14201                 fi
14202         done
14203
14204         # generate more changelog records to accumulate on each MDT
14205         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14206                 error "create $DIR/$tdir/${tfile}bis failed"
14207
14208         for i in $(seq $MDSCOUNT); do
14209                 last_rec=$(changelog_users $SINGLEMDS |
14210                            awk '/^current.index:/ { print $NF }')
14211                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14212                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14213                         error "changelogs are off on mds$i"
14214         done
14215 }
14216 run_test 160i "changelog user register/unregister race"
14217
14218 test_160j() {
14219         remote_mds_nodsh && skip "remote MDS with nodsh"
14220         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14221                 skip "Need MDS version at least 2.12.56"
14222
14223         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14224
14225         changelog_register || error "first changelog_register failed"
14226
14227         # generate some changelog
14228         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
14229         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14230                 error "create $DIR/$tdir/${tfile}bis failed"
14231
14232         # open the changelog device
14233         exec 3>/dev/changelog-$FSNAME-MDT0000
14234         exec 4</dev/changelog-$FSNAME-MDT0000
14235
14236         # umount the first lustre mount
14237         umount $MOUNT
14238
14239         # read changelog
14240         cat <&4 >/dev/null || error "read changelog failed"
14241
14242         # clear changelog
14243         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14244         changelog_users $SINGLEMDS | grep -q $cl_user ||
14245                 error "User $cl_user not found in changelog_users"
14246
14247         printf 'clear:'$cl_user':0' >&3
14248
14249         # close
14250         exec 3>&-
14251         exec 4<&-
14252
14253         # cleanup
14254         changelog_deregister || error "changelog_deregister failed"
14255
14256         umount $MOUNT2
14257         mount_client $MOUNT || error "mount_client on $MOUNT failed"
14258 }
14259 run_test 160j "client can be umounted  while its chanangelog is being used"
14260
14261 test_160k() {
14262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14263         remote_mds_nodsh && skip "remote MDS with nodsh"
14264
14265         mkdir -p $DIR/$tdir/1/1
14266
14267         changelog_register || error "changelog_register failed"
14268         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14269
14270         changelog_users $SINGLEMDS | grep -q $cl_user ||
14271                 error "User '$cl_user' not found in changelog_users"
14272 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14273         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
14274         rmdir $DIR/$tdir/1/1 & sleep 1
14275         mkdir $DIR/$tdir/2
14276         touch $DIR/$tdir/2/2
14277         rm -rf $DIR/$tdir/2
14278
14279         wait
14280         sleep 4
14281
14282         changelog_dump | grep rmdir || error "rmdir not recorded"
14283
14284         rm -rf $DIR/$tdir
14285         changelog_deregister
14286 }
14287 run_test 160k "Verify that changelog records are not lost"
14288
14289 test_161a() {
14290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14291
14292         test_mkdir -c1 $DIR/$tdir
14293         cp /etc/hosts $DIR/$tdir/$tfile
14294         test_mkdir -c1 $DIR/$tdir/foo1
14295         test_mkdir -c1 $DIR/$tdir/foo2
14296         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
14297         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
14298         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
14299         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
14300         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
14301         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14302                 $LFS fid2path $DIR $FID
14303                 error "bad link ea"
14304         fi
14305         # middle
14306         rm $DIR/$tdir/foo2/zachary
14307         # last
14308         rm $DIR/$tdir/foo2/thor
14309         # first
14310         rm $DIR/$tdir/$tfile
14311         # rename
14312         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
14313         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
14314                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
14315         rm $DIR/$tdir/foo2/maggie
14316
14317         # overflow the EA
14318         local longname=$tfile.avg_len_is_thirty_two_
14319         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
14320                 error_noexit 'failed to unlink many hardlinks'" EXIT
14321         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
14322                 error "failed to hardlink many files"
14323         links=$($LFS fid2path $DIR $FID | wc -l)
14324         echo -n "${links}/1000 links in link EA"
14325         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
14326 }
14327 run_test 161a "link ea sanity"
14328
14329 test_161b() {
14330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14331         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
14332
14333         local MDTIDX=1
14334         local remote_dir=$DIR/$tdir/remote_dir
14335
14336         mkdir -p $DIR/$tdir
14337         $LFS mkdir -i $MDTIDX $remote_dir ||
14338                 error "create remote directory failed"
14339
14340         cp /etc/hosts $remote_dir/$tfile
14341         mkdir -p $remote_dir/foo1
14342         mkdir -p $remote_dir/foo2
14343         ln $remote_dir/$tfile $remote_dir/foo1/sofia
14344         ln $remote_dir/$tfile $remote_dir/foo2/zachary
14345         ln $remote_dir/$tfile $remote_dir/foo1/luna
14346         ln $remote_dir/$tfile $remote_dir/foo2/thor
14347
14348         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
14349                      tr -d ']')
14350         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14351                 $LFS fid2path $DIR $FID
14352                 error "bad link ea"
14353         fi
14354         # middle
14355         rm $remote_dir/foo2/zachary
14356         # last
14357         rm $remote_dir/foo2/thor
14358         # first
14359         rm $remote_dir/$tfile
14360         # rename
14361         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
14362         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
14363         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
14364                 $LFS fid2path $DIR $FID
14365                 error "bad link rename"
14366         fi
14367         rm $remote_dir/foo2/maggie
14368
14369         # overflow the EA
14370         local longname=filename_avg_len_is_thirty_two_
14371         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
14372                 error "failed to hardlink many files"
14373         links=$($LFS fid2path $DIR $FID | wc -l)
14374         echo -n "${links}/1000 links in link EA"
14375         [[ ${links} -gt 60 ]] ||
14376                 error "expected at least 60 links in link EA"
14377         unlinkmany $remote_dir/foo2/$longname 1000 ||
14378         error "failed to unlink many hardlinks"
14379 }
14380 run_test 161b "link ea sanity under remote directory"
14381
14382 test_161c() {
14383         remote_mds_nodsh && skip "remote MDS with nodsh"
14384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14385         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
14386                 skip "Need MDS version at least 2.1.5"
14387
14388         # define CLF_RENAME_LAST 0x0001
14389         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
14390         changelog_register || error "changelog_register failed"
14391
14392         rm -rf $DIR/$tdir
14393         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
14394         touch $DIR/$tdir/foo_161c
14395         touch $DIR/$tdir/bar_161c
14396         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14397         changelog_dump | grep RENME | tail -n 5
14398         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14399         changelog_clear 0 || error "changelog_clear failed"
14400         if [ x$flags != "x0x1" ]; then
14401                 error "flag $flags is not 0x1"
14402         fi
14403
14404         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
14405         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
14406         touch $DIR/$tdir/foo_161c
14407         touch $DIR/$tdir/bar_161c
14408         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14409         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14410         changelog_dump | grep RENME | tail -n 5
14411         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14412         changelog_clear 0 || error "changelog_clear failed"
14413         if [ x$flags != "x0x0" ]; then
14414                 error "flag $flags is not 0x0"
14415         fi
14416         echo "rename overwrite a target having nlink > 1," \
14417                 "changelog record has flags of $flags"
14418
14419         # rename doesn't overwrite a target (changelog flag 0x0)
14420         touch $DIR/$tdir/foo_161c
14421         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
14422         changelog_dump | grep RENME | tail -n 5
14423         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
14424         changelog_clear 0 || error "changelog_clear failed"
14425         if [ x$flags != "x0x0" ]; then
14426                 error "flag $flags is not 0x0"
14427         fi
14428         echo "rename doesn't overwrite a target," \
14429                 "changelog record has flags of $flags"
14430
14431         # define CLF_UNLINK_LAST 0x0001
14432         # unlink a file having nlink = 1 (changelog flag 0x1)
14433         rm -f $DIR/$tdir/foo2_161c
14434         changelog_dump | grep UNLNK | tail -n 5
14435         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14436         changelog_clear 0 || error "changelog_clear failed"
14437         if [ x$flags != "x0x1" ]; then
14438                 error "flag $flags is not 0x1"
14439         fi
14440         echo "unlink a file having nlink = 1," \
14441                 "changelog record has flags of $flags"
14442
14443         # unlink a file having nlink > 1 (changelog flag 0x0)
14444         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14445         rm -f $DIR/$tdir/foobar_161c
14446         changelog_dump | grep UNLNK | tail -n 5
14447         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14448         changelog_clear 0 || error "changelog_clear failed"
14449         if [ x$flags != "x0x0" ]; then
14450                 error "flag $flags is not 0x0"
14451         fi
14452         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
14453 }
14454 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
14455
14456 test_161d() {
14457         remote_mds_nodsh && skip "remote MDS with nodsh"
14458         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
14459
14460         local pid
14461         local fid
14462
14463         changelog_register || error "changelog_register failed"
14464
14465         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
14466         # interfer with $MOUNT/.lustre/fid/ access
14467         mkdir $DIR/$tdir
14468         [[ $? -eq 0 ]] || error "mkdir failed"
14469
14470         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
14471         $LCTL set_param fail_loc=0x8000140c
14472         # 5s pause
14473         $LCTL set_param fail_val=5
14474
14475         # create file
14476         echo foofoo > $DIR/$tdir/$tfile &
14477         pid=$!
14478
14479         # wait for create to be delayed
14480         sleep 2
14481
14482         ps -p $pid
14483         [[ $? -eq 0 ]] || error "create should be blocked"
14484
14485         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
14486         stack_trap "rm -f $tempfile"
14487         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
14488         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
14489         # some delay may occur during ChangeLog publishing and file read just
14490         # above, that could allow file write to happen finally
14491         [[ -s $tempfile ]] && echo "file should be empty"
14492
14493         $LCTL set_param fail_loc=0
14494
14495         wait $pid
14496         [[ $? -eq 0 ]] || error "create failed"
14497 }
14498 run_test 161d "create with concurrent .lustre/fid access"
14499
14500 check_path() {
14501         local expected="$1"
14502         shift
14503         local fid="$2"
14504
14505         local path
14506         path=$($LFS fid2path "$@")
14507         local rc=$?
14508
14509         if [ $rc -ne 0 ]; then
14510                 error "path looked up of '$expected' failed: rc=$rc"
14511         elif [ "$path" != "$expected" ]; then
14512                 error "path looked up '$path' instead of '$expected'"
14513         else
14514                 echo "FID '$fid' resolves to path '$path' as expected"
14515         fi
14516 }
14517
14518 test_162a() { # was test_162
14519         test_mkdir -p -c1 $DIR/$tdir/d2
14520         touch $DIR/$tdir/d2/$tfile
14521         touch $DIR/$tdir/d2/x1
14522         touch $DIR/$tdir/d2/x2
14523         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
14524         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
14525         # regular file
14526         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
14527         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
14528
14529         # softlink
14530         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
14531         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
14532         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
14533
14534         # softlink to wrong file
14535         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
14536         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
14537         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
14538
14539         # hardlink
14540         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
14541         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
14542         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
14543         # fid2path dir/fsname should both work
14544         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
14545         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
14546
14547         # hardlink count: check that there are 2 links
14548         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
14549         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
14550
14551         # hardlink indexing: remove the first link
14552         rm $DIR/$tdir/d2/p/q/r/hlink
14553         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
14554 }
14555 run_test 162a "path lookup sanity"
14556
14557 test_162b() {
14558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14559         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14560
14561         mkdir $DIR/$tdir
14562         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
14563                                 error "create striped dir failed"
14564
14565         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
14566                                         tail -n 1 | awk '{print $2}')
14567         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
14568
14569         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
14570         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
14571
14572         # regular file
14573         for ((i=0;i<5;i++)); do
14574                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
14575                         error "get fid for f$i failed"
14576                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
14577
14578                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
14579                         error "get fid for d$i failed"
14580                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
14581         done
14582
14583         return 0
14584 }
14585 run_test 162b "striped directory path lookup sanity"
14586
14587 # LU-4239: Verify fid2path works with paths 100 or more directories deep
14588 test_162c() {
14589         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
14590                 skip "Need MDS version at least 2.7.51"
14591
14592         local lpath=$tdir.local
14593         local rpath=$tdir.remote
14594
14595         test_mkdir $DIR/$lpath
14596         test_mkdir $DIR/$rpath
14597
14598         for ((i = 0; i <= 101; i++)); do
14599                 lpath="$lpath/$i"
14600                 mkdir $DIR/$lpath
14601                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
14602                         error "get fid for local directory $DIR/$lpath failed"
14603                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
14604
14605                 rpath="$rpath/$i"
14606                 test_mkdir $DIR/$rpath
14607                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
14608                         error "get fid for remote directory $DIR/$rpath failed"
14609                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
14610         done
14611
14612         return 0
14613 }
14614 run_test 162c "fid2path works with paths 100 or more directories deep"
14615
14616 test_169() {
14617         # do directio so as not to populate the page cache
14618         log "creating a 10 Mb file"
14619         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14620         log "starting reads"
14621         dd if=$DIR/$tfile of=/dev/null bs=4096 &
14622         log "truncating the file"
14623         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14624         log "killing dd"
14625         kill %+ || true # reads might have finished
14626         echo "wait until dd is finished"
14627         wait
14628         log "removing the temporary file"
14629         rm -rf $DIR/$tfile || error "tmp file removal failed"
14630 }
14631 run_test 169 "parallel read and truncate should not deadlock"
14632
14633 test_170() {
14634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14635
14636         $LCTL clear     # bug 18514
14637         $LCTL debug_daemon start $TMP/${tfile}_log_good
14638         touch $DIR/$tfile
14639         $LCTL debug_daemon stop
14640         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
14641                 error "sed failed to read log_good"
14642
14643         $LCTL debug_daemon start $TMP/${tfile}_log_good
14644         rm -rf $DIR/$tfile
14645         $LCTL debug_daemon stop
14646
14647         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
14648                error "lctl df log_bad failed"
14649
14650         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14651         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14652
14653         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
14654         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
14655
14656         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
14657                 error "bad_line good_line1 good_line2 are empty"
14658
14659         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14660         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
14661         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14662
14663         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
14664         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14665         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14666
14667         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
14668                 error "bad_line_new good_line_new are empty"
14669
14670         local expected_good=$((good_line1 + good_line2*2))
14671
14672         rm -f $TMP/${tfile}*
14673         # LU-231, short malformed line may not be counted into bad lines
14674         if [ $bad_line -ne $bad_line_new ] &&
14675                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
14676                 error "expected $bad_line bad lines, but got $bad_line_new"
14677                 return 1
14678         fi
14679
14680         if [ $expected_good -ne $good_line_new ]; then
14681                 error "expected $expected_good good lines, but got $good_line_new"
14682                 return 2
14683         fi
14684         true
14685 }
14686 run_test 170 "test lctl df to handle corrupted log ====================="
14687
14688 test_171() { # bug20592
14689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14690
14691         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
14692         $LCTL set_param fail_loc=0x50e
14693         $LCTL set_param fail_val=3000
14694         multiop_bg_pause $DIR/$tfile O_s || true
14695         local MULTIPID=$!
14696         kill -USR1 $MULTIPID
14697         # cause log dump
14698         sleep 3
14699         wait $MULTIPID
14700         if dmesg | grep "recursive fault"; then
14701                 error "caught a recursive fault"
14702         fi
14703         $LCTL set_param fail_loc=0
14704         true
14705 }
14706 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
14707
14708 # it would be good to share it with obdfilter-survey/iokit-libecho code
14709 setup_obdecho_osc () {
14710         local rc=0
14711         local ost_nid=$1
14712         local obdfilter_name=$2
14713         echo "Creating new osc for $obdfilter_name on $ost_nid"
14714         # make sure we can find loopback nid
14715         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
14716
14717         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
14718                            ${obdfilter_name}_osc_UUID || rc=2; }
14719         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
14720                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
14721         return $rc
14722 }
14723
14724 cleanup_obdecho_osc () {
14725         local obdfilter_name=$1
14726         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
14727         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
14728         return 0
14729 }
14730
14731 obdecho_test() {
14732         local OBD=$1
14733         local node=$2
14734         local pages=${3:-64}
14735         local rc=0
14736         local id
14737
14738         local count=10
14739         local obd_size=$(get_obd_size $node $OBD)
14740         local page_size=$(get_page_size $node)
14741         if [[ -n "$obd_size" ]]; then
14742                 local new_count=$((obd_size / (pages * page_size / 1024)))
14743                 [[ $new_count -ge $count ]] || count=$new_count
14744         fi
14745
14746         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
14747         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
14748                            rc=2; }
14749         if [ $rc -eq 0 ]; then
14750             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
14751             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
14752         fi
14753         echo "New object id is $id"
14754         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
14755                            rc=4; }
14756         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
14757                            "test_brw $count w v $pages $id" || rc=4; }
14758         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
14759                            rc=4; }
14760         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
14761                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
14762         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
14763                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
14764         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
14765         return $rc
14766 }
14767
14768 test_180a() {
14769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14770
14771         if ! module_loaded obdecho; then
14772                 load_module obdecho/obdecho &&
14773                         stack_trap "rmmod obdecho" EXIT ||
14774                         error "unable to load obdecho on client"
14775         fi
14776
14777         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
14778         local host=$($LCTL get_param -n osc.$osc.import |
14779                      awk '/current_connection:/ { print $2 }' )
14780         local target=$($LCTL get_param -n osc.$osc.import |
14781                        awk '/target:/ { print $2 }' )
14782         target=${target%_UUID}
14783
14784         if [ -n "$target" ]; then
14785                 setup_obdecho_osc $host $target &&
14786                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
14787                         { error "obdecho setup failed with $?"; return; }
14788
14789                 obdecho_test ${target}_osc client ||
14790                         error "obdecho_test failed on ${target}_osc"
14791         else
14792                 $LCTL get_param osc.$osc.import
14793                 error "there is no osc.$osc.import target"
14794         fi
14795 }
14796 run_test 180a "test obdecho on osc"
14797
14798 test_180b() {
14799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14800         remote_ost_nodsh && skip "remote OST with nodsh"
14801
14802         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14803                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14804                 error "failed to load module obdecho"
14805
14806         local target=$(do_facet ost1 $LCTL dl |
14807                        awk '/obdfilter/ { print $4; exit; }')
14808
14809         if [ -n "$target" ]; then
14810                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
14811         else
14812                 do_facet ost1 $LCTL dl
14813                 error "there is no obdfilter target on ost1"
14814         fi
14815 }
14816 run_test 180b "test obdecho directly on obdfilter"
14817
14818 test_180c() { # LU-2598
14819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14820         remote_ost_nodsh && skip "remote OST with nodsh"
14821         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
14822                 skip "Need MDS version at least 2.4.0"
14823
14824         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14825                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14826                 error "failed to load module obdecho"
14827
14828         local target=$(do_facet ost1 $LCTL dl |
14829                        awk '/obdfilter/ { print $4; exit; }')
14830
14831         if [ -n "$target" ]; then
14832                 local pages=16384 # 64MB bulk I/O RPC size
14833
14834                 obdecho_test "$target" ost1 "$pages" ||
14835                         error "obdecho_test with pages=$pages failed with $?"
14836         else
14837                 do_facet ost1 $LCTL dl
14838                 error "there is no obdfilter target on ost1"
14839         fi
14840 }
14841 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
14842
14843 test_181() { # bug 22177
14844         test_mkdir $DIR/$tdir
14845         # create enough files to index the directory
14846         createmany -o $DIR/$tdir/foobar 4000
14847         # print attributes for debug purpose
14848         lsattr -d .
14849         # open dir
14850         multiop_bg_pause $DIR/$tdir D_Sc || return 1
14851         MULTIPID=$!
14852         # remove the files & current working dir
14853         unlinkmany $DIR/$tdir/foobar 4000
14854         rmdir $DIR/$tdir
14855         kill -USR1 $MULTIPID
14856         wait $MULTIPID
14857         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
14858         return 0
14859 }
14860 run_test 181 "Test open-unlinked dir ========================"
14861
14862 test_182() {
14863         local fcount=1000
14864         local tcount=10
14865
14866         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14867
14868         $LCTL set_param mdc.*.rpc_stats=clear
14869
14870         for (( i = 0; i < $tcount; i++ )) ; do
14871                 mkdir $DIR/$tdir/$i
14872         done
14873
14874         for (( i = 0; i < $tcount; i++ )) ; do
14875                 createmany -o $DIR/$tdir/$i/f- $fcount &
14876         done
14877         wait
14878
14879         for (( i = 0; i < $tcount; i++ )) ; do
14880                 unlinkmany $DIR/$tdir/$i/f- $fcount &
14881         done
14882         wait
14883
14884         $LCTL get_param mdc.*.rpc_stats
14885
14886         rm -rf $DIR/$tdir
14887 }
14888 run_test 182 "Test parallel modify metadata operations ================"
14889
14890 test_183() { # LU-2275
14891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14892         remote_mds_nodsh && skip "remote MDS with nodsh"
14893         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
14894                 skip "Need MDS version at least 2.3.56"
14895
14896         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14897         echo aaa > $DIR/$tdir/$tfile
14898
14899 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
14900         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
14901
14902         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
14903         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
14904
14905         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
14906
14907         # Flush negative dentry cache
14908         touch $DIR/$tdir/$tfile
14909
14910         # We are not checking for any leaked references here, they'll
14911         # become evident next time we do cleanup with module unload.
14912         rm -rf $DIR/$tdir
14913 }
14914 run_test 183 "No crash or request leak in case of strange dispositions ========"
14915
14916 # test suite 184 is for LU-2016, LU-2017
14917 test_184a() {
14918         check_swap_layouts_support
14919
14920         dir0=$DIR/$tdir/$testnum
14921         test_mkdir -p -c1 $dir0
14922         ref1=/etc/passwd
14923         ref2=/etc/group
14924         file1=$dir0/f1
14925         file2=$dir0/f2
14926         $LFS setstripe -c1 $file1
14927         cp $ref1 $file1
14928         $LFS setstripe -c2 $file2
14929         cp $ref2 $file2
14930         gen1=$($LFS getstripe -g $file1)
14931         gen2=$($LFS getstripe -g $file2)
14932
14933         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
14934         gen=$($LFS getstripe -g $file1)
14935         [[ $gen1 != $gen ]] ||
14936                 "Layout generation on $file1 does not change"
14937         gen=$($LFS getstripe -g $file2)
14938         [[ $gen2 != $gen ]] ||
14939                 "Layout generation on $file2 does not change"
14940
14941         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
14942         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
14943
14944         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
14945 }
14946 run_test 184a "Basic layout swap"
14947
14948 test_184b() {
14949         check_swap_layouts_support
14950
14951         dir0=$DIR/$tdir/$testnum
14952         mkdir -p $dir0 || error "creating dir $dir0"
14953         file1=$dir0/f1
14954         file2=$dir0/f2
14955         file3=$dir0/f3
14956         dir1=$dir0/d1
14957         dir2=$dir0/d2
14958         mkdir $dir1 $dir2
14959         $LFS setstripe -c1 $file1
14960         $LFS setstripe -c2 $file2
14961         $LFS setstripe -c1 $file3
14962         chown $RUNAS_ID $file3
14963         gen1=$($LFS getstripe -g $file1)
14964         gen2=$($LFS getstripe -g $file2)
14965
14966         $LFS swap_layouts $dir1 $dir2 &&
14967                 error "swap of directories layouts should fail"
14968         $LFS swap_layouts $dir1 $file1 &&
14969                 error "swap of directory and file layouts should fail"
14970         $RUNAS $LFS swap_layouts $file1 $file2 &&
14971                 error "swap of file we cannot write should fail"
14972         $LFS swap_layouts $file1 $file3 &&
14973                 error "swap of file with different owner should fail"
14974         /bin/true # to clear error code
14975 }
14976 run_test 184b "Forbidden layout swap (will generate errors)"
14977
14978 test_184c() {
14979         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
14980         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
14981         check_swap_layouts_support
14982
14983         local dir0=$DIR/$tdir/$testnum
14984         mkdir -p $dir0 || error "creating dir $dir0"
14985
14986         local ref1=$dir0/ref1
14987         local ref2=$dir0/ref2
14988         local file1=$dir0/file1
14989         local file2=$dir0/file2
14990         # create a file large enough for the concurrent test
14991         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
14992         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
14993         echo "ref file size: ref1($(stat -c %s $ref1))," \
14994              "ref2($(stat -c %s $ref2))"
14995
14996         cp $ref2 $file2
14997         dd if=$ref1 of=$file1 bs=16k &
14998         local DD_PID=$!
14999
15000         # Make sure dd starts to copy file
15001         while [ ! -f $file1 ]; do sleep 0.1; done
15002
15003         $LFS swap_layouts $file1 $file2
15004         local rc=$?
15005         wait $DD_PID
15006         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
15007         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
15008
15009         # how many bytes copied before swapping layout
15010         local copied=$(stat -c %s $file2)
15011         local remaining=$(stat -c %s $ref1)
15012         remaining=$((remaining - copied))
15013         echo "Copied $copied bytes before swapping layout..."
15014
15015         cmp -n $copied $file1 $ref2 | grep differ &&
15016                 error "Content mismatch [0, $copied) of ref2 and file1"
15017         cmp -n $copied $file2 $ref1 ||
15018                 error "Content mismatch [0, $copied) of ref1 and file2"
15019         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
15020                 error "Content mismatch [$copied, EOF) of ref1 and file1"
15021
15022         # clean up
15023         rm -f $ref1 $ref2 $file1 $file2
15024 }
15025 run_test 184c "Concurrent write and layout swap"
15026
15027 test_184d() {
15028         check_swap_layouts_support
15029         [ -z "$(which getfattr 2>/dev/null)" ] &&
15030                 skip_env "no getfattr command"
15031
15032         local file1=$DIR/$tdir/$tfile-1
15033         local file2=$DIR/$tdir/$tfile-2
15034         local file3=$DIR/$tdir/$tfile-3
15035         local lovea1
15036         local lovea2
15037
15038         mkdir -p $DIR/$tdir
15039         touch $file1 || error "create $file1 failed"
15040         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15041                 error "create $file2 failed"
15042         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15043                 error "create $file3 failed"
15044         lovea1=$(get_layout_param $file1)
15045
15046         $LFS swap_layouts $file2 $file3 ||
15047                 error "swap $file2 $file3 layouts failed"
15048         $LFS swap_layouts $file1 $file2 ||
15049                 error "swap $file1 $file2 layouts failed"
15050
15051         lovea2=$(get_layout_param $file2)
15052         echo "$lovea1"
15053         echo "$lovea2"
15054         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
15055
15056         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15057         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
15058 }
15059 run_test 184d "allow stripeless layouts swap"
15060
15061 test_184e() {
15062         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
15063                 skip "Need MDS version at least 2.6.94"
15064         check_swap_layouts_support
15065         [ -z "$(which getfattr 2>/dev/null)" ] &&
15066                 skip_env "no getfattr command"
15067
15068         local file1=$DIR/$tdir/$tfile-1
15069         local file2=$DIR/$tdir/$tfile-2
15070         local file3=$DIR/$tdir/$tfile-3
15071         local lovea
15072
15073         mkdir -p $DIR/$tdir
15074         touch $file1 || error "create $file1 failed"
15075         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15076                 error "create $file2 failed"
15077         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15078                 error "create $file3 failed"
15079
15080         $LFS swap_layouts $file1 $file2 ||
15081                 error "swap $file1 $file2 layouts failed"
15082
15083         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15084         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
15085
15086         echo 123 > $file1 || error "Should be able to write into $file1"
15087
15088         $LFS swap_layouts $file1 $file3 ||
15089                 error "swap $file1 $file3 layouts failed"
15090
15091         echo 123 > $file1 || error "Should be able to write into $file1"
15092
15093         rm -rf $file1 $file2 $file3
15094 }
15095 run_test 184e "Recreate layout after stripeless layout swaps"
15096
15097 test_184f() {
15098         # Create a file with name longer than sizeof(struct stat) ==
15099         # 144 to see if we can get chars from the file name to appear
15100         # in the returned striping. Note that 'f' == 0x66.
15101         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
15102
15103         mkdir -p $DIR/$tdir
15104         mcreate $DIR/$tdir/$file
15105         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
15106                 error "IOC_MDC_GETFILEINFO returned garbage striping"
15107         fi
15108 }
15109 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
15110
15111 test_185() { # LU-2441
15112         # LU-3553 - no volatile file support in old servers
15113         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
15114                 skip "Need MDS version at least 2.3.60"
15115
15116         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15117         touch $DIR/$tdir/spoo
15118         local mtime1=$(stat -c "%Y" $DIR/$tdir)
15119         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
15120                 error "cannot create/write a volatile file"
15121         [ "$FILESET" == "" ] &&
15122         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
15123                 error "FID is still valid after close"
15124
15125         multiop_bg_pause $DIR/$tdir vVw4096_c
15126         local multi_pid=$!
15127
15128         local OLD_IFS=$IFS
15129         IFS=":"
15130         local fidv=($fid)
15131         IFS=$OLD_IFS
15132         # assume that the next FID for this client is sequential, since stdout
15133         # is unfortunately eaten by multiop_bg_pause
15134         local n=$((${fidv[1]} + 1))
15135         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
15136         if [ "$FILESET" == "" ]; then
15137                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
15138                         error "FID is missing before close"
15139         fi
15140         kill -USR1 $multi_pid
15141         # 1 second delay, so if mtime change we will see it
15142         sleep 1
15143         local mtime2=$(stat -c "%Y" $DIR/$tdir)
15144         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
15145 }
15146 run_test 185 "Volatile file support"
15147
15148 function create_check_volatile() {
15149         local idx=$1
15150         local tgt
15151
15152         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
15153         local PID=$!
15154         sleep 1
15155         local FID=$(cat /tmp/${tfile}.fid)
15156         [ "$FID" == "" ] && error "can't get FID for volatile"
15157         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
15158         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
15159         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
15160         kill -USR1 $PID
15161         wait
15162         sleep 1
15163         cancel_lru_locks mdc # flush opencache
15164         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
15165         return 0
15166 }
15167
15168 test_185a(){
15169         # LU-12516 - volatile creation via .lustre
15170         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
15171                 skip "Need MDS version at least 2.3.55"
15172
15173         create_check_volatile 0
15174         [ $MDSCOUNT -lt 2 ] && return 0
15175
15176         # DNE case
15177         create_check_volatile 1
15178
15179         return 0
15180 }
15181 run_test 185a "Volatile file creation in .lustre/fid/"
15182
15183 test_187a() {
15184         remote_mds_nodsh && skip "remote MDS with nodsh"
15185         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15186                 skip "Need MDS version at least 2.3.0"
15187
15188         local dir0=$DIR/$tdir/$testnum
15189         mkdir -p $dir0 || error "creating dir $dir0"
15190
15191         local file=$dir0/file1
15192         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
15193         local dv1=$($LFS data_version $file)
15194         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
15195         local dv2=$($LFS data_version $file)
15196         [[ $dv1 != $dv2 ]] ||
15197                 error "data version did not change on write $dv1 == $dv2"
15198
15199         # clean up
15200         rm -f $file1
15201 }
15202 run_test 187a "Test data version change"
15203
15204 test_187b() {
15205         remote_mds_nodsh && skip "remote MDS with nodsh"
15206         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15207                 skip "Need MDS version at least 2.3.0"
15208
15209         local dir0=$DIR/$tdir/$testnum
15210         mkdir -p $dir0 || error "creating dir $dir0"
15211
15212         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
15213         [[ ${DV[0]} != ${DV[1]} ]] ||
15214                 error "data version did not change on write"\
15215                       " ${DV[0]} == ${DV[1]}"
15216
15217         # clean up
15218         rm -f $file1
15219 }
15220 run_test 187b "Test data version change on volatile file"
15221
15222 test_200() {
15223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15224         remote_mgs_nodsh && skip "remote MGS with nodsh"
15225         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15226
15227         local POOL=${POOL:-cea1}
15228         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
15229         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
15230         # Pool OST targets
15231         local first_ost=0
15232         local last_ost=$(($OSTCOUNT - 1))
15233         local ost_step=2
15234         local ost_list=$(seq $first_ost $ost_step $last_ost)
15235         local ost_range="$first_ost $last_ost $ost_step"
15236         local test_path=$POOL_ROOT/$POOL_DIR_NAME
15237         local file_dir=$POOL_ROOT/file_tst
15238         local subdir=$test_path/subdir
15239         local rc=0
15240
15241         while : ; do
15242                 # former test_200a test_200b
15243                 pool_add $POOL                          || { rc=$? ; break; }
15244                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
15245                 # former test_200c test_200d
15246                 mkdir -p $test_path
15247                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
15248                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
15249                 mkdir -p $subdir
15250                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
15251                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
15252                                                         || { rc=$? ; break; }
15253                 # former test_200e test_200f
15254                 local files=$((OSTCOUNT*3))
15255                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
15256                                                         || { rc=$? ; break; }
15257                 pool_create_files $POOL $file_dir $files "$ost_list" \
15258                                                         || { rc=$? ; break; }
15259                 # former test_200g test_200h
15260                 pool_lfs_df $POOL                       || { rc=$? ; break; }
15261                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
15262
15263                 # former test_201a test_201b test_201c
15264                 pool_remove_first_target $POOL          || { rc=$? ; break; }
15265
15266                 local f=$test_path/$tfile
15267                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
15268                 pool_remove $POOL $f                    || { rc=$? ; break; }
15269                 break
15270         done
15271
15272         destroy_test_pools
15273
15274         return $rc
15275 }
15276 run_test 200 "OST pools"
15277
15278 # usage: default_attr <count | size | offset>
15279 default_attr() {
15280         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
15281 }
15282
15283 # usage: check_default_stripe_attr
15284 check_default_stripe_attr() {
15285         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
15286         case $1 in
15287         --stripe-count|-c)
15288                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
15289         --stripe-size|-S)
15290                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
15291         --stripe-index|-i)
15292                 EXPECTED=-1;;
15293         *)
15294                 error "unknown getstripe attr '$1'"
15295         esac
15296
15297         [ $ACTUAL == $EXPECTED ] ||
15298                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
15299 }
15300
15301 test_204a() {
15302         test_mkdir $DIR/$tdir
15303         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
15304
15305         check_default_stripe_attr --stripe-count
15306         check_default_stripe_attr --stripe-size
15307         check_default_stripe_attr --stripe-index
15308 }
15309 run_test 204a "Print default stripe attributes"
15310
15311 test_204b() {
15312         test_mkdir $DIR/$tdir
15313         $LFS setstripe --stripe-count 1 $DIR/$tdir
15314
15315         check_default_stripe_attr --stripe-size
15316         check_default_stripe_attr --stripe-index
15317 }
15318 run_test 204b "Print default stripe size and offset"
15319
15320 test_204c() {
15321         test_mkdir $DIR/$tdir
15322         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15323
15324         check_default_stripe_attr --stripe-count
15325         check_default_stripe_attr --stripe-index
15326 }
15327 run_test 204c "Print default stripe count and offset"
15328
15329 test_204d() {
15330         test_mkdir $DIR/$tdir
15331         $LFS setstripe --stripe-index 0 $DIR/$tdir
15332
15333         check_default_stripe_attr --stripe-count
15334         check_default_stripe_attr --stripe-size
15335 }
15336 run_test 204d "Print default stripe count and size"
15337
15338 test_204e() {
15339         test_mkdir $DIR/$tdir
15340         $LFS setstripe -d $DIR/$tdir
15341
15342         check_default_stripe_attr --stripe-count --raw
15343         check_default_stripe_attr --stripe-size --raw
15344         check_default_stripe_attr --stripe-index --raw
15345 }
15346 run_test 204e "Print raw stripe attributes"
15347
15348 test_204f() {
15349         test_mkdir $DIR/$tdir
15350         $LFS setstripe --stripe-count 1 $DIR/$tdir
15351
15352         check_default_stripe_attr --stripe-size --raw
15353         check_default_stripe_attr --stripe-index --raw
15354 }
15355 run_test 204f "Print raw stripe size and offset"
15356
15357 test_204g() {
15358         test_mkdir $DIR/$tdir
15359         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15360
15361         check_default_stripe_attr --stripe-count --raw
15362         check_default_stripe_attr --stripe-index --raw
15363 }
15364 run_test 204g "Print raw stripe count and offset"
15365
15366 test_204h() {
15367         test_mkdir $DIR/$tdir
15368         $LFS setstripe --stripe-index 0 $DIR/$tdir
15369
15370         check_default_stripe_attr --stripe-count --raw
15371         check_default_stripe_attr --stripe-size --raw
15372 }
15373 run_test 204h "Print raw stripe count and size"
15374
15375 # Figure out which job scheduler is being used, if any,
15376 # or use a fake one
15377 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
15378         JOBENV=SLURM_JOB_ID
15379 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
15380         JOBENV=LSB_JOBID
15381 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
15382         JOBENV=PBS_JOBID
15383 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
15384         JOBENV=LOADL_STEP_ID
15385 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
15386         JOBENV=JOB_ID
15387 else
15388         $LCTL list_param jobid_name > /dev/null 2>&1
15389         if [ $? -eq 0 ]; then
15390                 JOBENV=nodelocal
15391         else
15392                 JOBENV=FAKE_JOBID
15393         fi
15394 fi
15395 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
15396
15397 verify_jobstats() {
15398         local cmd=($1)
15399         shift
15400         local facets="$@"
15401
15402 # we don't really need to clear the stats for this test to work, since each
15403 # command has a unique jobid, but it makes debugging easier if needed.
15404 #       for facet in $facets; do
15405 #               local dev=$(convert_facet2label $facet)
15406 #               # clear old jobstats
15407 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
15408 #       done
15409
15410         # use a new JobID for each test, or we might see an old one
15411         [ "$JOBENV" = "FAKE_JOBID" ] &&
15412                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
15413
15414         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
15415
15416         [ "$JOBENV" = "nodelocal" ] && {
15417                 FAKE_JOBID=id.$testnum.%e.$RANDOM
15418                 $LCTL set_param jobid_name=$FAKE_JOBID
15419                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
15420         }
15421
15422         log "Test: ${cmd[*]}"
15423         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
15424
15425         if [ $JOBENV = "FAKE_JOBID" ]; then
15426                 FAKE_JOBID=$JOBVAL ${cmd[*]}
15427         else
15428                 ${cmd[*]}
15429         fi
15430
15431         # all files are created on OST0000
15432         for facet in $facets; do
15433                 local stats="*.$(convert_facet2label $facet).job_stats"
15434
15435                 # strip out libtool wrappers for in-tree executables
15436                 if [ $(do_facet $facet lctl get_param $stats |
15437                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
15438                         do_facet $facet lctl get_param $stats
15439                         error "No jobstats for $JOBVAL found on $facet::$stats"
15440                 fi
15441         done
15442 }
15443
15444 jobstats_set() {
15445         local new_jobenv=$1
15446
15447         set_persistent_param_and_check client "jobid_var" \
15448                 "$FSNAME.sys.jobid_var" $new_jobenv
15449 }
15450
15451 test_205() { # Job stats
15452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15453         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
15454                 skip "Need MDS version with at least 2.7.1"
15455         remote_mgs_nodsh && skip "remote MGS with nodsh"
15456         remote_mds_nodsh && skip "remote MDS with nodsh"
15457         remote_ost_nodsh && skip "remote OST with nodsh"
15458         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
15459                 skip "Server doesn't support jobstats"
15460         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
15461
15462         local old_jobenv=$($LCTL get_param -n jobid_var)
15463         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
15464
15465         if [[ $PERM_CMD == *"set_param -P"* ]]; then
15466                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
15467         else
15468                 stack_trap "do_facet mgs $PERM_CMD \
15469                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
15470         fi
15471         changelog_register
15472
15473         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
15474                                 mdt.*.job_cleanup_interval | head -n 1)
15475         local new_interval=5
15476         do_facet $SINGLEMDS \
15477                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
15478         stack_trap "do_facet $SINGLEMDS \
15479                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
15480         local start=$SECONDS
15481
15482         local cmd
15483         # mkdir
15484         cmd="mkdir $DIR/$tdir"
15485         verify_jobstats "$cmd" "$SINGLEMDS"
15486         # rmdir
15487         cmd="rmdir $DIR/$tdir"
15488         verify_jobstats "$cmd" "$SINGLEMDS"
15489         # mkdir on secondary MDT
15490         if [ $MDSCOUNT -gt 1 ]; then
15491                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
15492                 verify_jobstats "$cmd" "mds2"
15493         fi
15494         # mknod
15495         cmd="mknod $DIR/$tfile c 1 3"
15496         verify_jobstats "$cmd" "$SINGLEMDS"
15497         # unlink
15498         cmd="rm -f $DIR/$tfile"
15499         verify_jobstats "$cmd" "$SINGLEMDS"
15500         # create all files on OST0000 so verify_jobstats can find OST stats
15501         # open & close
15502         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
15503         verify_jobstats "$cmd" "$SINGLEMDS"
15504         # setattr
15505         cmd="touch $DIR/$tfile"
15506         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15507         # write
15508         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
15509         verify_jobstats "$cmd" "ost1"
15510         # read
15511         cancel_lru_locks osc
15512         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
15513         verify_jobstats "$cmd" "ost1"
15514         # truncate
15515         cmd="$TRUNCATE $DIR/$tfile 0"
15516         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15517         # rename
15518         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
15519         verify_jobstats "$cmd" "$SINGLEMDS"
15520         # jobstats expiry - sleep until old stats should be expired
15521         local left=$((new_interval + 5 - (SECONDS - start)))
15522         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
15523                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
15524                         "0" $left
15525         cmd="mkdir $DIR/$tdir.expire"
15526         verify_jobstats "$cmd" "$SINGLEMDS"
15527         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
15528             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
15529
15530         # Ensure that jobid are present in changelog (if supported by MDS)
15531         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
15532                 changelog_dump | tail -10
15533                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
15534                 [ $jobids -eq 9 ] ||
15535                         error "Wrong changelog jobid count $jobids != 9"
15536
15537                 # LU-5862
15538                 JOBENV="disable"
15539                 jobstats_set $JOBENV
15540                 touch $DIR/$tfile
15541                 changelog_dump | grep $tfile
15542                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
15543                 [ $jobids -eq 0 ] ||
15544                         error "Unexpected jobids when jobid_var=$JOBENV"
15545         fi
15546
15547         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
15548         JOBENV="JOBCOMPLEX"
15549         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
15550
15551         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
15552 }
15553 run_test 205 "Verify job stats"
15554
15555 # LU-1480, LU-1773 and LU-1657
15556 test_206() {
15557         mkdir -p $DIR/$tdir
15558         $LFS setstripe -c -1 $DIR/$tdir
15559 #define OBD_FAIL_LOV_INIT 0x1403
15560         $LCTL set_param fail_loc=0xa0001403
15561         $LCTL set_param fail_val=1
15562         touch $DIR/$tdir/$tfile || true
15563 }
15564 run_test 206 "fail lov_init_raid0() doesn't lbug"
15565
15566 test_207a() {
15567         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15568         local fsz=`stat -c %s $DIR/$tfile`
15569         cancel_lru_locks mdc
15570
15571         # do not return layout in getattr intent
15572 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
15573         $LCTL set_param fail_loc=0x170
15574         local sz=`stat -c %s $DIR/$tfile`
15575
15576         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
15577
15578         rm -rf $DIR/$tfile
15579 }
15580 run_test 207a "can refresh layout at glimpse"
15581
15582 test_207b() {
15583         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15584         local cksum=`md5sum $DIR/$tfile`
15585         local fsz=`stat -c %s $DIR/$tfile`
15586         cancel_lru_locks mdc
15587         cancel_lru_locks osc
15588
15589         # do not return layout in getattr intent
15590 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
15591         $LCTL set_param fail_loc=0x171
15592
15593         # it will refresh layout after the file is opened but before read issues
15594         echo checksum is "$cksum"
15595         echo "$cksum" |md5sum -c --quiet || error "file differs"
15596
15597         rm -rf $DIR/$tfile
15598 }
15599 run_test 207b "can refresh layout at open"
15600
15601 test_208() {
15602         # FIXME: in this test suite, only RD lease is used. This is okay
15603         # for now as only exclusive open is supported. After generic lease
15604         # is done, this test suite should be revised. - Jinshan
15605
15606         remote_mds_nodsh && skip "remote MDS with nodsh"
15607         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
15608                 skip "Need MDS version at least 2.4.52"
15609
15610         echo "==== test 1: verify get lease work"
15611         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
15612
15613         echo "==== test 2: verify lease can be broken by upcoming open"
15614         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15615         local PID=$!
15616         sleep 1
15617
15618         $MULTIOP $DIR/$tfile oO_RDONLY:c
15619         kill -USR1 $PID && wait $PID || error "break lease error"
15620
15621         echo "==== test 3: verify lease can't be granted if an open already exists"
15622         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
15623         local PID=$!
15624         sleep 1
15625
15626         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
15627         kill -USR1 $PID && wait $PID || error "open file error"
15628
15629         echo "==== test 4: lease can sustain over recovery"
15630         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
15631         PID=$!
15632         sleep 1
15633
15634         fail mds1
15635
15636         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
15637
15638         echo "==== test 5: lease broken can't be regained by replay"
15639         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15640         PID=$!
15641         sleep 1
15642
15643         # open file to break lease and then recovery
15644         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
15645         fail mds1
15646
15647         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
15648
15649         rm -f $DIR/$tfile
15650 }
15651 run_test 208 "Exclusive open"
15652
15653 test_209() {
15654         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
15655                 skip_env "must have disp_stripe"
15656
15657         touch $DIR/$tfile
15658         sync; sleep 5; sync;
15659
15660         echo 3 > /proc/sys/vm/drop_caches
15661         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15662
15663         # open/close 500 times
15664         for i in $(seq 500); do
15665                 cat $DIR/$tfile
15666         done
15667
15668         echo 3 > /proc/sys/vm/drop_caches
15669         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15670
15671         echo "before: $req_before, after: $req_after"
15672         [ $((req_after - req_before)) -ge 300 ] &&
15673                 error "open/close requests are not freed"
15674         return 0
15675 }
15676 run_test 209 "read-only open/close requests should be freed promptly"
15677
15678 test_212() {
15679         size=`date +%s`
15680         size=$((size % 8192 + 1))
15681         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
15682         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
15683         rm -f $DIR/f212 $DIR/f212.xyz
15684 }
15685 run_test 212 "Sendfile test ============================================"
15686
15687 test_213() {
15688         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
15689         cancel_lru_locks osc
15690         lctl set_param fail_loc=0x8000040f
15691         # generate a read lock
15692         cat $DIR/$tfile > /dev/null
15693         # write to the file, it will try to cancel the above read lock.
15694         cat /etc/hosts >> $DIR/$tfile
15695 }
15696 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
15697
15698 test_214() { # for bug 20133
15699         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
15700         for (( i=0; i < 340; i++ )) ; do
15701                 touch $DIR/$tdir/d214c/a$i
15702         done
15703
15704         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
15705         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
15706         ls $DIR/d214c || error "ls $DIR/d214c failed"
15707         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
15708         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
15709 }
15710 run_test 214 "hash-indexed directory test - bug 20133"
15711
15712 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
15713 create_lnet_proc_files() {
15714         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
15715 }
15716
15717 # counterpart of create_lnet_proc_files
15718 remove_lnet_proc_files() {
15719         rm -f $TMP/lnet_$1.sys
15720 }
15721
15722 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15723 # 3rd arg as regexp for body
15724 check_lnet_proc_stats() {
15725         local l=$(cat "$TMP/lnet_$1" |wc -l)
15726         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
15727
15728         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
15729 }
15730
15731 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15732 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
15733 # optional and can be regexp for 2nd line (lnet.routes case)
15734 check_lnet_proc_entry() {
15735         local blp=2          # blp stands for 'position of 1st line of body'
15736         [ -z "$5" ] || blp=3 # lnet.routes case
15737
15738         local l=$(cat "$TMP/lnet_$1" |wc -l)
15739         # subtracting one from $blp because the body can be empty
15740         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
15741
15742         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
15743                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
15744
15745         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
15746                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
15747
15748         # bail out if any unexpected line happened
15749         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
15750         [ "$?" != 0 ] || error "$2 misformatted"
15751 }
15752
15753 test_215() { # for bugs 18102, 21079, 21517
15754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15755
15756         local N='(0|[1-9][0-9]*)'       # non-negative numeric
15757         local P='[1-9][0-9]*'           # positive numeric
15758         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
15759         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
15760         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
15761         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
15762
15763         local L1 # regexp for 1st line
15764         local L2 # regexp for 2nd line (optional)
15765         local BR # regexp for the rest (body)
15766
15767         # lnet.stats should look as 11 space-separated non-negative numerics
15768         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
15769         create_lnet_proc_files "stats"
15770         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
15771         remove_lnet_proc_files "stats"
15772
15773         # lnet.routes should look like this:
15774         # Routing disabled/enabled
15775         # net hops priority state router
15776         # where net is a string like tcp0, hops > 0, priority >= 0,
15777         # state is up/down,
15778         # router is a string like 192.168.1.1@tcp2
15779         L1="^Routing (disabled|enabled)$"
15780         L2="^net +hops +priority +state +router$"
15781         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
15782         create_lnet_proc_files "routes"
15783         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
15784         remove_lnet_proc_files "routes"
15785
15786         # lnet.routers should look like this:
15787         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
15788         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
15789         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
15790         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
15791         L1="^ref +rtr_ref +alive +router$"
15792         BR="^$P +$P +(up|down) +$NID$"
15793         create_lnet_proc_files "routers"
15794         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
15795         remove_lnet_proc_files "routers"
15796
15797         # lnet.peers should look like this:
15798         # nid refs state last max rtr min tx min queue
15799         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
15800         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
15801         # numeric (0 or >0 or <0), queue >= 0.
15802         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
15803         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
15804         create_lnet_proc_files "peers"
15805         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
15806         remove_lnet_proc_files "peers"
15807
15808         # lnet.buffers  should look like this:
15809         # pages count credits min
15810         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
15811         L1="^pages +count +credits +min$"
15812         BR="^ +$N +$N +$I +$I$"
15813         create_lnet_proc_files "buffers"
15814         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
15815         remove_lnet_proc_files "buffers"
15816
15817         # lnet.nis should look like this:
15818         # nid status alive refs peer rtr max tx min
15819         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
15820         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
15821         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
15822         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
15823         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
15824         create_lnet_proc_files "nis"
15825         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
15826         remove_lnet_proc_files "nis"
15827
15828         # can we successfully write to lnet.stats?
15829         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
15830 }
15831 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
15832
15833 test_216() { # bug 20317
15834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15835         remote_ost_nodsh && skip "remote OST with nodsh"
15836
15837         local node
15838         local facets=$(get_facets OST)
15839         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15840
15841         save_lustre_params client "osc.*.contention_seconds" > $p
15842         save_lustre_params $facets \
15843                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
15844         save_lustre_params $facets \
15845                 "ldlm.namespaces.filter-*.contended_locks" >> $p
15846         save_lustre_params $facets \
15847                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
15848         clear_stats osc.*.osc_stats
15849
15850         # agressive lockless i/o settings
15851         do_nodes $(comma_list $(osts_nodes)) \
15852                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
15853                         ldlm.namespaces.filter-*.contended_locks=0 \
15854                         ldlm.namespaces.filter-*.contention_seconds=60"
15855         lctl set_param -n osc.*.contention_seconds=60
15856
15857         $DIRECTIO write $DIR/$tfile 0 10 4096
15858         $CHECKSTAT -s 40960 $DIR/$tfile
15859
15860         # disable lockless i/o
15861         do_nodes $(comma_list $(osts_nodes)) \
15862                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
15863                         ldlm.namespaces.filter-*.contended_locks=32 \
15864                         ldlm.namespaces.filter-*.contention_seconds=0"
15865         lctl set_param -n osc.*.contention_seconds=0
15866         clear_stats osc.*.osc_stats
15867
15868         dd if=/dev/zero of=$DIR/$tfile count=0
15869         $CHECKSTAT -s 0 $DIR/$tfile
15870
15871         restore_lustre_params <$p
15872         rm -f $p
15873         rm $DIR/$tfile
15874 }
15875 run_test 216 "check lockless direct write updates file size and kms correctly"
15876
15877 test_217() { # bug 22430
15878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15879
15880         local node
15881         local nid
15882
15883         for node in $(nodes_list); do
15884                 nid=$(host_nids_address $node $NETTYPE)
15885                 if [[ $nid = *-* ]] ; then
15886                         echo "lctl ping $(h2nettype $nid)"
15887                         lctl ping $(h2nettype $nid)
15888                 else
15889                         echo "skipping $node (no hyphen detected)"
15890                 fi
15891         done
15892 }
15893 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
15894
15895 test_218() {
15896        # do directio so as not to populate the page cache
15897        log "creating a 10 Mb file"
15898        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15899        log "starting reads"
15900        dd if=$DIR/$tfile of=/dev/null bs=4096 &
15901        log "truncating the file"
15902        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15903        log "killing dd"
15904        kill %+ || true # reads might have finished
15905        echo "wait until dd is finished"
15906        wait
15907        log "removing the temporary file"
15908        rm -rf $DIR/$tfile || error "tmp file removal failed"
15909 }
15910 run_test 218 "parallel read and truncate should not deadlock"
15911
15912 test_219() {
15913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15914
15915         # write one partial page
15916         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
15917         # set no grant so vvp_io_commit_write will do sync write
15918         $LCTL set_param fail_loc=0x411
15919         # write a full page at the end of file
15920         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
15921
15922         $LCTL set_param fail_loc=0
15923         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
15924         $LCTL set_param fail_loc=0x411
15925         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
15926
15927         # LU-4201
15928         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
15929         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
15930 }
15931 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
15932
15933 test_220() { #LU-325
15934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15935         remote_ost_nodsh && skip "remote OST with nodsh"
15936         remote_mds_nodsh && skip "remote MDS with nodsh"
15937         remote_mgs_nodsh && skip "remote MGS with nodsh"
15938
15939         local OSTIDX=0
15940
15941         # create on MDT0000 so the last_id and next_id are correct
15942         mkdir $DIR/$tdir
15943         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
15944         OST=${OST%_UUID}
15945
15946         # on the mdt's osc
15947         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
15948         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
15949                         osp.$mdtosc_proc1.prealloc_last_id)
15950         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
15951                         osp.$mdtosc_proc1.prealloc_next_id)
15952
15953         $LFS df -i
15954
15955         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
15956         #define OBD_FAIL_OST_ENOINO              0x229
15957         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
15958         create_pool $FSNAME.$TESTNAME || return 1
15959         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
15960
15961         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
15962
15963         MDSOBJS=$((last_id - next_id))
15964         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
15965
15966         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
15967         echo "OST still has $count kbytes free"
15968
15969         echo "create $MDSOBJS files @next_id..."
15970         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
15971
15972         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15973                         osp.$mdtosc_proc1.prealloc_last_id)
15974         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15975                         osp.$mdtosc_proc1.prealloc_next_id)
15976
15977         echo "after creation, last_id=$last_id2, next_id=$next_id2"
15978         $LFS df -i
15979
15980         echo "cleanup..."
15981
15982         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
15983         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
15984
15985         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
15986                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
15987         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
15988                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
15989         echo "unlink $MDSOBJS files @$next_id..."
15990         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
15991 }
15992 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
15993
15994 test_221() {
15995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15996
15997         dd if=`which date` of=$MOUNT/date oflag=sync
15998         chmod +x $MOUNT/date
15999
16000         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
16001         $LCTL set_param fail_loc=0x80001401
16002
16003         $MOUNT/date > /dev/null
16004         rm -f $MOUNT/date
16005 }
16006 run_test 221 "make sure fault and truncate race to not cause OOM"
16007
16008 test_222a () {
16009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16010
16011         rm -rf $DIR/$tdir
16012         test_mkdir $DIR/$tdir
16013         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16014         createmany -o $DIR/$tdir/$tfile 10
16015         cancel_lru_locks mdc
16016         cancel_lru_locks osc
16017         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16018         $LCTL set_param fail_loc=0x31a
16019         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
16020         $LCTL set_param fail_loc=0
16021         rm -r $DIR/$tdir
16022 }
16023 run_test 222a "AGL for ls should not trigger CLIO lock failure"
16024
16025 test_222b () {
16026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16027
16028         rm -rf $DIR/$tdir
16029         test_mkdir $DIR/$tdir
16030         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16031         createmany -o $DIR/$tdir/$tfile 10
16032         cancel_lru_locks mdc
16033         cancel_lru_locks osc
16034         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16035         $LCTL set_param fail_loc=0x31a
16036         rm -r $DIR/$tdir || error "AGL for rmdir failed"
16037         $LCTL set_param fail_loc=0
16038 }
16039 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
16040
16041 test_223 () {
16042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16043
16044         rm -rf $DIR/$tdir
16045         test_mkdir $DIR/$tdir
16046         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16047         createmany -o $DIR/$tdir/$tfile 10
16048         cancel_lru_locks mdc
16049         cancel_lru_locks osc
16050         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
16051         $LCTL set_param fail_loc=0x31b
16052         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
16053         $LCTL set_param fail_loc=0
16054         rm -r $DIR/$tdir
16055 }
16056 run_test 223 "osc reenqueue if without AGL lock granted ======================="
16057
16058 test_224a() { # LU-1039, MRP-303
16059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16060
16061         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
16062         $LCTL set_param fail_loc=0x508
16063         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
16064         $LCTL set_param fail_loc=0
16065         df $DIR
16066 }
16067 run_test 224a "Don't panic on bulk IO failure"
16068
16069 test_224b() { # LU-1039, MRP-303
16070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16071
16072         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
16073         cancel_lru_locks osc
16074         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
16075         $LCTL set_param fail_loc=0x515
16076         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
16077         $LCTL set_param fail_loc=0
16078         df $DIR
16079 }
16080 run_test 224b "Don't panic on bulk IO failure"
16081
16082 test_224c() { # LU-6441
16083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16084         remote_mds_nodsh && skip "remote MDS with nodsh"
16085
16086         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16087         save_writethrough $p
16088         set_cache writethrough on
16089
16090         local pages_per_rpc=$($LCTL get_param \
16091                                 osc.*.max_pages_per_rpc)
16092         local at_max=$($LCTL get_param -n at_max)
16093         local timeout=$($LCTL get_param -n timeout)
16094         local test_at="at_max"
16095         local param_at="$FSNAME.sys.at_max"
16096         local test_timeout="timeout"
16097         local param_timeout="$FSNAME.sys.timeout"
16098
16099         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
16100
16101         set_persistent_param_and_check client "$test_at" "$param_at" 0
16102         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
16103
16104         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
16105         do_facet ost1 "$LCTL set_param fail_loc=0x520"
16106         $LFS setstripe -c 1 -i 0 $DIR/$tfile
16107         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
16108         sync
16109         do_facet ost1 "$LCTL set_param fail_loc=0"
16110
16111         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
16112         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
16113                 $timeout
16114
16115         $LCTL set_param -n $pages_per_rpc
16116         restore_lustre_params < $p
16117         rm -f $p
16118 }
16119 run_test 224c "Don't hang if one of md lost during large bulk RPC"
16120
16121 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
16122 test_225a () {
16123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16124         if [ -z ${MDSSURVEY} ]; then
16125                 skip_env "mds-survey not found"
16126         fi
16127         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16128                 skip "Need MDS version at least 2.2.51"
16129
16130         local mds=$(facet_host $SINGLEMDS)
16131         local target=$(do_nodes $mds 'lctl dl' |
16132                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16133
16134         local cmd1="file_count=1000 thrhi=4"
16135         local cmd2="dir_count=2 layer=mdd stripe_count=0"
16136         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16137         local cmd="$cmd1 $cmd2 $cmd3"
16138
16139         rm -f ${TMP}/mds_survey*
16140         echo + $cmd
16141         eval $cmd || error "mds-survey with zero-stripe failed"
16142         cat ${TMP}/mds_survey*
16143         rm -f ${TMP}/mds_survey*
16144 }
16145 run_test 225a "Metadata survey sanity with zero-stripe"
16146
16147 test_225b () {
16148         if [ -z ${MDSSURVEY} ]; then
16149                 skip_env "mds-survey not found"
16150         fi
16151         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16152                 skip "Need MDS version at least 2.2.51"
16153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16154         remote_mds_nodsh && skip "remote MDS with nodsh"
16155         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
16156                 skip_env "Need to mount OST to test"
16157         fi
16158
16159         local mds=$(facet_host $SINGLEMDS)
16160         local target=$(do_nodes $mds 'lctl dl' |
16161                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16162
16163         local cmd1="file_count=1000 thrhi=4"
16164         local cmd2="dir_count=2 layer=mdd stripe_count=1"
16165         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16166         local cmd="$cmd1 $cmd2 $cmd3"
16167
16168         rm -f ${TMP}/mds_survey*
16169         echo + $cmd
16170         eval $cmd || error "mds-survey with stripe_count failed"
16171         cat ${TMP}/mds_survey*
16172         rm -f ${TMP}/mds_survey*
16173 }
16174 run_test 225b "Metadata survey sanity with stripe_count = 1"
16175
16176 mcreate_path2fid () {
16177         local mode=$1
16178         local major=$2
16179         local minor=$3
16180         local name=$4
16181         local desc=$5
16182         local path=$DIR/$tdir/$name
16183         local fid
16184         local rc
16185         local fid_path
16186
16187         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
16188                 error "cannot create $desc"
16189
16190         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
16191         rc=$?
16192         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
16193
16194         fid_path=$($LFS fid2path $MOUNT $fid)
16195         rc=$?
16196         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
16197
16198         [ "$path" == "$fid_path" ] ||
16199                 error "fid2path returned $fid_path, expected $path"
16200
16201         echo "pass with $path and $fid"
16202 }
16203
16204 test_226a () {
16205         rm -rf $DIR/$tdir
16206         mkdir -p $DIR/$tdir
16207
16208         mcreate_path2fid 0010666 0 0 fifo "FIFO"
16209         mcreate_path2fid 0020666 1 3 null "character special file (null)"
16210         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
16211         mcreate_path2fid 0040666 0 0 dir "directory"
16212         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
16213         mcreate_path2fid 0100666 0 0 file "regular file"
16214         mcreate_path2fid 0120666 0 0 link "symbolic link"
16215         mcreate_path2fid 0140666 0 0 sock "socket"
16216 }
16217 run_test 226a "call path2fid and fid2path on files of all type"
16218
16219 test_226b () {
16220         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16221
16222         local MDTIDX=1
16223
16224         rm -rf $DIR/$tdir
16225         mkdir -p $DIR/$tdir
16226         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
16227                 error "create remote directory failed"
16228         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
16229         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
16230                                 "character special file (null)"
16231         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
16232                                 "character special file (no device)"
16233         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
16234         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
16235                                 "block special file (loop)"
16236         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
16237         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
16238         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
16239 }
16240 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
16241
16242 # LU-1299 Executing or running ldd on a truncated executable does not
16243 # cause an out-of-memory condition.
16244 test_227() {
16245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16246         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
16247
16248         dd if=$(which date) of=$MOUNT/date bs=1k count=1
16249         chmod +x $MOUNT/date
16250
16251         $MOUNT/date > /dev/null
16252         ldd $MOUNT/date > /dev/null
16253         rm -f $MOUNT/date
16254 }
16255 run_test 227 "running truncated executable does not cause OOM"
16256
16257 # LU-1512 try to reuse idle OI blocks
16258 test_228a() {
16259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16260         remote_mds_nodsh && skip "remote MDS with nodsh"
16261         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16262
16263         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16264         local myDIR=$DIR/$tdir
16265
16266         mkdir -p $myDIR
16267         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16268         $LCTL set_param fail_loc=0x80001002
16269         createmany -o $myDIR/t- 10000
16270         $LCTL set_param fail_loc=0
16271         # The guard is current the largest FID holder
16272         touch $myDIR/guard
16273         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16274                     tr -d '[')
16275         local IDX=$(($SEQ % 64))
16276
16277         do_facet $SINGLEMDS sync
16278         # Make sure journal flushed.
16279         sleep 6
16280         local blk1=$(do_facet $SINGLEMDS \
16281                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16282                      grep Blockcount | awk '{print $4}')
16283
16284         # Remove old files, some OI blocks will become idle.
16285         unlinkmany $myDIR/t- 10000
16286         # Create new files, idle OI blocks should be reused.
16287         createmany -o $myDIR/t- 2000
16288         do_facet $SINGLEMDS sync
16289         # Make sure journal flushed.
16290         sleep 6
16291         local blk2=$(do_facet $SINGLEMDS \
16292                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16293                      grep Blockcount | awk '{print $4}')
16294
16295         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16296 }
16297 run_test 228a "try to reuse idle OI blocks"
16298
16299 test_228b() {
16300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16301         remote_mds_nodsh && skip "remote MDS with nodsh"
16302         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16303
16304         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16305         local myDIR=$DIR/$tdir
16306
16307         mkdir -p $myDIR
16308         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16309         $LCTL set_param fail_loc=0x80001002
16310         createmany -o $myDIR/t- 10000
16311         $LCTL set_param fail_loc=0
16312         # The guard is current the largest FID holder
16313         touch $myDIR/guard
16314         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16315                     tr -d '[')
16316         local IDX=$(($SEQ % 64))
16317
16318         do_facet $SINGLEMDS sync
16319         # Make sure journal flushed.
16320         sleep 6
16321         local blk1=$(do_facet $SINGLEMDS \
16322                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16323                      grep Blockcount | awk '{print $4}')
16324
16325         # Remove old files, some OI blocks will become idle.
16326         unlinkmany $myDIR/t- 10000
16327
16328         # stop the MDT
16329         stop $SINGLEMDS || error "Fail to stop MDT."
16330         # remount the MDT
16331         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
16332
16333         df $MOUNT || error "Fail to df."
16334         # Create new files, idle OI blocks should be reused.
16335         createmany -o $myDIR/t- 2000
16336         do_facet $SINGLEMDS sync
16337         # Make sure journal flushed.
16338         sleep 6
16339         local blk2=$(do_facet $SINGLEMDS \
16340                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16341                      grep Blockcount | awk '{print $4}')
16342
16343         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16344 }
16345 run_test 228b "idle OI blocks can be reused after MDT restart"
16346
16347 #LU-1881
16348 test_228c() {
16349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16350         remote_mds_nodsh && skip "remote MDS with nodsh"
16351         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16352
16353         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16354         local myDIR=$DIR/$tdir
16355
16356         mkdir -p $myDIR
16357         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16358         $LCTL set_param fail_loc=0x80001002
16359         # 20000 files can guarantee there are index nodes in the OI file
16360         createmany -o $myDIR/t- 20000
16361         $LCTL set_param fail_loc=0
16362         # The guard is current the largest FID holder
16363         touch $myDIR/guard
16364         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16365                     tr -d '[')
16366         local IDX=$(($SEQ % 64))
16367
16368         do_facet $SINGLEMDS sync
16369         # Make sure journal flushed.
16370         sleep 6
16371         local blk1=$(do_facet $SINGLEMDS \
16372                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16373                      grep Blockcount | awk '{print $4}')
16374
16375         # Remove old files, some OI blocks will become idle.
16376         unlinkmany $myDIR/t- 20000
16377         rm -f $myDIR/guard
16378         # The OI file should become empty now
16379
16380         # Create new files, idle OI blocks should be reused.
16381         createmany -o $myDIR/t- 2000
16382         do_facet $SINGLEMDS sync
16383         # Make sure journal flushed.
16384         sleep 6
16385         local blk2=$(do_facet $SINGLEMDS \
16386                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16387                      grep Blockcount | awk '{print $4}')
16388
16389         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16390 }
16391 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
16392
16393 test_229() { # LU-2482, LU-3448
16394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16395         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
16396         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
16397                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
16398
16399         rm -f $DIR/$tfile
16400
16401         # Create a file with a released layout and stripe count 2.
16402         $MULTIOP $DIR/$tfile H2c ||
16403                 error "failed to create file with released layout"
16404
16405         $LFS getstripe -v $DIR/$tfile
16406
16407         local pattern=$($LFS getstripe -L $DIR/$tfile)
16408         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
16409
16410         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
16411                 error "getstripe"
16412         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
16413         stat $DIR/$tfile || error "failed to stat released file"
16414
16415         chown $RUNAS_ID $DIR/$tfile ||
16416                 error "chown $RUNAS_ID $DIR/$tfile failed"
16417
16418         chgrp $RUNAS_ID $DIR/$tfile ||
16419                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
16420
16421         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
16422         rm $DIR/$tfile || error "failed to remove released file"
16423 }
16424 run_test 229 "getstripe/stat/rm/attr changes work on released files"
16425
16426 test_230a() {
16427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16428         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16429         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16430                 skip "Need MDS version at least 2.11.52"
16431
16432         local MDTIDX=1
16433
16434         test_mkdir $DIR/$tdir
16435         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
16436         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
16437         [ $mdt_idx -ne 0 ] &&
16438                 error "create local directory on wrong MDT $mdt_idx"
16439
16440         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
16441                         error "create remote directory failed"
16442         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
16443         [ $mdt_idx -ne $MDTIDX ] &&
16444                 error "create remote directory on wrong MDT $mdt_idx"
16445
16446         createmany -o $DIR/$tdir/test_230/t- 10 ||
16447                 error "create files on remote directory failed"
16448         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
16449         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
16450         rm -r $DIR/$tdir || error "unlink remote directory failed"
16451 }
16452 run_test 230a "Create remote directory and files under the remote directory"
16453
16454 test_230b() {
16455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16456         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16457         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16458                 skip "Need MDS version at least 2.11.52"
16459
16460         local MDTIDX=1
16461         local mdt_index
16462         local i
16463         local file
16464         local pid
16465         local stripe_count
16466         local migrate_dir=$DIR/$tdir/migrate_dir
16467         local other_dir=$DIR/$tdir/other_dir
16468
16469         test_mkdir $DIR/$tdir
16470         test_mkdir -i0 -c1 $migrate_dir
16471         test_mkdir -i0 -c1 $other_dir
16472         for ((i=0; i<10; i++)); do
16473                 mkdir -p $migrate_dir/dir_${i}
16474                 createmany -o $migrate_dir/dir_${i}/f 10 ||
16475                         error "create files under remote dir failed $i"
16476         done
16477
16478         cp /etc/passwd $migrate_dir/$tfile
16479         cp /etc/passwd $other_dir/$tfile
16480         chattr +SAD $migrate_dir
16481         chattr +SAD $migrate_dir/$tfile
16482
16483         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16484         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16485         local old_dir_mode=$(stat -c%f $migrate_dir)
16486         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
16487
16488         mkdir -p $migrate_dir/dir_default_stripe2
16489         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
16490         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
16491
16492         mkdir -p $other_dir
16493         ln $migrate_dir/$tfile $other_dir/luna
16494         ln $migrate_dir/$tfile $migrate_dir/sofia
16495         ln $other_dir/$tfile $migrate_dir/david
16496         ln -s $migrate_dir/$tfile $other_dir/zachary
16497         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
16498         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
16499
16500         $LFS migrate -m $MDTIDX $migrate_dir ||
16501                 error "fails on migrating remote dir to MDT1"
16502
16503         echo "migratate to MDT1, then checking.."
16504         for ((i = 0; i < 10; i++)); do
16505                 for file in $(find $migrate_dir/dir_${i}); do
16506                         mdt_index=$($LFS getstripe -m $file)
16507                         [ $mdt_index == $MDTIDX ] ||
16508                                 error "$file is not on MDT${MDTIDX}"
16509                 done
16510         done
16511
16512         # the multiple link file should still in MDT0
16513         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
16514         [ $mdt_index == 0 ] ||
16515                 error "$file is not on MDT${MDTIDX}"
16516
16517         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16518         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16519                 error " expect $old_dir_flag get $new_dir_flag"
16520
16521         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16522         [ "$old_file_flag" = "$new_file_flag" ] ||
16523                 error " expect $old_file_flag get $new_file_flag"
16524
16525         local new_dir_mode=$(stat -c%f $migrate_dir)
16526         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16527                 error "expect mode $old_dir_mode get $new_dir_mode"
16528
16529         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16530         [ "$old_file_mode" = "$new_file_mode" ] ||
16531                 error "expect mode $old_file_mode get $new_file_mode"
16532
16533         diff /etc/passwd $migrate_dir/$tfile ||
16534                 error "$tfile different after migration"
16535
16536         diff /etc/passwd $other_dir/luna ||
16537                 error "luna different after migration"
16538
16539         diff /etc/passwd $migrate_dir/sofia ||
16540                 error "sofia different after migration"
16541
16542         diff /etc/passwd $migrate_dir/david ||
16543                 error "david different after migration"
16544
16545         diff /etc/passwd $other_dir/zachary ||
16546                 error "zachary different after migration"
16547
16548         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16549                 error "${tfile}_ln different after migration"
16550
16551         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16552                 error "${tfile}_ln_other different after migration"
16553
16554         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
16555         [ $stripe_count = 2 ] ||
16556                 error "dir strpe_count $d != 2 after migration."
16557
16558         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
16559         [ $stripe_count = 2 ] ||
16560                 error "file strpe_count $d != 2 after migration."
16561
16562         #migrate back to MDT0
16563         MDTIDX=0
16564
16565         $LFS migrate -m $MDTIDX $migrate_dir ||
16566                 error "fails on migrating remote dir to MDT0"
16567
16568         echo "migrate back to MDT0, checking.."
16569         for file in $(find $migrate_dir); do
16570                 mdt_index=$($LFS getstripe -m $file)
16571                 [ $mdt_index == $MDTIDX ] ||
16572                         error "$file is not on MDT${MDTIDX}"
16573         done
16574
16575         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16576         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16577                 error " expect $old_dir_flag get $new_dir_flag"
16578
16579         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16580         [ "$old_file_flag" = "$new_file_flag" ] ||
16581                 error " expect $old_file_flag get $new_file_flag"
16582
16583         local new_dir_mode=$(stat -c%f $migrate_dir)
16584         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16585                 error "expect mode $old_dir_mode get $new_dir_mode"
16586
16587         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16588         [ "$old_file_mode" = "$new_file_mode" ] ||
16589                 error "expect mode $old_file_mode get $new_file_mode"
16590
16591         diff /etc/passwd ${migrate_dir}/$tfile ||
16592                 error "$tfile different after migration"
16593
16594         diff /etc/passwd ${other_dir}/luna ||
16595                 error "luna different after migration"
16596
16597         diff /etc/passwd ${migrate_dir}/sofia ||
16598                 error "sofia different after migration"
16599
16600         diff /etc/passwd ${other_dir}/zachary ||
16601                 error "zachary different after migration"
16602
16603         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16604                 error "${tfile}_ln different after migration"
16605
16606         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16607                 error "${tfile}_ln_other different after migration"
16608
16609         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
16610         [ $stripe_count = 2 ] ||
16611                 error "dir strpe_count $d != 2 after migration."
16612
16613         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
16614         [ $stripe_count = 2 ] ||
16615                 error "file strpe_count $d != 2 after migration."
16616
16617         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16618 }
16619 run_test 230b "migrate directory"
16620
16621 test_230c() {
16622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16623         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16624         remote_mds_nodsh && skip "remote MDS with nodsh"
16625         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16626                 skip "Need MDS version at least 2.11.52"
16627
16628         local MDTIDX=1
16629         local total=3
16630         local mdt_index
16631         local file
16632         local migrate_dir=$DIR/$tdir/migrate_dir
16633
16634         #If migrating directory fails in the middle, all entries of
16635         #the directory is still accessiable.
16636         test_mkdir $DIR/$tdir
16637         test_mkdir -i0 -c1 $migrate_dir
16638         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
16639         stat $migrate_dir
16640         createmany -o $migrate_dir/f $total ||
16641                 error "create files under ${migrate_dir} failed"
16642
16643         # fail after migrating top dir, and this will fail only once, so the
16644         # first sub file migration will fail (currently f3), others succeed.
16645         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
16646         do_facet mds1 lctl set_param fail_loc=0x1801
16647         local t=$(ls $migrate_dir | wc -l)
16648         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
16649                 error "migrate should fail"
16650         local u=$(ls $migrate_dir | wc -l)
16651         [ "$u" == "$t" ] || error "$u != $t during migration"
16652
16653         # add new dir/file should succeed
16654         mkdir $migrate_dir/dir ||
16655                 error "mkdir failed under migrating directory"
16656         touch $migrate_dir/file ||
16657                 error "create file failed under migrating directory"
16658
16659         # add file with existing name should fail
16660         for file in $migrate_dir/f*; do
16661                 stat $file > /dev/null || error "stat $file failed"
16662                 $OPENFILE -f O_CREAT:O_EXCL $file &&
16663                         error "open(O_CREAT|O_EXCL) $file should fail"
16664                 $MULTIOP $file m && error "create $file should fail"
16665                 touch $DIR/$tdir/remote_dir/$tfile ||
16666                         error "touch $tfile failed"
16667                 ln $DIR/$tdir/remote_dir/$tfile $file &&
16668                         error "link $file should fail"
16669                 mdt_index=$($LFS getstripe -m $file)
16670                 if [ $mdt_index == 0 ]; then
16671                         # file failed to migrate is not allowed to rename to
16672                         mv $DIR/$tdir/remote_dir/$tfile $file &&
16673                                 error "rename to $file should fail"
16674                 else
16675                         mv $DIR/$tdir/remote_dir/$tfile $file ||
16676                                 error "rename to $file failed"
16677                 fi
16678                 echo hello >> $file || error "write $file failed"
16679         done
16680
16681         # resume migration with different options should fail
16682         $LFS migrate -m 0 $migrate_dir &&
16683                 error "migrate -m 0 $migrate_dir should fail"
16684
16685         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
16686                 error "migrate -c 2 $migrate_dir should fail"
16687
16688         # resume migration should succeed
16689         $LFS migrate -m $MDTIDX $migrate_dir ||
16690                 error "migrate $migrate_dir failed"
16691
16692         echo "Finish migration, then checking.."
16693         for file in $(find $migrate_dir); do
16694                 mdt_index=$($LFS getstripe -m $file)
16695                 [ $mdt_index == $MDTIDX ] ||
16696                         error "$file is not on MDT${MDTIDX}"
16697         done
16698
16699         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16700 }
16701 run_test 230c "check directory accessiblity if migration failed"
16702
16703 test_230d() {
16704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16705         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16706         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16707                 skip "Need MDS version at least 2.11.52"
16708         # LU-11235
16709         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
16710
16711         local migrate_dir=$DIR/$tdir/migrate_dir
16712         local old_index
16713         local new_index
16714         local old_count
16715         local new_count
16716         local new_hash
16717         local mdt_index
16718         local i
16719         local j
16720
16721         old_index=$((RANDOM % MDSCOUNT))
16722         old_count=$((MDSCOUNT - old_index))
16723         new_index=$((RANDOM % MDSCOUNT))
16724         new_count=$((MDSCOUNT - new_index))
16725         new_hash="all_char"
16726
16727         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
16728         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
16729
16730         test_mkdir $DIR/$tdir
16731         test_mkdir -i $old_index -c $old_count $migrate_dir
16732
16733         for ((i=0; i<100; i++)); do
16734                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
16735                 createmany -o $migrate_dir/dir_${i}/f 100 ||
16736                         error "create files under remote dir failed $i"
16737         done
16738
16739         echo -n "Migrate from MDT$old_index "
16740         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
16741         echo -n "to MDT$new_index"
16742         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
16743         echo
16744
16745         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
16746         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
16747                 error "migrate remote dir error"
16748
16749         echo "Finish migration, then checking.."
16750         for file in $(find $migrate_dir); do
16751                 mdt_index=$($LFS getstripe -m $file)
16752                 if [ $mdt_index -lt $new_index ] ||
16753                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
16754                         error "$file is on MDT$mdt_index"
16755                 fi
16756         done
16757
16758         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16759 }
16760 run_test 230d "check migrate big directory"
16761
16762 test_230e() {
16763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16764         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16765         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16766                 skip "Need MDS version at least 2.11.52"
16767
16768         local i
16769         local j
16770         local a_fid
16771         local b_fid
16772
16773         mkdir -p $DIR/$tdir
16774         mkdir $DIR/$tdir/migrate_dir
16775         mkdir $DIR/$tdir/other_dir
16776         touch $DIR/$tdir/migrate_dir/a
16777         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
16778         ls $DIR/$tdir/other_dir
16779
16780         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16781                 error "migrate dir fails"
16782
16783         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16784         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16785
16786         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16787         [ $mdt_index == 0 ] || error "a is not on MDT0"
16788
16789         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
16790                 error "migrate dir fails"
16791
16792         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
16793         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
16794
16795         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16796         [ $mdt_index == 1 ] || error "a is not on MDT1"
16797
16798         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
16799         [ $mdt_index == 1 ] || error "b is not on MDT1"
16800
16801         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16802         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
16803
16804         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
16805
16806         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16807 }
16808 run_test 230e "migrate mulitple local link files"
16809
16810 test_230f() {
16811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16812         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16813         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16814                 skip "Need MDS version at least 2.11.52"
16815
16816         local a_fid
16817         local ln_fid
16818
16819         mkdir -p $DIR/$tdir
16820         mkdir $DIR/$tdir/migrate_dir
16821         $LFS mkdir -i1 $DIR/$tdir/other_dir
16822         touch $DIR/$tdir/migrate_dir/a
16823         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
16824         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
16825         ls $DIR/$tdir/other_dir
16826
16827         # a should be migrated to MDT1, since no other links on MDT0
16828         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16829                 error "#1 migrate dir fails"
16830         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16831         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16832         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16833         [ $mdt_index == 1 ] || error "a is not on MDT1"
16834
16835         # a should stay on MDT1, because it is a mulitple link file
16836         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16837                 error "#2 migrate dir fails"
16838         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16839         [ $mdt_index == 1 ] || error "a is not on MDT1"
16840
16841         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16842                 error "#3 migrate dir fails"
16843
16844         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16845         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
16846         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
16847
16848         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
16849         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
16850
16851         # a should be migrated to MDT0, since no other links on MDT1
16852         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16853                 error "#4 migrate dir fails"
16854         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16855         [ $mdt_index == 0 ] || error "a is not on MDT0"
16856
16857         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16858 }
16859 run_test 230f "migrate mulitple remote link files"
16860
16861 test_230g() {
16862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16863         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16864         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16865                 skip "Need MDS version at least 2.11.52"
16866
16867         mkdir -p $DIR/$tdir/migrate_dir
16868
16869         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
16870                 error "migrating dir to non-exist MDT succeeds"
16871         true
16872 }
16873 run_test 230g "migrate dir to non-exist MDT"
16874
16875 test_230h() {
16876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16877         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16878         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16879                 skip "Need MDS version at least 2.11.52"
16880
16881         local mdt_index
16882
16883         mkdir -p $DIR/$tdir/migrate_dir
16884
16885         $LFS migrate -m1 $DIR &&
16886                 error "migrating mountpoint1 should fail"
16887
16888         $LFS migrate -m1 $DIR/$tdir/.. &&
16889                 error "migrating mountpoint2 should fail"
16890
16891         # same as mv
16892         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
16893                 error "migrating $tdir/migrate_dir/.. should fail"
16894
16895         true
16896 }
16897 run_test 230h "migrate .. and root"
16898
16899 test_230i() {
16900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16901         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16902         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16903                 skip "Need MDS version at least 2.11.52"
16904
16905         mkdir -p $DIR/$tdir/migrate_dir
16906
16907         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
16908                 error "migration fails with a tailing slash"
16909
16910         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
16911                 error "migration fails with two tailing slashes"
16912 }
16913 run_test 230i "lfs migrate -m tolerates trailing slashes"
16914
16915 test_230j() {
16916         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16917         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16918                 skip "Need MDS version at least 2.11.52"
16919
16920         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
16921         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
16922                 error "create $tfile failed"
16923         cat /etc/passwd > $DIR/$tdir/$tfile
16924
16925         $LFS migrate -m 1 $DIR/$tdir
16926
16927         cmp /etc/passwd $DIR/$tdir/$tfile ||
16928                 error "DoM file mismatch after migration"
16929 }
16930 run_test 230j "DoM file data not changed after dir migration"
16931
16932 test_230k() {
16933         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
16934         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16935                 skip "Need MDS version at least 2.11.56"
16936
16937         local total=20
16938         local files_on_starting_mdt=0
16939
16940         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
16941         $LFS getdirstripe $DIR/$tdir
16942         for i in $(seq $total); do
16943                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
16944                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16945                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16946         done
16947
16948         echo "$files_on_starting_mdt files on MDT0"
16949
16950         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
16951         $LFS getdirstripe $DIR/$tdir
16952
16953         files_on_starting_mdt=0
16954         for i in $(seq $total); do
16955                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16956                         error "file $tfile.$i mismatch after migration"
16957                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
16958                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16959         done
16960
16961         echo "$files_on_starting_mdt files on MDT1 after migration"
16962         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
16963
16964         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
16965         $LFS getdirstripe $DIR/$tdir
16966
16967         files_on_starting_mdt=0
16968         for i in $(seq $total); do
16969                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16970                         error "file $tfile.$i mismatch after 2nd migration"
16971                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16972                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16973         done
16974
16975         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
16976         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
16977
16978         true
16979 }
16980 run_test 230k "file data not changed after dir migration"
16981
16982 test_230l() {
16983         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16984         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16985                 skip "Need MDS version at least 2.11.56"
16986
16987         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
16988         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
16989                 error "create files under remote dir failed $i"
16990         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
16991 }
16992 run_test 230l "readdir between MDTs won't crash"
16993
16994 test_230m() {
16995         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16996         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16997                 skip "Need MDS version at least 2.11.56"
16998
16999         local MDTIDX=1
17000         local mig_dir=$DIR/$tdir/migrate_dir
17001         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
17002         local shortstr="b"
17003         local val
17004
17005         echo "Creating files and dirs with xattrs"
17006         test_mkdir $DIR/$tdir
17007         test_mkdir -i0 -c1 $mig_dir
17008         mkdir $mig_dir/dir
17009         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
17010                 error "cannot set xattr attr1 on dir"
17011         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
17012                 error "cannot set xattr attr2 on dir"
17013         touch $mig_dir/dir/f0
17014         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
17015                 error "cannot set xattr attr1 on file"
17016         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
17017                 error "cannot set xattr attr2 on file"
17018         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
17019         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
17020         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
17021         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
17022         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
17023         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
17024         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
17025         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
17026         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
17027
17028         echo "Migrating to MDT1"
17029         $LFS migrate -m $MDTIDX $mig_dir ||
17030                 error "fails on migrating dir to MDT1"
17031
17032         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
17033         echo "Checking xattrs"
17034         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
17035         [ "$val" = $longstr ] ||
17036                 error "expecting xattr1 $longstr on dir, found $val"
17037         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
17038         [ "$val" = $shortstr ] ||
17039                 error "expecting xattr2 $shortstr on dir, found $val"
17040         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
17041         [ "$val" = $longstr ] ||
17042                 error "expecting xattr1 $longstr on file, found $val"
17043         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
17044         [ "$val" = $shortstr ] ||
17045                 error "expecting xattr2 $shortstr on file, found $val"
17046 }
17047 run_test 230m "xattrs not changed after dir migration"
17048
17049 test_231a()
17050 {
17051         # For simplicity this test assumes that max_pages_per_rpc
17052         # is the same across all OSCs
17053         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
17054         local bulk_size=$((max_pages * PAGE_SIZE))
17055         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
17056                                        head -n 1)
17057
17058         mkdir -p $DIR/$tdir
17059         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
17060                 error "failed to set stripe with -S ${brw_size}M option"
17061
17062         # clear the OSC stats
17063         $LCTL set_param osc.*.stats=0 &>/dev/null
17064         stop_writeback
17065
17066         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
17067         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
17068                 oflag=direct &>/dev/null || error "dd failed"
17069
17070         sync; sleep 1; sync # just to be safe
17071         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
17072         if [ x$nrpcs != "x1" ]; then
17073                 $LCTL get_param osc.*.stats
17074                 error "found $nrpcs ost_write RPCs, not 1 as expected"
17075         fi
17076
17077         start_writeback
17078         # Drop the OSC cache, otherwise we will read from it
17079         cancel_lru_locks osc
17080
17081         # clear the OSC stats
17082         $LCTL set_param osc.*.stats=0 &>/dev/null
17083
17084         # Client reads $bulk_size.
17085         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
17086                 iflag=direct &>/dev/null || error "dd failed"
17087
17088         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
17089         if [ x$nrpcs != "x1" ]; then
17090                 $LCTL get_param osc.*.stats
17091                 error "found $nrpcs ost_read RPCs, not 1 as expected"
17092         fi
17093 }
17094 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
17095
17096 test_231b() {
17097         mkdir -p $DIR/$tdir
17098         local i
17099         for i in {0..1023}; do
17100                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
17101                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
17102                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
17103         done
17104         sync
17105 }
17106 run_test 231b "must not assert on fully utilized OST request buffer"
17107
17108 test_232a() {
17109         mkdir -p $DIR/$tdir
17110         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
17111
17112         #define OBD_FAIL_LDLM_OST_LVB            0x31c
17113         do_facet ost1 $LCTL set_param fail_loc=0x31c
17114
17115         # ignore dd failure
17116         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
17117
17118         do_facet ost1 $LCTL set_param fail_loc=0
17119         umount_client $MOUNT || error "umount failed"
17120         mount_client $MOUNT || error "mount failed"
17121         stop ost1 || error "cannot stop ost1"
17122         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17123 }
17124 run_test 232a "failed lock should not block umount"
17125
17126 test_232b() {
17127         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
17128                 skip "Need MDS version at least 2.10.58"
17129
17130         mkdir -p $DIR/$tdir
17131         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
17132         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
17133         sync
17134         cancel_lru_locks osc
17135
17136         #define OBD_FAIL_LDLM_OST_LVB            0x31c
17137         do_facet ost1 $LCTL set_param fail_loc=0x31c
17138
17139         # ignore failure
17140         $LFS data_version $DIR/$tdir/$tfile || true
17141
17142         do_facet ost1 $LCTL set_param fail_loc=0
17143         umount_client $MOUNT || error "umount failed"
17144         mount_client $MOUNT || error "mount failed"
17145         stop ost1 || error "cannot stop ost1"
17146         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17147 }
17148 run_test 232b "failed data version lock should not block umount"
17149
17150 test_233a() {
17151         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
17152                 skip "Need MDS version at least 2.3.64"
17153         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
17154
17155         local fid=$($LFS path2fid $MOUNT)
17156
17157         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17158                 error "cannot access $MOUNT using its FID '$fid'"
17159 }
17160 run_test 233a "checking that OBF of the FS root succeeds"
17161
17162 test_233b() {
17163         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
17164                 skip "Need MDS version at least 2.5.90"
17165         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
17166
17167         local fid=$($LFS path2fid $MOUNT/.lustre)
17168
17169         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17170                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
17171
17172         fid=$($LFS path2fid $MOUNT/.lustre/fid)
17173         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17174                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
17175 }
17176 run_test 233b "checking that OBF of the FS .lustre succeeds"
17177
17178 test_234() {
17179         local p="$TMP/sanityN-$TESTNAME.parameters"
17180         save_lustre_params client "llite.*.xattr_cache" > $p
17181         lctl set_param llite.*.xattr_cache 1 ||
17182                 skip_env "xattr cache is not supported"
17183
17184         mkdir -p $DIR/$tdir || error "mkdir failed"
17185         touch $DIR/$tdir/$tfile || error "touch failed"
17186         # OBD_FAIL_LLITE_XATTR_ENOMEM
17187         $LCTL set_param fail_loc=0x1405
17188         getfattr -n user.attr $DIR/$tdir/$tfile &&
17189                 error "getfattr should have failed with ENOMEM"
17190         $LCTL set_param fail_loc=0x0
17191         rm -rf $DIR/$tdir
17192
17193         restore_lustre_params < $p
17194         rm -f $p
17195 }
17196 run_test 234 "xattr cache should not crash on ENOMEM"
17197
17198 test_235() {
17199         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
17200                 skip "Need MDS version at least 2.4.52"
17201
17202         flock_deadlock $DIR/$tfile
17203         local RC=$?
17204         case $RC in
17205                 0)
17206                 ;;
17207                 124) error "process hangs on a deadlock"
17208                 ;;
17209                 *) error "error executing flock_deadlock $DIR/$tfile"
17210                 ;;
17211         esac
17212 }
17213 run_test 235 "LU-1715: flock deadlock detection does not work properly"
17214
17215 #LU-2935
17216 test_236() {
17217         check_swap_layouts_support
17218
17219         local ref1=/etc/passwd
17220         local ref2=/etc/group
17221         local file1=$DIR/$tdir/f1
17222         local file2=$DIR/$tdir/f2
17223
17224         test_mkdir -c1 $DIR/$tdir
17225         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
17226         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
17227         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
17228         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
17229         local fd=$(free_fd)
17230         local cmd="exec $fd<>$file2"
17231         eval $cmd
17232         rm $file2
17233         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
17234                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
17235         cmd="exec $fd>&-"
17236         eval $cmd
17237         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17238
17239         #cleanup
17240         rm -rf $DIR/$tdir
17241 }
17242 run_test 236 "Layout swap on open unlinked file"
17243
17244 # LU-4659 linkea consistency
17245 test_238() {
17246         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17247                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17248                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17249                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17250
17251         touch $DIR/$tfile
17252         ln $DIR/$tfile $DIR/$tfile.lnk
17253         touch $DIR/$tfile.new
17254         mv $DIR/$tfile.new $DIR/$tfile
17255         local fid1=$($LFS path2fid $DIR/$tfile)
17256         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
17257         local path1=$($LFS fid2path $FSNAME "$fid1")
17258         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
17259         local path2=$($LFS fid2path $FSNAME "$fid2")
17260         [ $tfile.lnk == $path2 ] ||
17261                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
17262         rm -f $DIR/$tfile*
17263 }
17264 run_test 238 "Verify linkea consistency"
17265
17266 test_239A() { # was test_239
17267         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
17268                 skip "Need MDS version at least 2.5.60"
17269
17270         local list=$(comma_list $(mdts_nodes))
17271
17272         mkdir -p $DIR/$tdir
17273         createmany -o $DIR/$tdir/f- 5000
17274         unlinkmany $DIR/$tdir/f- 5000
17275         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
17276                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
17277         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
17278                         osp.*MDT*.sync_in_flight" | calc_sum)
17279         [ "$changes" -eq 0 ] || error "$changes not synced"
17280 }
17281 run_test 239A "osp_sync test"
17282
17283 test_239a() { #LU-5297
17284         remote_mds_nodsh && skip "remote MDS with nodsh"
17285
17286         touch $DIR/$tfile
17287         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
17288         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
17289         chgrp $RUNAS_GID $DIR/$tfile
17290         wait_delete_completed
17291 }
17292 run_test 239a "process invalid osp sync record correctly"
17293
17294 test_239b() { #LU-5297
17295         remote_mds_nodsh && skip "remote MDS with nodsh"
17296
17297         touch $DIR/$tfile1
17298         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
17299         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
17300         chgrp $RUNAS_GID $DIR/$tfile1
17301         wait_delete_completed
17302         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17303         touch $DIR/$tfile2
17304         chgrp $RUNAS_GID $DIR/$tfile2
17305         wait_delete_completed
17306 }
17307 run_test 239b "process osp sync record with ENOMEM error correctly"
17308
17309 test_240() {
17310         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17311         remote_mds_nodsh && skip "remote MDS with nodsh"
17312
17313         mkdir -p $DIR/$tdir
17314
17315         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
17316                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
17317         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
17318                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
17319
17320         umount_client $MOUNT || error "umount failed"
17321         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
17322         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
17323         mount_client $MOUNT || error "failed to mount client"
17324
17325         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
17326         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
17327 }
17328 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
17329
17330 test_241_bio() {
17331         local count=$1
17332         local bsize=$2
17333
17334         for LOOP in $(seq $count); do
17335                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
17336                 cancel_lru_locks $OSC || true
17337         done
17338 }
17339
17340 test_241_dio() {
17341         local count=$1
17342         local bsize=$2
17343
17344         for LOOP in $(seq $1); do
17345                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
17346                         2>/dev/null
17347         done
17348 }
17349
17350 test_241a() { # was test_241
17351         local bsize=$PAGE_SIZE
17352
17353         (( bsize < 40960 )) && bsize=40960
17354         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17355         ls -la $DIR/$tfile
17356         cancel_lru_locks $OSC
17357         test_241_bio 1000 $bsize &
17358         PID=$!
17359         test_241_dio 1000 $bsize
17360         wait $PID
17361 }
17362 run_test 241a "bio vs dio"
17363
17364 test_241b() {
17365         local bsize=$PAGE_SIZE
17366
17367         (( bsize < 40960 )) && bsize=40960
17368         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17369         ls -la $DIR/$tfile
17370         test_241_dio 1000 $bsize &
17371         PID=$!
17372         test_241_dio 1000 $bsize
17373         wait $PID
17374 }
17375 run_test 241b "dio vs dio"
17376
17377 test_242() {
17378         remote_mds_nodsh && skip "remote MDS with nodsh"
17379
17380         mkdir -p $DIR/$tdir
17381         touch $DIR/$tdir/$tfile
17382
17383         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
17384         do_facet mds1 lctl set_param fail_loc=0x105
17385         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
17386
17387         do_facet mds1 lctl set_param fail_loc=0
17388         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
17389 }
17390 run_test 242 "mdt_readpage failure should not cause directory unreadable"
17391
17392 test_243()
17393 {
17394         test_mkdir $DIR/$tdir
17395         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
17396 }
17397 run_test 243 "various group lock tests"
17398
17399 test_244a()
17400 {
17401         test_mkdir $DIR/$tdir
17402         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
17403         sendfile_grouplock $DIR/$tdir/$tfile || \
17404                 error "sendfile+grouplock failed"
17405         rm -rf $DIR/$tdir
17406 }
17407 run_test 244a "sendfile with group lock tests"
17408
17409 test_244b()
17410 {
17411         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
17412
17413         local threads=50
17414         local size=$((1024*1024))
17415
17416         test_mkdir $DIR/$tdir
17417         for i in $(seq 1 $threads); do
17418                 local file=$DIR/$tdir/file_$((i / 10))
17419                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
17420                 local pids[$i]=$!
17421         done
17422         for i in $(seq 1 $threads); do
17423                 wait ${pids[$i]}
17424         done
17425 }
17426 run_test 244b "multi-threaded write with group lock"
17427
17428 test_245() {
17429         local flagname="multi_mod_rpcs"
17430         local connect_data_name="max_mod_rpcs"
17431         local out
17432
17433         # check if multiple modify RPCs flag is set
17434         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
17435                 grep "connect_flags:")
17436         echo "$out"
17437
17438         echo "$out" | grep -qw $flagname
17439         if [ $? -ne 0 ]; then
17440                 echo "connect flag $flagname is not set"
17441                 return
17442         fi
17443
17444         # check if multiple modify RPCs data is set
17445         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
17446         echo "$out"
17447
17448         echo "$out" | grep -qw $connect_data_name ||
17449                 error "import should have connect data $connect_data_name"
17450 }
17451 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
17452
17453 cleanup_247() {
17454         local submount=$1
17455
17456         trap 0
17457         umount_client $submount
17458         rmdir $submount
17459 }
17460
17461 test_247a() {
17462         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17463                 grep -q subtree ||
17464                 skip_env "Fileset feature is not supported"
17465
17466         local submount=${MOUNT}_$tdir
17467
17468         mkdir $MOUNT/$tdir
17469         mkdir -p $submount || error "mkdir $submount failed"
17470         FILESET="$FILESET/$tdir" mount_client $submount ||
17471                 error "mount $submount failed"
17472         trap "cleanup_247 $submount" EXIT
17473         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
17474         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
17475                 error "read $MOUNT/$tdir/$tfile failed"
17476         cleanup_247 $submount
17477 }
17478 run_test 247a "mount subdir as fileset"
17479
17480 test_247b() {
17481         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17482                 skip_env "Fileset feature is not supported"
17483
17484         local submount=${MOUNT}_$tdir
17485
17486         rm -rf $MOUNT/$tdir
17487         mkdir -p $submount || error "mkdir $submount failed"
17488         SKIP_FILESET=1
17489         FILESET="$FILESET/$tdir" mount_client $submount &&
17490                 error "mount $submount should fail"
17491         rmdir $submount
17492 }
17493 run_test 247b "mount subdir that dose not exist"
17494
17495 test_247c() {
17496         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17497                 skip_env "Fileset feature is not supported"
17498
17499         local submount=${MOUNT}_$tdir
17500
17501         mkdir -p $MOUNT/$tdir/dir1
17502         mkdir -p $submount || error "mkdir $submount failed"
17503         trap "cleanup_247 $submount" EXIT
17504         FILESET="$FILESET/$tdir" mount_client $submount ||
17505                 error "mount $submount failed"
17506         local fid=$($LFS path2fid $MOUNT/)
17507         $LFS fid2path $submount $fid && error "fid2path should fail"
17508         cleanup_247 $submount
17509 }
17510 run_test 247c "running fid2path outside root"
17511
17512 test_247d() {
17513         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17514                 skip "Fileset feature is not supported"
17515
17516         local submount=${MOUNT}_$tdir
17517
17518         mkdir -p $MOUNT/$tdir/dir1
17519         mkdir -p $submount || error "mkdir $submount failed"
17520         FILESET="$FILESET/$tdir" mount_client $submount ||
17521                 error "mount $submount failed"
17522         trap "cleanup_247 $submount" EXIT
17523         local fid=$($LFS path2fid $submount/dir1)
17524         $LFS fid2path $submount $fid || error "fid2path should succeed"
17525         cleanup_247 $submount
17526 }
17527 run_test 247d "running fid2path inside root"
17528
17529 # LU-8037
17530 test_247e() {
17531         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17532                 grep -q subtree ||
17533                 skip "Fileset feature is not supported"
17534
17535         local submount=${MOUNT}_$tdir
17536
17537         mkdir $MOUNT/$tdir
17538         mkdir -p $submount || error "mkdir $submount failed"
17539         FILESET="$FILESET/.." mount_client $submount &&
17540                 error "mount $submount should fail"
17541         rmdir $submount
17542 }
17543 run_test 247e "mount .. as fileset"
17544
17545 test_248a() {
17546         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
17547         [ -z "$fast_read_sav" ] && skip "no fast read support"
17548
17549         # create a large file for fast read verification
17550         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
17551
17552         # make sure the file is created correctly
17553         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
17554                 { rm -f $DIR/$tfile; skip "file creation error"; }
17555
17556         echo "Test 1: verify that fast read is 4 times faster on cache read"
17557
17558         # small read with fast read enabled
17559         $LCTL set_param -n llite.*.fast_read=1
17560         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17561                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17562                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17563         # small read with fast read disabled
17564         $LCTL set_param -n llite.*.fast_read=0
17565         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17566                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17567                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17568
17569         # verify that fast read is 4 times faster for cache read
17570         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
17571                 error_not_in_vm "fast read was not 4 times faster: " \
17572                            "$t_fast vs $t_slow"
17573
17574         echo "Test 2: verify the performance between big and small read"
17575         $LCTL set_param -n llite.*.fast_read=1
17576
17577         # 1k non-cache read
17578         cancel_lru_locks osc
17579         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17580                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17581                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17582
17583         # 1M non-cache read
17584         cancel_lru_locks osc
17585         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17586                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17587                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17588
17589         # verify that big IO is not 4 times faster than small IO
17590         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
17591                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
17592
17593         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
17594         rm -f $DIR/$tfile
17595 }
17596 run_test 248a "fast read verification"
17597
17598 test_248b() {
17599         # Default short_io_bytes=16384, try both smaller and larger sizes.
17600         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
17601         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
17602         echo "bs=53248 count=113 normal buffered write"
17603         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
17604                 error "dd of initial data file failed"
17605         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
17606
17607         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
17608         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
17609                 error "dd with sync normal writes failed"
17610         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
17611
17612         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
17613         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
17614                 error "dd with sync small writes failed"
17615         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
17616
17617         cancel_lru_locks osc
17618
17619         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
17620         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
17621         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
17622         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
17623                 iflag=direct || error "dd with O_DIRECT small read failed"
17624         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
17625         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
17626                 error "compare $TMP/$tfile.1 failed"
17627
17628         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
17629         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
17630
17631         # just to see what the maximum tunable value is, and test parsing
17632         echo "test invalid parameter 2MB"
17633         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
17634                 error "too-large short_io_bytes allowed"
17635         echo "test maximum parameter 512KB"
17636         # if we can set a larger short_io_bytes, run test regardless of version
17637         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
17638                 # older clients may not allow setting it this large, that's OK
17639                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
17640                         skip "Need at least client version 2.13.50"
17641                 error "medium short_io_bytes failed"
17642         fi
17643         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
17644         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
17645
17646         echo "test large parameter 64KB"
17647         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
17648         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
17649
17650         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
17651         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
17652                 error "dd with sync large writes failed"
17653         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
17654
17655         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
17656         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
17657         num=$((113 * 4096 / PAGE_SIZE))
17658         echo "bs=$size count=$num oflag=direct large write $tfile.3"
17659         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
17660                 error "dd with O_DIRECT large writes failed"
17661         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
17662                 error "compare $DIR/$tfile.3 failed"
17663
17664         cancel_lru_locks osc
17665
17666         echo "bs=$size count=$num iflag=direct large read $tfile.2"
17667         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
17668                 error "dd with O_DIRECT large read failed"
17669         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
17670                 error "compare $TMP/$tfile.2 failed"
17671
17672         echo "bs=$size count=$num iflag=direct large read $tfile.3"
17673         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
17674                 error "dd with O_DIRECT large read failed"
17675         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
17676                 error "compare $TMP/$tfile.3 failed"
17677 }
17678 run_test 248b "test short_io read and write for both small and large sizes"
17679
17680 test_249() { # LU-7890
17681         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
17682                 skip "Need at least version 2.8.54"
17683
17684         rm -f $DIR/$tfile
17685         $LFS setstripe -c 1 $DIR/$tfile
17686         # Offset 2T == 4k * 512M
17687         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
17688                 error "dd to 2T offset failed"
17689 }
17690 run_test 249 "Write above 2T file size"
17691
17692 test_250() {
17693         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
17694          && skip "no 16TB file size limit on ZFS"
17695
17696         $LFS setstripe -c 1 $DIR/$tfile
17697         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
17698         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
17699         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
17700         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
17701                 conv=notrunc,fsync && error "append succeeded"
17702         return 0
17703 }
17704 run_test 250 "Write above 16T limit"
17705
17706 test_251() {
17707         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
17708
17709         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
17710         #Skip once - writing the first stripe will succeed
17711         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17712         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
17713                 error "short write happened"
17714
17715         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17716         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
17717                 error "short read happened"
17718
17719         rm -f $DIR/$tfile
17720 }
17721 run_test 251 "Handling short read and write correctly"
17722
17723 test_252() {
17724         remote_mds_nodsh && skip "remote MDS with nodsh"
17725         remote_ost_nodsh && skip "remote OST with nodsh"
17726         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
17727                 skip_env "ldiskfs only test"
17728         fi
17729
17730         local tgt
17731         local dev
17732         local out
17733         local uuid
17734         local num
17735         local gen
17736
17737         # check lr_reader on OST0000
17738         tgt=ost1
17739         dev=$(facet_device $tgt)
17740         out=$(do_facet $tgt $LR_READER $dev)
17741         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17742         echo "$out"
17743         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
17744         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
17745                 error "Invalid uuid returned by $LR_READER on target $tgt"
17746         echo -e "uuid returned by $LR_READER is '$uuid'\n"
17747
17748         # check lr_reader -c on MDT0000
17749         tgt=mds1
17750         dev=$(facet_device $tgt)
17751         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
17752                 skip "$LR_READER does not support additional options"
17753         fi
17754         out=$(do_facet $tgt $LR_READER -c $dev)
17755         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17756         echo "$out"
17757         num=$(echo "$out" | grep -c "mdtlov")
17758         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
17759                 error "Invalid number of mdtlov clients returned by $LR_READER"
17760         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
17761
17762         # check lr_reader -cr on MDT0000
17763         out=$(do_facet $tgt $LR_READER -cr $dev)
17764         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17765         echo "$out"
17766         echo "$out" | grep -q "^reply_data:$" ||
17767                 error "$LR_READER should have returned 'reply_data' section"
17768         num=$(echo "$out" | grep -c "client_generation")
17769         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
17770 }
17771 run_test 252 "check lr_reader tool"
17772
17773 test_253() {
17774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17775         remote_mds_nodsh && skip "remote MDS with nodsh"
17776         remote_mgs_nodsh && skip "remote MGS with nodsh"
17777
17778         local ostidx=0
17779         local rc=0
17780         local ost_name=$(ostname_from_index $ostidx)
17781
17782         # on the mdt's osc
17783         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
17784         do_facet $SINGLEMDS $LCTL get_param -n \
17785                 osp.$mdtosc_proc1.reserved_mb_high ||
17786                 skip  "remote MDS does not support reserved_mb_high"
17787
17788         rm -rf $DIR/$tdir
17789         wait_mds_ost_sync
17790         wait_delete_completed
17791         mkdir $DIR/$tdir
17792
17793         pool_add $TESTNAME || error "Pool creation failed"
17794         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
17795
17796         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
17797                 error "Setstripe failed"
17798
17799         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
17800
17801         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
17802                     grep "watermarks")
17803         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
17804
17805         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17806                         osp.$mdtosc_proc1.prealloc_status)
17807         echo "prealloc_status $oa_status"
17808
17809         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
17810                 error "File creation should fail"
17811
17812         #object allocation was stopped, but we still able to append files
17813         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
17814                 oflag=append || error "Append failed"
17815
17816         rm -f $DIR/$tdir/$tfile.0
17817
17818         # For this test, we want to delete the files we created to go out of
17819         # space but leave the watermark, so we remain nearly out of space
17820         ost_watermarks_enospc_delete_files $tfile $ostidx
17821
17822         wait_delete_completed
17823
17824         sleep_maxage
17825
17826         for i in $(seq 10 12); do
17827                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
17828                         2>/dev/null || error "File creation failed after rm"
17829         done
17830
17831         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17832                         osp.$mdtosc_proc1.prealloc_status)
17833         echo "prealloc_status $oa_status"
17834
17835         if (( oa_status != 0 )); then
17836                 error "Object allocation still disable after rm"
17837         fi
17838 }
17839 run_test 253 "Check object allocation limit"
17840
17841 test_254() {
17842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17843         remote_mds_nodsh && skip "remote MDS with nodsh"
17844         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
17845                 skip "MDS does not support changelog_size"
17846
17847         local cl_user
17848         local MDT0=$(facet_svc $SINGLEMDS)
17849
17850         changelog_register || error "changelog_register failed"
17851
17852         changelog_clear 0 || error "changelog_clear failed"
17853
17854         local size1=$(do_facet $SINGLEMDS \
17855                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17856         echo "Changelog size $size1"
17857
17858         rm -rf $DIR/$tdir
17859         $LFS mkdir -i 0 $DIR/$tdir
17860         # change something
17861         mkdir -p $DIR/$tdir/pics/2008/zachy
17862         touch $DIR/$tdir/pics/2008/zachy/timestamp
17863         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
17864         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17865         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17866         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17867         rm $DIR/$tdir/pics/desktop.jpg
17868
17869         local size2=$(do_facet $SINGLEMDS \
17870                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17871         echo "Changelog size after work $size2"
17872
17873         (( $size2 > $size1 )) ||
17874                 error "new Changelog size=$size2 less than old size=$size1"
17875 }
17876 run_test 254 "Check changelog size"
17877
17878 ladvise_no_type()
17879 {
17880         local type=$1
17881         local file=$2
17882
17883         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
17884                 awk -F: '{print $2}' | grep $type > /dev/null
17885         if [ $? -ne 0 ]; then
17886                 return 0
17887         fi
17888         return 1
17889 }
17890
17891 ladvise_no_ioctl()
17892 {
17893         local file=$1
17894
17895         lfs ladvise -a willread $file > /dev/null 2>&1
17896         if [ $? -eq 0 ]; then
17897                 return 1
17898         fi
17899
17900         lfs ladvise -a willread $file 2>&1 |
17901                 grep "Inappropriate ioctl for device" > /dev/null
17902         if [ $? -eq 0 ]; then
17903                 return 0
17904         fi
17905         return 1
17906 }
17907
17908 percent() {
17909         bc <<<"scale=2; ($1 - $2) * 100 / $2"
17910 }
17911
17912 # run a random read IO workload
17913 # usage: random_read_iops <filename> <filesize> <iosize>
17914 random_read_iops() {
17915         local file=$1
17916         local fsize=$2
17917         local iosize=${3:-4096}
17918
17919         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
17920                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
17921 }
17922
17923 drop_file_oss_cache() {
17924         local file="$1"
17925         local nodes="$2"
17926
17927         $LFS ladvise -a dontneed $file 2>/dev/null ||
17928                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
17929 }
17930
17931 ladvise_willread_performance()
17932 {
17933         local repeat=10
17934         local average_origin=0
17935         local average_cache=0
17936         local average_ladvise=0
17937
17938         for ((i = 1; i <= $repeat; i++)); do
17939                 echo "Iter $i/$repeat: reading without willread hint"
17940                 cancel_lru_locks osc
17941                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17942                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
17943                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
17944                 average_origin=$(bc <<<"$average_origin + $speed_origin")
17945
17946                 cancel_lru_locks osc
17947                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
17948                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
17949                 average_cache=$(bc <<<"$average_cache + $speed_cache")
17950
17951                 cancel_lru_locks osc
17952                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17953                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
17954                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
17955                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
17956                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
17957         done
17958         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
17959         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
17960         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
17961
17962         speedup_cache=$(percent $average_cache $average_origin)
17963         speedup_ladvise=$(percent $average_ladvise $average_origin)
17964
17965         echo "Average uncached read: $average_origin"
17966         echo "Average speedup with OSS cached read: " \
17967                 "$average_cache = +$speedup_cache%"
17968         echo "Average speedup with ladvise willread: " \
17969                 "$average_ladvise = +$speedup_ladvise%"
17970
17971         local lowest_speedup=20
17972         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
17973                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
17974                         "got $average_cache%. Skipping ladvise willread check."
17975                 return 0
17976         fi
17977
17978         # the test won't work on ZFS until it supports 'ladvise dontneed', but
17979         # it is still good to run until then to exercise 'ladvise willread'
17980         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17981                 [ "$ost1_FSTYPE" = "zfs" ] &&
17982                 echo "osd-zfs does not support dontneed or drop_caches" &&
17983                 return 0
17984
17985         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
17986         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
17987                 error_not_in_vm "Speedup with willread is less than " \
17988                         "$lowest_speedup%, got $average_ladvise%"
17989 }
17990
17991 test_255a() {
17992         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17993                 skip "lustre < 2.8.54 does not support ladvise "
17994         remote_ost_nodsh && skip "remote OST with nodsh"
17995
17996         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
17997
17998         ladvise_no_type willread $DIR/$tfile &&
17999                 skip "willread ladvise is not supported"
18000
18001         ladvise_no_ioctl $DIR/$tfile &&
18002                 skip "ladvise ioctl is not supported"
18003
18004         local size_mb=100
18005         local size=$((size_mb * 1048576))
18006         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
18007                 error "dd to $DIR/$tfile failed"
18008
18009         lfs ladvise -a willread $DIR/$tfile ||
18010                 error "Ladvise failed with no range argument"
18011
18012         lfs ladvise -a willread -s 0 $DIR/$tfile ||
18013                 error "Ladvise failed with no -l or -e argument"
18014
18015         lfs ladvise -a willread -e 1 $DIR/$tfile ||
18016                 error "Ladvise failed with only -e argument"
18017
18018         lfs ladvise -a willread -l 1 $DIR/$tfile ||
18019                 error "Ladvise failed with only -l argument"
18020
18021         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
18022                 error "End offset should not be smaller than start offset"
18023
18024         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
18025                 error "End offset should not be equal to start offset"
18026
18027         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
18028                 error "Ladvise failed with overflowing -s argument"
18029
18030         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
18031                 error "Ladvise failed with overflowing -e argument"
18032
18033         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
18034                 error "Ladvise failed with overflowing -l argument"
18035
18036         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
18037                 error "Ladvise succeeded with conflicting -l and -e arguments"
18038
18039         echo "Synchronous ladvise should wait"
18040         local delay=4
18041 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
18042         do_nodes $(comma_list $(osts_nodes)) \
18043                 $LCTL set_param fail_val=$delay fail_loc=0x237
18044
18045         local start_ts=$SECONDS
18046         lfs ladvise -a willread $DIR/$tfile ||
18047                 error "Ladvise failed with no range argument"
18048         local end_ts=$SECONDS
18049         local inteval_ts=$((end_ts - start_ts))
18050
18051         if [ $inteval_ts -lt $(($delay - 1)) ]; then
18052                 error "Synchronous advice didn't wait reply"
18053         fi
18054
18055         echo "Asynchronous ladvise shouldn't wait"
18056         local start_ts=$SECONDS
18057         lfs ladvise -a willread -b $DIR/$tfile ||
18058                 error "Ladvise failed with no range argument"
18059         local end_ts=$SECONDS
18060         local inteval_ts=$((end_ts - start_ts))
18061
18062         if [ $inteval_ts -gt $(($delay / 2)) ]; then
18063                 error "Asynchronous advice blocked"
18064         fi
18065
18066         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
18067         ladvise_willread_performance
18068 }
18069 run_test 255a "check 'lfs ladvise -a willread'"
18070
18071 facet_meminfo() {
18072         local facet=$1
18073         local info=$2
18074
18075         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
18076 }
18077
18078 test_255b() {
18079         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
18080                 skip "lustre < 2.8.54 does not support ladvise "
18081         remote_ost_nodsh && skip "remote OST with nodsh"
18082
18083         lfs setstripe -c 1 -i 0 $DIR/$tfile
18084
18085         ladvise_no_type dontneed $DIR/$tfile &&
18086                 skip "dontneed ladvise is not supported"
18087
18088         ladvise_no_ioctl $DIR/$tfile &&
18089                 skip "ladvise ioctl is not supported"
18090
18091         ! $LFS ladvise -a dontneed $DIR/$tfile &&
18092                 [ "$ost1_FSTYPE" = "zfs" ] &&
18093                 skip "zfs-osd does not support 'ladvise dontneed'"
18094
18095         local size_mb=100
18096         local size=$((size_mb * 1048576))
18097         # In order to prevent disturbance of other processes, only check 3/4
18098         # of the memory usage
18099         local kibibytes=$((size_mb * 1024 * 3 / 4))
18100
18101         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
18102                 error "dd to $DIR/$tfile failed"
18103
18104         #force write to complete before dropping OST cache & checking memory
18105         sync
18106
18107         local total=$(facet_meminfo ost1 MemTotal)
18108         echo "Total memory: $total KiB"
18109
18110         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
18111         local before_read=$(facet_meminfo ost1 Cached)
18112         echo "Cache used before read: $before_read KiB"
18113
18114         lfs ladvise -a willread $DIR/$tfile ||
18115                 error "Ladvise willread failed"
18116         local after_read=$(facet_meminfo ost1 Cached)
18117         echo "Cache used after read: $after_read KiB"
18118
18119         lfs ladvise -a dontneed $DIR/$tfile ||
18120                 error "Ladvise dontneed again failed"
18121         local no_read=$(facet_meminfo ost1 Cached)
18122         echo "Cache used after dontneed ladvise: $no_read KiB"
18123
18124         if [ $total -lt $((before_read + kibibytes)) ]; then
18125                 echo "Memory is too small, abort checking"
18126                 return 0
18127         fi
18128
18129         if [ $((before_read + kibibytes)) -gt $after_read ]; then
18130                 error "Ladvise willread should use more memory" \
18131                         "than $kibibytes KiB"
18132         fi
18133
18134         if [ $((no_read + kibibytes)) -gt $after_read ]; then
18135                 error "Ladvise dontneed should release more memory" \
18136                         "than $kibibytes KiB"
18137         fi
18138 }
18139 run_test 255b "check 'lfs ladvise -a dontneed'"
18140
18141 test_255c() {
18142         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
18143                 skip "lustre < 2.10.50 does not support lockahead"
18144
18145         local count
18146         local new_count
18147         local difference
18148         local i
18149         local rc
18150
18151         test_mkdir -p $DIR/$tdir
18152         $LFS setstripe -i 0 -c 1 $DIR/$tdir
18153
18154         #test 10 returns only success/failure
18155         i=10
18156         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18157         rc=$?
18158         if [ $rc -eq 255 ]; then
18159                 error "Ladvise test${i} failed, ${rc}"
18160         fi
18161
18162         #test 11 counts lock enqueue requests, all others count new locks
18163         i=11
18164         count=$(do_facet ost1 \
18165                 $LCTL get_param -n ost.OSS.ost.stats)
18166         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
18167
18168         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18169         rc=$?
18170         if [ $rc -eq 255 ]; then
18171                 error "Ladvise test${i} failed, ${rc}"
18172         fi
18173
18174         new_count=$(do_facet ost1 \
18175                 $LCTL get_param -n ost.OSS.ost.stats)
18176         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
18177                    awk '{ print $2 }')
18178
18179         difference="$((new_count - count))"
18180         if [ $difference -ne $rc ]; then
18181                 error "Ladvise test${i}, bad enqueue count, returned " \
18182                       "${rc}, actual ${difference}"
18183         fi
18184
18185         for i in $(seq 12 21); do
18186                 # If we do not do this, we run the risk of having too many
18187                 # locks and starting lock cancellation while we are checking
18188                 # lock counts.
18189                 cancel_lru_locks osc
18190
18191                 count=$($LCTL get_param -n \
18192                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
18193
18194                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
18195                 rc=$?
18196                 if [ $rc -eq 255 ]; then
18197                         error "Ladvise test ${i} failed, ${rc}"
18198                 fi
18199
18200                 new_count=$($LCTL get_param -n \
18201                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
18202                 difference="$((new_count - count))"
18203
18204                 # Test 15 output is divided by 100 to map down to valid return
18205                 if [ $i -eq 15 ]; then
18206                         rc="$((rc * 100))"
18207                 fi
18208
18209                 if [ $difference -ne $rc ]; then
18210                         error "Ladvise test ${i}, bad lock count, returned " \
18211                               "${rc}, actual ${difference}"
18212                 fi
18213         done
18214
18215         #test 22 returns only success/failure
18216         i=22
18217         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18218         rc=$?
18219         if [ $rc -eq 255 ]; then
18220                 error "Ladvise test${i} failed, ${rc}"
18221         fi
18222 }
18223 run_test 255c "suite of ladvise lockahead tests"
18224
18225 test_256() {
18226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18227         remote_mds_nodsh && skip "remote MDS with nodsh"
18228         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18229         changelog_users $SINGLEMDS | grep "^cl" &&
18230                 skip "active changelog user"
18231
18232         local cl_user
18233         local cat_sl
18234         local mdt_dev
18235
18236         mdt_dev=$(mdsdevname 1)
18237         echo $mdt_dev
18238
18239         changelog_register || error "changelog_register failed"
18240
18241         rm -rf $DIR/$tdir
18242         mkdir -p $DIR/$tdir
18243
18244         changelog_clear 0 || error "changelog_clear failed"
18245
18246         # change something
18247         touch $DIR/$tdir/{1..10}
18248
18249         # stop the MDT
18250         stop $SINGLEMDS || error "Fail to stop MDT"
18251
18252         # remount the MDT
18253
18254         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
18255
18256         #after mount new plainllog is used
18257         touch $DIR/$tdir/{11..19}
18258         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
18259         stack_trap "rm -f $tmpfile"
18260         cat_sl=$(do_facet $SINGLEMDS "sync; \
18261                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18262                  llog_reader $tmpfile | grep -c type=1064553b")
18263         do_facet $SINGLEMDS llog_reader $tmpfile
18264
18265         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
18266
18267         changelog_clear 0 || error "changelog_clear failed"
18268
18269         cat_sl=$(do_facet $SINGLEMDS "sync; \
18270                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18271                  llog_reader $tmpfile | grep -c type=1064553b")
18272
18273         if (( cat_sl == 2 )); then
18274                 error "Empty plain llog was not deleted from changelog catalog"
18275         elif (( cat_sl != 1 )); then
18276                 error "Active plain llog shouldn't be deleted from catalog"
18277         fi
18278 }
18279 run_test 256 "Check llog delete for empty and not full state"
18280
18281 test_257() {
18282         remote_mds_nodsh && skip "remote MDS with nodsh"
18283         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
18284                 skip "Need MDS version at least 2.8.55"
18285
18286         test_mkdir $DIR/$tdir
18287
18288         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
18289                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
18290         stat $DIR/$tdir
18291
18292 #define OBD_FAIL_MDS_XATTR_REP                  0x161
18293         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18294         local facet=mds$((mdtidx + 1))
18295         set_nodes_failloc $(facet_active_host $facet) 0x80000161
18296         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
18297
18298         stop $facet || error "stop MDS failed"
18299         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
18300                 error "start MDS fail"
18301         wait_recovery_complete $facet
18302 }
18303 run_test 257 "xattr locks are not lost"
18304
18305 # Verify we take the i_mutex when security requires it
18306 test_258a() {
18307 #define OBD_FAIL_IMUTEX_SEC 0x141c
18308         $LCTL set_param fail_loc=0x141c
18309         touch $DIR/$tfile
18310         chmod u+s $DIR/$tfile
18311         chmod a+rwx $DIR/$tfile
18312         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18313         RC=$?
18314         if [ $RC -ne 0 ]; then
18315                 error "error, failed to take i_mutex, rc=$?"
18316         fi
18317         rm -f $DIR/$tfile
18318 }
18319 run_test 258a "verify i_mutex security behavior when suid attributes is set"
18320
18321 # Verify we do NOT take the i_mutex in the normal case
18322 test_258b() {
18323 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
18324         $LCTL set_param fail_loc=0x141d
18325         touch $DIR/$tfile
18326         chmod a+rwx $DIR
18327         chmod a+rw $DIR/$tfile
18328         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18329         RC=$?
18330         if [ $RC -ne 0 ]; then
18331                 error "error, took i_mutex unnecessarily, rc=$?"
18332         fi
18333         rm -f $DIR/$tfile
18334
18335 }
18336 run_test 258b "verify i_mutex security behavior"
18337
18338 test_259() {
18339         local file=$DIR/$tfile
18340         local before
18341         local after
18342
18343         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18344
18345         stack_trap "rm -f $file" EXIT
18346
18347         wait_delete_completed
18348         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18349         echo "before: $before"
18350
18351         $LFS setstripe -i 0 -c 1 $file
18352         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
18353         sync_all_data
18354         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18355         echo "after write: $after"
18356
18357 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
18358         do_facet ost1 $LCTL set_param fail_loc=0x2301
18359         $TRUNCATE $file 0
18360         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18361         echo "after truncate: $after"
18362
18363         stop ost1
18364         do_facet ost1 $LCTL set_param fail_loc=0
18365         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18366         sleep 2
18367         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18368         echo "after restart: $after"
18369         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
18370                 error "missing truncate?"
18371
18372         return 0
18373 }
18374 run_test 259 "crash at delayed truncate"
18375
18376 test_260() {
18377 #define OBD_FAIL_MDC_CLOSE               0x806
18378         $LCTL set_param fail_loc=0x80000806
18379         touch $DIR/$tfile
18380
18381 }
18382 run_test 260 "Check mdc_close fail"
18383
18384 ### Data-on-MDT sanity tests ###
18385 test_270a() {
18386         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18387                 skip "Need MDS version at least 2.10.55 for DoM"
18388
18389         # create DoM file
18390         local dom=$DIR/$tdir/dom_file
18391         local tmp=$DIR/$tdir/tmp_file
18392
18393         mkdir -p $DIR/$tdir
18394
18395         # basic checks for DoM component creation
18396         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
18397                 error "Can set MDT layout to non-first entry"
18398
18399         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
18400                 error "Can define multiple entries as MDT layout"
18401
18402         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
18403
18404         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
18405         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
18406         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
18407
18408         local mdtidx=$($LFS getstripe -m $dom)
18409         local mdtname=MDT$(printf %04x $mdtidx)
18410         local facet=mds$((mdtidx + 1))
18411         local space_check=1
18412
18413         # Skip free space checks with ZFS
18414         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
18415
18416         # write
18417         sync
18418         local size_tmp=$((65536 * 3))
18419         local mdtfree1=$(do_facet $facet \
18420                          lctl get_param -n osd*.*$mdtname.kbytesfree)
18421
18422         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18423         # check also direct IO along write
18424         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
18425         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18426         sync
18427         cmp $tmp $dom || error "file data is different"
18428         [ $(stat -c%s $dom) == $size_tmp ] ||
18429                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18430         if [ $space_check == 1 ]; then
18431                 local mdtfree2=$(do_facet $facet \
18432                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
18433
18434                 # increase in usage from by $size_tmp
18435                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18436                         error "MDT free space wrong after write: " \
18437                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18438         fi
18439
18440         # truncate
18441         local size_dom=10000
18442
18443         $TRUNCATE $dom $size_dom
18444         [ $(stat -c%s $dom) == $size_dom ] ||
18445                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
18446         if [ $space_check == 1 ]; then
18447                 mdtfree1=$(do_facet $facet \
18448                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18449                 # decrease in usage from $size_tmp to new $size_dom
18450                 [ $(($mdtfree1 - $mdtfree2)) -ge \
18451                   $(((size_tmp - size_dom) / 1024)) ] ||
18452                         error "MDT free space is wrong after truncate: " \
18453                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
18454         fi
18455
18456         # append
18457         cat $tmp >> $dom
18458         sync
18459         size_dom=$((size_dom + size_tmp))
18460         [ $(stat -c%s $dom) == $size_dom ] ||
18461                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
18462         if [ $space_check == 1 ]; then
18463                 mdtfree2=$(do_facet $facet \
18464                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18465                 # increase in usage by $size_tmp from previous
18466                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18467                         error "MDT free space is wrong after append: " \
18468                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18469         fi
18470
18471         # delete
18472         rm $dom
18473         if [ $space_check == 1 ]; then
18474                 mdtfree1=$(do_facet $facet \
18475                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18476                 # decrease in usage by $size_dom from previous
18477                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
18478                         error "MDT free space is wrong after removal: " \
18479                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
18480         fi
18481
18482         # combined striping
18483         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
18484                 error "Can't create DoM + OST striping"
18485
18486         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
18487         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18488         # check also direct IO along write
18489         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18490         sync
18491         cmp $tmp $dom || error "file data is different"
18492         [ $(stat -c%s $dom) == $size_tmp ] ||
18493                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18494         rm $dom $tmp
18495
18496         return 0
18497 }
18498 run_test 270a "DoM: basic functionality tests"
18499
18500 test_270b() {
18501         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18502                 skip "Need MDS version at least 2.10.55"
18503
18504         local dom=$DIR/$tdir/dom_file
18505         local max_size=1048576
18506
18507         mkdir -p $DIR/$tdir
18508         $LFS setstripe -E $max_size -L mdt $dom
18509
18510         # truncate over the limit
18511         $TRUNCATE $dom $(($max_size + 1)) &&
18512                 error "successful truncate over the maximum size"
18513         # write over the limit
18514         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
18515                 error "successful write over the maximum size"
18516         # append over the limit
18517         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
18518         echo "12345" >> $dom && error "successful append over the maximum size"
18519         rm $dom
18520
18521         return 0
18522 }
18523 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
18524
18525 test_270c() {
18526         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18527                 skip "Need MDS version at least 2.10.55"
18528
18529         mkdir -p $DIR/$tdir
18530         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18531
18532         # check files inherit DoM EA
18533         touch $DIR/$tdir/first
18534         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
18535                 error "bad pattern"
18536         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
18537                 error "bad stripe count"
18538         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
18539                 error "bad stripe size"
18540
18541         # check directory inherits DoM EA and uses it as default
18542         mkdir $DIR/$tdir/subdir
18543         touch $DIR/$tdir/subdir/second
18544         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
18545                 error "bad pattern in sub-directory"
18546         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
18547                 error "bad stripe count in sub-directory"
18548         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
18549                 error "bad stripe size in sub-directory"
18550         return 0
18551 }
18552 run_test 270c "DoM: DoM EA inheritance tests"
18553
18554 test_270d() {
18555         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18556                 skip "Need MDS version at least 2.10.55"
18557
18558         mkdir -p $DIR/$tdir
18559         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18560
18561         # inherit default DoM striping
18562         mkdir $DIR/$tdir/subdir
18563         touch $DIR/$tdir/subdir/f1
18564
18565         # change default directory striping
18566         $LFS setstripe -c 1 $DIR/$tdir/subdir
18567         touch $DIR/$tdir/subdir/f2
18568         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
18569                 error "wrong default striping in file 2"
18570         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
18571                 error "bad pattern in file 2"
18572         return 0
18573 }
18574 run_test 270d "DoM: change striping from DoM to RAID0"
18575
18576 test_270e() {
18577         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18578                 skip "Need MDS version at least 2.10.55"
18579
18580         mkdir -p $DIR/$tdir/dom
18581         mkdir -p $DIR/$tdir/norm
18582         DOMFILES=20
18583         NORMFILES=10
18584         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
18585         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
18586
18587         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
18588         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
18589
18590         # find DoM files by layout
18591         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
18592         [ $NUM -eq  $DOMFILES ] ||
18593                 error "lfs find -L: found $NUM, expected $DOMFILES"
18594         echo "Test 1: lfs find 20 DOM files by layout: OK"
18595
18596         # there should be 1 dir with default DOM striping
18597         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
18598         [ $NUM -eq  1 ] ||
18599                 error "lfs find -L: found $NUM, expected 1 dir"
18600         echo "Test 2: lfs find 1 DOM dir by layout: OK"
18601
18602         # find DoM files by stripe size
18603         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
18604         [ $NUM -eq  $DOMFILES ] ||
18605                 error "lfs find -S: found $NUM, expected $DOMFILES"
18606         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
18607
18608         # find files by stripe offset except DoM files
18609         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
18610         [ $NUM -eq  $NORMFILES ] ||
18611                 error "lfs find -i: found $NUM, expected $NORMFILES"
18612         echo "Test 5: lfs find no DOM files by stripe index: OK"
18613         return 0
18614 }
18615 run_test 270e "DoM: lfs find with DoM files test"
18616
18617 test_270f() {
18618         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18619                 skip "Need MDS version at least 2.10.55"
18620
18621         local mdtname=${FSNAME}-MDT0000-mdtlov
18622         local dom=$DIR/$tdir/dom_file
18623         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
18624                                                 lod.$mdtname.dom_stripesize)
18625         local dom_limit=131072
18626
18627         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
18628         local dom_current=$(do_facet mds1 $LCTL get_param -n \
18629                                                 lod.$mdtname.dom_stripesize)
18630         [ ${dom_limit} -eq ${dom_current} ] ||
18631                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
18632
18633         $LFS mkdir -i 0 -c 1 $DIR/$tdir
18634         $LFS setstripe -d $DIR/$tdir
18635         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
18636                 error "Can't set directory default striping"
18637
18638         # exceed maximum stripe size
18639         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18640                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
18641         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
18642                 error "Able to create DoM component size more than LOD limit"
18643
18644         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
18645         dom_current=$(do_facet mds1 $LCTL get_param -n \
18646                                                 lod.$mdtname.dom_stripesize)
18647         [ 0 -eq ${dom_current} ] ||
18648                 error "Can't set zero DoM stripe limit"
18649         rm $dom
18650
18651         # attempt to create DoM file on server with disabled DoM should
18652         # remove DoM entry from layout and be succeed
18653         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
18654                 error "Can't create DoM file (DoM is disabled)"
18655         [ $($LFS getstripe -L $dom) == "mdt" ] &&
18656                 error "File has DoM component while DoM is disabled"
18657         rm $dom
18658
18659         # attempt to create DoM file with only DoM stripe should return error
18660         $LFS setstripe -E $dom_limit -L mdt $dom &&
18661                 error "Able to create DoM-only file while DoM is disabled"
18662
18663         # too low values to be aligned with smallest stripe size 64K
18664         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
18665         dom_current=$(do_facet mds1 $LCTL get_param -n \
18666                                                 lod.$mdtname.dom_stripesize)
18667         [ 30000 -eq ${dom_current} ] &&
18668                 error "Can set too small DoM stripe limit"
18669
18670         # 64K is a minimal stripe size in Lustre, expect limit of that size
18671         [ 65536 -eq ${dom_current} ] ||
18672                 error "Limit is not set to 64K but ${dom_current}"
18673
18674         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
18675         dom_current=$(do_facet mds1 $LCTL get_param -n \
18676                                                 lod.$mdtname.dom_stripesize)
18677         echo $dom_current
18678         [ 2147483648 -eq ${dom_current} ] &&
18679                 error "Can set too large DoM stripe limit"
18680
18681         do_facet mds1 $LCTL set_param -n \
18682                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
18683         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18684                 error "Can't create DoM component size after limit change"
18685         do_facet mds1 $LCTL set_param -n \
18686                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
18687         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
18688                 error "Can't create DoM file after limit decrease"
18689         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
18690                 error "Can create big DoM component after limit decrease"
18691         touch ${dom}_def ||
18692                 error "Can't create file with old default layout"
18693
18694         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
18695         return 0
18696 }
18697 run_test 270f "DoM: maximum DoM stripe size checks"
18698
18699 test_271a() {
18700         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18701                 skip "Need MDS version at least 2.10.55"
18702
18703         local dom=$DIR/$tdir/dom
18704
18705         mkdir -p $DIR/$tdir
18706
18707         $LFS setstripe -E 1024K -L mdt $dom
18708
18709         lctl set_param -n mdc.*.stats=clear
18710         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18711         cat $dom > /dev/null
18712         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
18713         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
18714         ls $dom
18715         rm -f $dom
18716 }
18717 run_test 271a "DoM: data is cached for read after write"
18718
18719 test_271b() {
18720         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18721                 skip "Need MDS version at least 2.10.55"
18722
18723         local dom=$DIR/$tdir/dom
18724
18725         mkdir -p $DIR/$tdir
18726
18727         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18728
18729         lctl set_param -n mdc.*.stats=clear
18730         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18731         cancel_lru_locks mdc
18732         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
18733         # second stat to check size is cached on client
18734         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
18735         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18736         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
18737         rm -f $dom
18738 }
18739 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
18740
18741 test_271ba() {
18742         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18743                 skip "Need MDS version at least 2.10.55"
18744
18745         local dom=$DIR/$tdir/dom
18746
18747         mkdir -p $DIR/$tdir
18748
18749         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18750
18751         lctl set_param -n mdc.*.stats=clear
18752         lctl set_param -n osc.*.stats=clear
18753         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
18754         cancel_lru_locks mdc
18755         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18756         # second stat to check size is cached on client
18757         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18758         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18759         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
18760         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
18761         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
18762         rm -f $dom
18763 }
18764 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
18765
18766
18767 get_mdc_stats() {
18768         local mdtidx=$1
18769         local param=$2
18770         local mdt=MDT$(printf %04x $mdtidx)
18771
18772         if [ -z $param ]; then
18773                 lctl get_param -n mdc.*$mdt*.stats
18774         else
18775                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
18776         fi
18777 }
18778
18779 test_271c() {
18780         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18781                 skip "Need MDS version at least 2.10.55"
18782
18783         local dom=$DIR/$tdir/dom
18784
18785         mkdir -p $DIR/$tdir
18786
18787         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18788
18789         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18790         local facet=mds$((mdtidx + 1))
18791
18792         cancel_lru_locks mdc
18793         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
18794         createmany -o $dom 1000
18795         lctl set_param -n mdc.*.stats=clear
18796         smalliomany -w $dom 1000 200
18797         get_mdc_stats $mdtidx
18798         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18799         # Each file has 1 open, 1 IO enqueues, total 2000
18800         # but now we have also +1 getxattr for security.capability, total 3000
18801         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
18802         unlinkmany $dom 1000
18803
18804         cancel_lru_locks mdc
18805         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
18806         createmany -o $dom 1000
18807         lctl set_param -n mdc.*.stats=clear
18808         smalliomany -w $dom 1000 200
18809         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18810         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
18811         # for OPEN and IO lock.
18812         [ $((enq - enq_2)) -ge 1000 ] ||
18813                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
18814         unlinkmany $dom 1000
18815         return 0
18816 }
18817 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
18818
18819 cleanup_271def_tests() {
18820         trap 0
18821         rm -f $1
18822 }
18823
18824 test_271d() {
18825         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18826                 skip "Need MDS version at least 2.10.57"
18827
18828         local dom=$DIR/$tdir/dom
18829         local tmp=$TMP/$tfile
18830         trap "cleanup_271def_tests $tmp" EXIT
18831
18832         mkdir -p $DIR/$tdir
18833
18834         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18835
18836         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18837
18838         cancel_lru_locks mdc
18839         dd if=/dev/urandom of=$tmp bs=1000 count=1
18840         dd if=$tmp of=$dom bs=1000 count=1
18841         cancel_lru_locks mdc
18842
18843         cat /etc/hosts >> $tmp
18844         lctl set_param -n mdc.*.stats=clear
18845
18846         # append data to the same file it should update local page
18847         echo "Append to the same page"
18848         cat /etc/hosts >> $dom
18849         local num=$(get_mdc_stats $mdtidx ost_read)
18850         local ra=$(get_mdc_stats $mdtidx req_active)
18851         local rw=$(get_mdc_stats $mdtidx req_waittime)
18852
18853         [ -z $num ] || error "$num READ RPC occured"
18854         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18855         echo "... DONE"
18856
18857         # compare content
18858         cmp $tmp $dom || error "file miscompare"
18859
18860         cancel_lru_locks mdc
18861         lctl set_param -n mdc.*.stats=clear
18862
18863         echo "Open and read file"
18864         cat $dom > /dev/null
18865         local num=$(get_mdc_stats $mdtidx ost_read)
18866         local ra=$(get_mdc_stats $mdtidx req_active)
18867         local rw=$(get_mdc_stats $mdtidx req_waittime)
18868
18869         [ -z $num ] || error "$num READ RPC occured"
18870         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18871         echo "... DONE"
18872
18873         # compare content
18874         cmp $tmp $dom || error "file miscompare"
18875
18876         return 0
18877 }
18878 run_test 271d "DoM: read on open (1K file in reply buffer)"
18879
18880 test_271f() {
18881         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18882                 skip "Need MDS version at least 2.10.57"
18883
18884         local dom=$DIR/$tdir/dom
18885         local tmp=$TMP/$tfile
18886         trap "cleanup_271def_tests $tmp" EXIT
18887
18888         mkdir -p $DIR/$tdir
18889
18890         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18891
18892         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18893
18894         cancel_lru_locks mdc
18895         dd if=/dev/urandom of=$tmp bs=265000 count=1
18896         dd if=$tmp of=$dom bs=265000 count=1
18897         cancel_lru_locks mdc
18898         cat /etc/hosts >> $tmp
18899         lctl set_param -n mdc.*.stats=clear
18900
18901         echo "Append to the same page"
18902         cat /etc/hosts >> $dom
18903         local num=$(get_mdc_stats $mdtidx ost_read)
18904         local ra=$(get_mdc_stats $mdtidx req_active)
18905         local rw=$(get_mdc_stats $mdtidx req_waittime)
18906
18907         [ -z $num ] || error "$num READ RPC occured"
18908         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18909         echo "... DONE"
18910
18911         # compare content
18912         cmp $tmp $dom || error "file miscompare"
18913
18914         cancel_lru_locks mdc
18915         lctl set_param -n mdc.*.stats=clear
18916
18917         echo "Open and read file"
18918         cat $dom > /dev/null
18919         local num=$(get_mdc_stats $mdtidx ost_read)
18920         local ra=$(get_mdc_stats $mdtidx req_active)
18921         local rw=$(get_mdc_stats $mdtidx req_waittime)
18922
18923         [ -z $num ] && num=0
18924         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
18925         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18926         echo "... DONE"
18927
18928         # compare content
18929         cmp $tmp $dom || error "file miscompare"
18930
18931         return 0
18932 }
18933 run_test 271f "DoM: read on open (200K file and read tail)"
18934
18935 test_271g() {
18936         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
18937                 skip "Skipping due to old client or server version"
18938
18939         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
18940         # to get layout
18941         $CHECKSTAT -t file $DIR1/$tfile
18942
18943         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
18944         MULTIOP_PID=$!
18945         sleep 1
18946         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
18947         $LCTL set_param fail_loc=0x80000314
18948         rm $DIR1/$tfile || error "Unlink fails"
18949         RC=$?
18950         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
18951         [ $RC -eq 0 ] || error "Failed write to stale object"
18952 }
18953 run_test 271g "Discard DoM data vs client flush race"
18954
18955 test_272a() {
18956         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18957                 skip "Need MDS version at least 2.11.50"
18958
18959         local dom=$DIR/$tdir/dom
18960         mkdir -p $DIR/$tdir
18961
18962         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
18963         dd if=/dev/urandom of=$dom bs=512K count=1 ||
18964                 error "failed to write data into $dom"
18965         local old_md5=$(md5sum $dom)
18966
18967         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
18968                 error "failed to migrate to the same DoM component"
18969
18970         local new_md5=$(md5sum $dom)
18971
18972         [ "$old_md5" == "$new_md5" ] ||
18973                 error "md5sum differ: $old_md5, $new_md5"
18974
18975         [ $($LFS getstripe -c $dom) -eq 2 ] ||
18976                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
18977 }
18978 run_test 272a "DoM migration: new layout with the same DOM component"
18979
18980 test_272b() {
18981         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18982                 skip "Need MDS version at least 2.11.50"
18983
18984         local dom=$DIR/$tdir/dom
18985         mkdir -p $DIR/$tdir
18986         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18987
18988         local mdtidx=$($LFS getstripe -m $dom)
18989         local mdtname=MDT$(printf %04x $mdtidx)
18990         local facet=mds$((mdtidx + 1))
18991
18992         local mdtfree1=$(do_facet $facet \
18993                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18994         dd if=/dev/urandom of=$dom bs=2M count=1 ||
18995                 error "failed to write data into $dom"
18996         local old_md5=$(md5sum $dom)
18997         cancel_lru_locks mdc
18998         local mdtfree1=$(do_facet $facet \
18999                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19000
19001         $LFS migrate -c2 $dom ||
19002                 error "failed to migrate to the new composite layout"
19003         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19004                 error "MDT stripe was not removed"
19005
19006         cancel_lru_locks mdc
19007         local new_md5=$(md5sum $dom)
19008         [ "$old_md5" == "$new_md5" ] ||
19009                 error "$old_md5 != $new_md5"
19010
19011         # Skip free space checks with ZFS
19012         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19013                 local mdtfree2=$(do_facet $facet \
19014                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19015                 [ $mdtfree2 -gt $mdtfree1 ] ||
19016                         error "MDT space is not freed after migration"
19017         fi
19018         return 0
19019 }
19020 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
19021
19022 test_272c() {
19023         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19024                 skip "Need MDS version at least 2.11.50"
19025
19026         local dom=$DIR/$tdir/$tfile
19027         mkdir -p $DIR/$tdir
19028         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
19029
19030         local mdtidx=$($LFS getstripe -m $dom)
19031         local mdtname=MDT$(printf %04x $mdtidx)
19032         local facet=mds$((mdtidx + 1))
19033
19034         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
19035                 error "failed to write data into $dom"
19036         local old_md5=$(md5sum $dom)
19037         cancel_lru_locks mdc
19038         local mdtfree1=$(do_facet $facet \
19039                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19040
19041         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
19042                 error "failed to migrate to the new composite layout"
19043         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
19044                 error "MDT stripe was not removed"
19045
19046         cancel_lru_locks mdc
19047         local new_md5=$(md5sum $dom)
19048         [ "$old_md5" == "$new_md5" ] ||
19049                 error "$old_md5 != $new_md5"
19050
19051         # Skip free space checks with ZFS
19052         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19053                 local mdtfree2=$(do_facet $facet \
19054                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19055                 [ $mdtfree2 -gt $mdtfree1 ] ||
19056                         error "MDS space is not freed after migration"
19057         fi
19058         return 0
19059 }
19060 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
19061
19062 test_272d() {
19063         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19064                 skip "Need MDS version at least 2.12.55"
19065
19066         local dom=$DIR/$tdir/$tfile
19067         mkdir -p $DIR/$tdir
19068         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
19069
19070         local mdtidx=$($LFS getstripe -m $dom)
19071         local mdtname=MDT$(printf %04x $mdtidx)
19072         local facet=mds$((mdtidx + 1))
19073
19074         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
19075                 error "failed to write data into $dom"
19076         local old_md5=$(md5sum $dom)
19077         cancel_lru_locks mdc
19078         local mdtfree1=$(do_facet $facet \
19079                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19080
19081         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
19082                 error "failed mirroring to the new composite layout"
19083         $LFS mirror resync $dom ||
19084                 error "failed mirror resync"
19085         $LFS mirror split --mirror-id 1 -d $dom ||
19086                 error "failed mirror split"
19087
19088         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19089                 error "MDT stripe was not removed"
19090
19091         cancel_lru_locks mdc
19092         local new_md5=$(md5sum $dom)
19093         [ "$old_md5" == "$new_md5" ] ||
19094                 error "$old_md5 != $new_md5"
19095
19096         # Skip free space checks with ZFS
19097         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19098                 local mdtfree2=$(do_facet $facet \
19099                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19100                 [ $mdtfree2 -gt $mdtfree1 ] ||
19101                         error "MDS space is not freed after DOM mirror deletion"
19102         fi
19103         return 0
19104 }
19105 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
19106
19107 test_272e() {
19108         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19109                 skip "Need MDS version at least 2.12.55"
19110
19111         local dom=$DIR/$tdir/$tfile
19112         mkdir -p $DIR/$tdir
19113         $LFS setstripe -c 2 $dom
19114
19115         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
19116                 error "failed to write data into $dom"
19117         local old_md5=$(md5sum $dom)
19118         cancel_lru_locks mdc
19119
19120         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
19121                 error "failed mirroring to the DOM layout"
19122         $LFS mirror resync $dom ||
19123                 error "failed mirror resync"
19124         $LFS mirror split --mirror-id 1 -d $dom ||
19125                 error "failed mirror split"
19126
19127         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19128                 error "MDT stripe was not removed"
19129
19130         cancel_lru_locks mdc
19131         local new_md5=$(md5sum $dom)
19132         [ "$old_md5" == "$new_md5" ] ||
19133                 error "$old_md5 != $new_md5"
19134
19135         return 0
19136 }
19137 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
19138
19139 test_272f() {
19140         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19141                 skip "Need MDS version at least 2.12.55"
19142
19143         local dom=$DIR/$tdir/$tfile
19144         mkdir -p $DIR/$tdir
19145         $LFS setstripe -c 2 $dom
19146
19147         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
19148                 error "failed to write data into $dom"
19149         local old_md5=$(md5sum $dom)
19150         cancel_lru_locks mdc
19151
19152         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
19153                 error "failed migrating to the DOM file"
19154
19155         cancel_lru_locks mdc
19156         local new_md5=$(md5sum $dom)
19157         [ "$old_md5" != "$new_md5" ] &&
19158                 error "$old_md5 != $new_md5"
19159
19160         return 0
19161 }
19162 run_test 272f "DoM migration: OST-striped file to DOM file"
19163
19164 test_273a() {
19165         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19166                 skip "Need MDS version at least 2.11.50"
19167
19168         # Layout swap cannot be done if either file has DOM component,
19169         # this will never be supported, migration should be used instead
19170
19171         local dom=$DIR/$tdir/$tfile
19172         mkdir -p $DIR/$tdir
19173
19174         $LFS setstripe -c2 ${dom}_plain
19175         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
19176         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
19177                 error "can swap layout with DoM component"
19178         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
19179                 error "can swap layout with DoM component"
19180
19181         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
19182         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
19183                 error "can swap layout with DoM component"
19184         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
19185                 error "can swap layout with DoM component"
19186         return 0
19187 }
19188 run_test 273a "DoM: layout swapping should fail with DOM"
19189
19190 test_275() {
19191         remote_ost_nodsh && skip "remote OST with nodsh"
19192         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
19193                 skip "Need OST version >= 2.10.57"
19194
19195         local file=$DIR/$tfile
19196         local oss
19197
19198         oss=$(comma_list $(osts_nodes))
19199
19200         dd if=/dev/urandom of=$file bs=1M count=2 ||
19201                 error "failed to create a file"
19202         cancel_lru_locks osc
19203
19204         #lock 1
19205         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
19206                 error "failed to read a file"
19207
19208 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
19209         $LCTL set_param fail_loc=0x8000031f
19210
19211         cancel_lru_locks osc &
19212         sleep 1
19213
19214 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
19215         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
19216         #IO takes another lock, but matches the PENDING one
19217         #and places it to the IO RPC
19218         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
19219                 error "failed to read a file with PENDING lock"
19220 }
19221 run_test 275 "Read on a canceled duplicate lock"
19222
19223 test_276() {
19224         remote_ost_nodsh && skip "remote OST with nodsh"
19225         local pid
19226
19227         do_facet ost1 "(while true; do \
19228                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
19229                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
19230         pid=$!
19231
19232         for LOOP in $(seq 20); do
19233                 stop ost1
19234                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
19235         done
19236         kill -9 $pid
19237         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
19238                 rm $TMP/sanity_276_pid"
19239 }
19240 run_test 276 "Race between mount and obd_statfs"
19241
19242 test_277() {
19243         $LCTL set_param ldlm.namespaces.*.lru_size=0
19244         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
19245         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19246                         grep ^used_mb | awk '{print $2}')
19247         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
19248         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
19249                 oflag=direct conv=notrunc
19250         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19251                         grep ^used_mb | awk '{print $2}')
19252         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
19253 }
19254 run_test 277 "Direct IO shall drop page cache"
19255
19256 test_278() {
19257         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19258         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19259         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
19260                 skip "needs the same host for mdt1 mdt2" && return
19261
19262         local pid1
19263         local pid2
19264
19265 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
19266         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
19267         stop mds2 &
19268         pid2=$!
19269
19270         stop mds1
19271
19272         echo "Starting MDTs"
19273         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
19274         wait $pid2
19275 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
19276 #will return NULL
19277         do_facet mds2 $LCTL set_param fail_loc=0
19278
19279         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
19280         wait_recovery_complete mds2
19281 }
19282 run_test 278 "Race starting MDS between MDTs stop/start"
19283
19284 cleanup_test_300() {
19285         trap 0
19286         umask $SAVE_UMASK
19287 }
19288 test_striped_dir() {
19289         local mdt_index=$1
19290         local stripe_count
19291         local stripe_index
19292
19293         mkdir -p $DIR/$tdir
19294
19295         SAVE_UMASK=$(umask)
19296         trap cleanup_test_300 RETURN EXIT
19297
19298         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
19299                                                 $DIR/$tdir/striped_dir ||
19300                 error "set striped dir error"
19301
19302         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
19303         [ "$mode" = "755" ] || error "expect 755 got $mode"
19304
19305         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
19306                 error "getdirstripe failed"
19307         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
19308         if [ "$stripe_count" != "2" ]; then
19309                 error "1:stripe_count is $stripe_count, expect 2"
19310         fi
19311         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
19312         if [ "$stripe_count" != "2" ]; then
19313                 error "2:stripe_count is $stripe_count, expect 2"
19314         fi
19315
19316         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
19317         if [ "$stripe_index" != "$mdt_index" ]; then
19318                 error "stripe_index is $stripe_index, expect $mdt_index"
19319         fi
19320
19321         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19322                 error "nlink error after create striped dir"
19323
19324         mkdir $DIR/$tdir/striped_dir/a
19325         mkdir $DIR/$tdir/striped_dir/b
19326
19327         stat $DIR/$tdir/striped_dir/a ||
19328                 error "create dir under striped dir failed"
19329         stat $DIR/$tdir/striped_dir/b ||
19330                 error "create dir under striped dir failed"
19331
19332         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
19333                 error "nlink error after mkdir"
19334
19335         rmdir $DIR/$tdir/striped_dir/a
19336         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
19337                 error "nlink error after rmdir"
19338
19339         rmdir $DIR/$tdir/striped_dir/b
19340         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19341                 error "nlink error after rmdir"
19342
19343         chattr +i $DIR/$tdir/striped_dir
19344         createmany -o $DIR/$tdir/striped_dir/f 10 &&
19345                 error "immutable flags not working under striped dir!"
19346         chattr -i $DIR/$tdir/striped_dir
19347
19348         rmdir $DIR/$tdir/striped_dir ||
19349                 error "rmdir striped dir error"
19350
19351         cleanup_test_300
19352
19353         true
19354 }
19355
19356 test_300a() {
19357         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19358                 skip "skipped for lustre < 2.7.0"
19359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19360         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19361
19362         test_striped_dir 0 || error "failed on striped dir on MDT0"
19363         test_striped_dir 1 || error "failed on striped dir on MDT0"
19364 }
19365 run_test 300a "basic striped dir sanity test"
19366
19367 test_300b() {
19368         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19369                 skip "skipped for lustre < 2.7.0"
19370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19371         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19372
19373         local i
19374         local mtime1
19375         local mtime2
19376         local mtime3
19377
19378         test_mkdir $DIR/$tdir || error "mkdir fail"
19379         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19380                 error "set striped dir error"
19381         for i in {0..9}; do
19382                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
19383                 sleep 1
19384                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
19385                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
19386                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
19387                 sleep 1
19388                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
19389                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
19390                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
19391         done
19392         true
19393 }
19394 run_test 300b "check ctime/mtime for striped dir"
19395
19396 test_300c() {
19397         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19398                 skip "skipped for lustre < 2.7.0"
19399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19400         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19401
19402         local file_count
19403
19404         mkdir -p $DIR/$tdir
19405         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
19406                 error "set striped dir error"
19407
19408         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
19409                 error "chown striped dir failed"
19410
19411         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
19412                 error "create 5k files failed"
19413
19414         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
19415
19416         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
19417
19418         rm -rf $DIR/$tdir
19419 }
19420 run_test 300c "chown && check ls under striped directory"
19421
19422 test_300d() {
19423         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19424                 skip "skipped for lustre < 2.7.0"
19425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19426         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19427
19428         local stripe_count
19429         local file
19430
19431         mkdir -p $DIR/$tdir
19432         $LFS setstripe -c 2 $DIR/$tdir
19433
19434         #local striped directory
19435         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19436                 error "set striped dir error"
19437         createmany -o $DIR/$tdir/striped_dir/f 10 ||
19438                 error "create 10 files failed"
19439
19440         #remote striped directory
19441         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
19442                 error "set striped dir error"
19443         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
19444                 error "create 10 files failed"
19445
19446         for file in $(find $DIR/$tdir); do
19447                 stripe_count=$($LFS getstripe -c $file)
19448                 [ $stripe_count -eq 2 ] ||
19449                         error "wrong stripe $stripe_count for $file"
19450         done
19451
19452         rm -rf $DIR/$tdir
19453 }
19454 run_test 300d "check default stripe under striped directory"
19455
19456 test_300e() {
19457         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19458                 skip "Need MDS version at least 2.7.55"
19459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19460         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19461
19462         local stripe_count
19463         local file
19464
19465         mkdir -p $DIR/$tdir
19466
19467         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19468                 error "set striped dir error"
19469
19470         touch $DIR/$tdir/striped_dir/a
19471         touch $DIR/$tdir/striped_dir/b
19472         touch $DIR/$tdir/striped_dir/c
19473
19474         mkdir $DIR/$tdir/striped_dir/dir_a
19475         mkdir $DIR/$tdir/striped_dir/dir_b
19476         mkdir $DIR/$tdir/striped_dir/dir_c
19477
19478         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
19479                 error "set striped adir under striped dir error"
19480
19481         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
19482                 error "set striped bdir under striped dir error"
19483
19484         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
19485                 error "set striped cdir under striped dir error"
19486
19487         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
19488                 error "rename dir under striped dir fails"
19489
19490         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
19491                 error "rename dir under different stripes fails"
19492
19493         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
19494                 error "rename file under striped dir should succeed"
19495
19496         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
19497                 error "rename dir under striped dir should succeed"
19498
19499         rm -rf $DIR/$tdir
19500 }
19501 run_test 300e "check rename under striped directory"
19502
19503 test_300f() {
19504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19505         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19506         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19507                 skip "Need MDS version at least 2.7.55"
19508
19509         local stripe_count
19510         local file
19511
19512         rm -rf $DIR/$tdir
19513         mkdir -p $DIR/$tdir
19514
19515         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19516                 error "set striped dir error"
19517
19518         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
19519                 error "set striped dir error"
19520
19521         touch $DIR/$tdir/striped_dir/a
19522         mkdir $DIR/$tdir/striped_dir/dir_a
19523         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
19524                 error "create striped dir under striped dir fails"
19525
19526         touch $DIR/$tdir/striped_dir1/b
19527         mkdir $DIR/$tdir/striped_dir1/dir_b
19528         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
19529                 error "create striped dir under striped dir fails"
19530
19531         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
19532                 error "rename dir under different striped dir should fail"
19533
19534         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
19535                 error "rename striped dir under diff striped dir should fail"
19536
19537         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
19538                 error "rename file under diff striped dirs fails"
19539
19540         rm -rf $DIR/$tdir
19541 }
19542 run_test 300f "check rename cross striped directory"
19543
19544 test_300_check_default_striped_dir()
19545 {
19546         local dirname=$1
19547         local default_count=$2
19548         local default_index=$3
19549         local stripe_count
19550         local stripe_index
19551         local dir_stripe_index
19552         local dir
19553
19554         echo "checking $dirname $default_count $default_index"
19555         $LFS setdirstripe -D -c $default_count -i $default_index \
19556                                 -t all_char $DIR/$tdir/$dirname ||
19557                 error "set default stripe on striped dir error"
19558         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
19559         [ $stripe_count -eq $default_count ] ||
19560                 error "expect $default_count get $stripe_count for $dirname"
19561
19562         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
19563         [ $stripe_index -eq $default_index ] ||
19564                 error "expect $default_index get $stripe_index for $dirname"
19565
19566         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
19567                                                 error "create dirs failed"
19568
19569         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
19570         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
19571         for dir in $(find $DIR/$tdir/$dirname/*); do
19572                 stripe_count=$($LFS getdirstripe -c $dir)
19573                 [ $stripe_count -eq $default_count ] ||
19574                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
19575                 error "stripe count $default_count != $stripe_count for $dir"
19576
19577                 stripe_index=$($LFS getdirstripe -i $dir)
19578                 [ $default_index -eq -1 ] ||
19579                         [ $stripe_index -eq $default_index ] ||
19580                         error "$stripe_index != $default_index for $dir"
19581
19582                 #check default stripe
19583                 stripe_count=$($LFS getdirstripe -D -c $dir)
19584                 [ $stripe_count -eq $default_count ] ||
19585                 error "default count $default_count != $stripe_count for $dir"
19586
19587                 stripe_index=$($LFS getdirstripe -D -i $dir)
19588                 [ $stripe_index -eq $default_index ] ||
19589                 error "default index $default_index != $stripe_index for $dir"
19590         done
19591         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
19592 }
19593
19594 test_300g() {
19595         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19596         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19597                 skip "Need MDS version at least 2.7.55"
19598
19599         local dir
19600         local stripe_count
19601         local stripe_index
19602
19603         mkdir $DIR/$tdir
19604         mkdir $DIR/$tdir/normal_dir
19605
19606         #Checking when client cache stripe index
19607         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
19608         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
19609                 error "create striped_dir failed"
19610
19611         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
19612                 error "create dir0 fails"
19613         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
19614         [ $stripe_index -eq 0 ] ||
19615                 error "dir0 expect index 0 got $stripe_index"
19616
19617         mkdir $DIR/$tdir/striped_dir/dir1 ||
19618                 error "create dir1 fails"
19619         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
19620         [ $stripe_index -eq 1 ] ||
19621                 error "dir1 expect index 1 got $stripe_index"
19622
19623         #check default stripe count/stripe index
19624         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
19625         test_300_check_default_striped_dir normal_dir 1 0
19626         test_300_check_default_striped_dir normal_dir 2 1
19627         test_300_check_default_striped_dir normal_dir 2 -1
19628
19629         #delete default stripe information
19630         echo "delete default stripeEA"
19631         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
19632                 error "set default stripe on striped dir error"
19633
19634         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
19635         for dir in $(find $DIR/$tdir/normal_dir/*); do
19636                 stripe_count=$($LFS getdirstripe -c $dir)
19637                 [ $stripe_count -eq 0 ] ||
19638                         error "expect 1 get $stripe_count for $dir"
19639                 stripe_index=$($LFS getdirstripe -i $dir)
19640                 [ $stripe_index -eq 0 ] ||
19641                         error "expect 0 get $stripe_index for $dir"
19642         done
19643 }
19644 run_test 300g "check default striped directory for normal directory"
19645
19646 test_300h() {
19647         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19648         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19649                 skip "Need MDS version at least 2.7.55"
19650
19651         local dir
19652         local stripe_count
19653
19654         mkdir $DIR/$tdir
19655         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19656                 error "set striped dir error"
19657
19658         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
19659         test_300_check_default_striped_dir striped_dir 1 0
19660         test_300_check_default_striped_dir striped_dir 2 1
19661         test_300_check_default_striped_dir striped_dir 2 -1
19662
19663         #delete default stripe information
19664         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
19665                 error "set default stripe on striped dir error"
19666
19667         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
19668         for dir in $(find $DIR/$tdir/striped_dir/*); do
19669                 stripe_count=$($LFS getdirstripe -c $dir)
19670                 [ $stripe_count -eq 0 ] ||
19671                         error "expect 1 get $stripe_count for $dir"
19672         done
19673 }
19674 run_test 300h "check default striped directory for striped directory"
19675
19676 test_300i() {
19677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19678         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19679         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19680                 skip "Need MDS version at least 2.7.55"
19681
19682         local stripe_count
19683         local file
19684
19685         mkdir $DIR/$tdir
19686
19687         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19688                 error "set striped dir error"
19689
19690         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
19691                 error "create files under striped dir failed"
19692
19693         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
19694                 error "set striped hashdir error"
19695
19696         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
19697                 error "create dir0 under hash dir failed"
19698         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
19699                 error "create dir1 under hash dir failed"
19700
19701         # unfortunately, we need to umount to clear dir layout cache for now
19702         # once we fully implement dir layout, we can drop this
19703         umount_client $MOUNT || error "umount failed"
19704         mount_client $MOUNT || error "mount failed"
19705
19706         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
19707         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
19708         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
19709
19710         #set the stripe to be unknown hash type
19711         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
19712         $LCTL set_param fail_loc=0x1901
19713         for ((i = 0; i < 10; i++)); do
19714                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
19715                         error "stat f-$i failed"
19716                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
19717         done
19718
19719         touch $DIR/$tdir/striped_dir/f0 &&
19720                 error "create under striped dir with unknown hash should fail"
19721
19722         $LCTL set_param fail_loc=0
19723
19724         umount_client $MOUNT || error "umount failed"
19725         mount_client $MOUNT || error "mount failed"
19726
19727         return 0
19728 }
19729 run_test 300i "client handle unknown hash type striped directory"
19730
19731 test_300j() {
19732         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19734         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19735                 skip "Need MDS version at least 2.7.55"
19736
19737         local stripe_count
19738         local file
19739
19740         mkdir $DIR/$tdir
19741
19742         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
19743         $LCTL set_param fail_loc=0x1702
19744         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19745                 error "set striped dir error"
19746
19747         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
19748                 error "create files under striped dir failed"
19749
19750         $LCTL set_param fail_loc=0
19751
19752         rm -rf $DIR/$tdir || error "unlink striped dir fails"
19753
19754         return 0
19755 }
19756 run_test 300j "test large update record"
19757
19758 test_300k() {
19759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19760         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19761         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19762                 skip "Need MDS version at least 2.7.55"
19763
19764         # this test needs a huge transaction
19765         local kb
19766         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19767              osd*.$FSNAME-MDT0000.kbytestotal")
19768         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
19769
19770         local stripe_count
19771         local file
19772
19773         mkdir $DIR/$tdir
19774
19775         #define OBD_FAIL_LARGE_STRIPE   0x1703
19776         $LCTL set_param fail_loc=0x1703
19777         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
19778                 error "set striped dir error"
19779         $LCTL set_param fail_loc=0
19780
19781         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19782                 error "getstripeddir fails"
19783         rm -rf $DIR/$tdir/striped_dir ||
19784                 error "unlink striped dir fails"
19785
19786         return 0
19787 }
19788 run_test 300k "test large striped directory"
19789
19790 test_300l() {
19791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19792         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19793         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19794                 skip "Need MDS version at least 2.7.55"
19795
19796         local stripe_index
19797
19798         test_mkdir -p $DIR/$tdir/striped_dir
19799         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
19800                         error "chown $RUNAS_ID failed"
19801         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
19802                 error "set default striped dir failed"
19803
19804         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
19805         $LCTL set_param fail_loc=0x80000158
19806         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
19807
19808         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
19809         [ $stripe_index -eq 1 ] ||
19810                 error "expect 1 get $stripe_index for $dir"
19811 }
19812 run_test 300l "non-root user to create dir under striped dir with stale layout"
19813
19814 test_300m() {
19815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19816         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
19817         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19818                 skip "Need MDS version at least 2.7.55"
19819
19820         mkdir -p $DIR/$tdir/striped_dir
19821         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
19822                 error "set default stripes dir error"
19823
19824         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
19825
19826         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
19827         [ $stripe_count -eq 0 ] ||
19828                         error "expect 0 get $stripe_count for a"
19829
19830         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
19831                 error "set default stripes dir error"
19832
19833         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
19834
19835         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
19836         [ $stripe_count -eq 0 ] ||
19837                         error "expect 0 get $stripe_count for b"
19838
19839         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
19840                 error "set default stripes dir error"
19841
19842         mkdir $DIR/$tdir/striped_dir/c &&
19843                 error "default stripe_index is invalid, mkdir c should fails"
19844
19845         rm -rf $DIR/$tdir || error "rmdir fails"
19846 }
19847 run_test 300m "setstriped directory on single MDT FS"
19848
19849 cleanup_300n() {
19850         local list=$(comma_list $(mdts_nodes))
19851
19852         trap 0
19853         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19854 }
19855
19856 test_300n() {
19857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19858         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19859         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19860                 skip "Need MDS version at least 2.7.55"
19861         remote_mds_nodsh && skip "remote MDS with nodsh"
19862
19863         local stripe_index
19864         local list=$(comma_list $(mdts_nodes))
19865
19866         trap cleanup_300n RETURN EXIT
19867         mkdir -p $DIR/$tdir
19868         chmod 777 $DIR/$tdir
19869         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
19870                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19871                 error "create striped dir succeeds with gid=0"
19872
19873         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19874         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
19875                 error "create striped dir fails with gid=-1"
19876
19877         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19878         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
19879                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19880                 error "set default striped dir succeeds with gid=0"
19881
19882
19883         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19884         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
19885                 error "set default striped dir fails with gid=-1"
19886
19887
19888         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19889         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
19890                                         error "create test_dir fails"
19891         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
19892                                         error "create test_dir1 fails"
19893         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
19894                                         error "create test_dir2 fails"
19895         cleanup_300n
19896 }
19897 run_test 300n "non-root user to create dir under striped dir with default EA"
19898
19899 test_300o() {
19900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19901         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19902         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19903                 skip "Need MDS version at least 2.7.55"
19904
19905         local numfree1
19906         local numfree2
19907
19908         mkdir -p $DIR/$tdir
19909
19910         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
19911         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
19912         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
19913                 skip "not enough free inodes $numfree1 $numfree2"
19914         fi
19915
19916         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
19917         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
19918         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
19919                 skip "not enough free space $numfree1 $numfree2"
19920         fi
19921
19922         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
19923                 error "setdirstripe fails"
19924
19925         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
19926                 error "create dirs fails"
19927
19928         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
19929         ls $DIR/$tdir/striped_dir > /dev/null ||
19930                 error "ls striped dir fails"
19931         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
19932                 error "unlink big striped dir fails"
19933 }
19934 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
19935
19936 test_300p() {
19937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19938         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19939         remote_mds_nodsh && skip "remote MDS with nodsh"
19940
19941         mkdir -p $DIR/$tdir
19942
19943         #define OBD_FAIL_OUT_ENOSPC     0x1704
19944         do_facet mds2 lctl set_param fail_loc=0x80001704
19945         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
19946                  && error "create striped directory should fail"
19947
19948         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
19949
19950         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
19951         true
19952 }
19953 run_test 300p "create striped directory without space"
19954
19955 test_300q() {
19956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19957         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19958
19959         local fd=$(free_fd)
19960         local cmd="exec $fd<$tdir"
19961         cd $DIR
19962         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
19963         eval $cmd
19964         cmd="exec $fd<&-"
19965         trap "eval $cmd" EXIT
19966         cd $tdir || error "cd $tdir fails"
19967         rmdir  ../$tdir || error "rmdir $tdir fails"
19968         mkdir local_dir && error "create dir succeeds"
19969         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
19970         eval $cmd
19971         return 0
19972 }
19973 run_test 300q "create remote directory under orphan directory"
19974
19975 test_300r() {
19976         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
19977                 skip "Need MDS version at least 2.7.55" && return
19978         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19979
19980         mkdir $DIR/$tdir
19981
19982         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
19983                 error "set striped dir error"
19984
19985         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19986                 error "getstripeddir fails"
19987
19988         local stripe_count
19989         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19990                       awk '/lmv_stripe_count:/ { print $2 }')
19991
19992         [ $MDSCOUNT -ne $stripe_count ] &&
19993                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
19994
19995         rm -rf $DIR/$tdir/striped_dir ||
19996                 error "unlink striped dir fails"
19997 }
19998 run_test 300r "test -1 striped directory"
19999
20000 prepare_remote_file() {
20001         mkdir $DIR/$tdir/src_dir ||
20002                 error "create remote source failed"
20003
20004         cp /etc/hosts $DIR/$tdir/src_dir/a ||
20005                  error "cp to remote source failed"
20006         touch $DIR/$tdir/src_dir/a
20007
20008         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
20009                 error "create remote target dir failed"
20010
20011         touch $DIR/$tdir/tgt_dir/b
20012
20013         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
20014                 error "rename dir cross MDT failed!"
20015
20016         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
20017                 error "src_child still exists after rename"
20018
20019         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
20020                 error "missing file(a) after rename"
20021
20022         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
20023                 error "diff after rename"
20024 }
20025
20026 test_310a() {
20027         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
20028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20029
20030         local remote_file=$DIR/$tdir/tgt_dir/b
20031
20032         mkdir -p $DIR/$tdir
20033
20034         prepare_remote_file || error "prepare remote file failed"
20035
20036         #open-unlink file
20037         $OPENUNLINK $remote_file $remote_file ||
20038                 error "openunlink $remote_file failed"
20039         $CHECKSTAT -a $remote_file || error "$remote_file exists"
20040 }
20041 run_test 310a "open unlink remote file"
20042
20043 test_310b() {
20044         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
20045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20046
20047         local remote_file=$DIR/$tdir/tgt_dir/b
20048
20049         mkdir -p $DIR/$tdir
20050
20051         prepare_remote_file || error "prepare remote file failed"
20052
20053         ln $remote_file $DIR/$tfile || error "link failed for remote file"
20054         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
20055         $CHECKSTAT -t file $remote_file || error "check file failed"
20056 }
20057 run_test 310b "unlink remote file with multiple links while open"
20058
20059 test_310c() {
20060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20061         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
20062
20063         local remote_file=$DIR/$tdir/tgt_dir/b
20064
20065         mkdir -p $DIR/$tdir
20066
20067         prepare_remote_file || error "prepare remote file failed"
20068
20069         ln $remote_file $DIR/$tfile || error "link failed for remote file"
20070         multiop_bg_pause $remote_file O_uc ||
20071                         error "mulitop failed for remote file"
20072         MULTIPID=$!
20073         $MULTIOP $DIR/$tfile Ouc
20074         kill -USR1 $MULTIPID
20075         wait $MULTIPID
20076 }
20077 run_test 310c "open-unlink remote file with multiple links"
20078
20079 #LU-4825
20080 test_311() {
20081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20082         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
20083         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
20084                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
20085         remote_mds_nodsh && skip "remote MDS with nodsh"
20086
20087         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
20088         local mdts=$(comma_list $(mdts_nodes))
20089
20090         mkdir -p $DIR/$tdir
20091         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20092         createmany -o $DIR/$tdir/$tfile. 1000
20093
20094         # statfs data is not real time, let's just calculate it
20095         old_iused=$((old_iused + 1000))
20096
20097         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20098                         osp.*OST0000*MDT0000.create_count")
20099         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20100                                 osp.*OST0000*MDT0000.max_create_count")
20101         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
20102
20103         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
20104         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
20105         [ $index -ne 0 ] || error "$tfile stripe index is 0"
20106
20107         unlinkmany $DIR/$tdir/$tfile. 1000
20108
20109         do_nodes $mdts "$LCTL set_param -n \
20110                         osp.*OST0000*.max_create_count=$max_count"
20111         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
20112                 do_nodes $mdts "$LCTL set_param -n \
20113                                 osp.*OST0000*.create_count=$count"
20114         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
20115                         grep "=0" && error "create_count is zero"
20116
20117         local new_iused
20118         for i in $(seq 120); do
20119                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
20120                 # system may be too busy to destroy all objs in time, use
20121                 # a somewhat small value to not fail autotest
20122                 [ $((old_iused - new_iused)) -gt 400 ] && break
20123                 sleep 1
20124         done
20125
20126         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
20127         [ $((old_iused - new_iused)) -gt 400 ] ||
20128                 error "objs not destroyed after unlink"
20129 }
20130 run_test 311 "disable OSP precreate, and unlink should destroy objs"
20131
20132 zfs_oid_to_objid()
20133 {
20134         local ost=$1
20135         local objid=$2
20136
20137         local vdevdir=$(dirname $(facet_vdevice $ost))
20138         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
20139         local zfs_zapid=$(do_facet $ost $cmd |
20140                           grep -w "/O/0/d$((objid%32))" -C 5 |
20141                           awk '/Object/{getline; print $1}')
20142         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
20143                           awk "/$objid = /"'{printf $3}')
20144
20145         echo $zfs_objid
20146 }
20147
20148 zfs_object_blksz() {
20149         local ost=$1
20150         local objid=$2
20151
20152         local vdevdir=$(dirname $(facet_vdevice $ost))
20153         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
20154         local blksz=$(do_facet $ost $cmd $objid |
20155                       awk '/dblk/{getline; printf $4}')
20156
20157         case "${blksz: -1}" in
20158                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
20159                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
20160                 *) ;;
20161         esac
20162
20163         echo $blksz
20164 }
20165
20166 test_312() { # LU-4856
20167         remote_ost_nodsh && skip "remote OST with nodsh"
20168         [ "$ost1_FSTYPE" = "zfs" ] ||
20169                 skip_env "the test only applies to zfs"
20170
20171         local max_blksz=$(do_facet ost1 \
20172                           $ZFS get -p recordsize $(facet_device ost1) |
20173                           awk '!/VALUE/{print $3}')
20174
20175         # to make life a little bit easier
20176         $LFS mkdir -c 1 -i 0 $DIR/$tdir
20177         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20178
20179         local tf=$DIR/$tdir/$tfile
20180         touch $tf
20181         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20182
20183         # Get ZFS object id
20184         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20185         # block size change by sequential overwrite
20186         local bs
20187
20188         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
20189                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
20190
20191                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
20192                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
20193         done
20194         rm -f $tf
20195
20196         # block size change by sequential append write
20197         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
20198         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20199         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20200         local count
20201
20202         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
20203                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
20204                         oflag=sync conv=notrunc
20205
20206                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
20207                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
20208                         error "blksz error, actual $blksz, " \
20209                                 "expected: 2 * $count * $PAGE_SIZE"
20210         done
20211         rm -f $tf
20212
20213         # random write
20214         touch $tf
20215         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20216         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20217
20218         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
20219         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20220         [ $blksz -eq $PAGE_SIZE ] ||
20221                 error "blksz error: $blksz, expected: $PAGE_SIZE"
20222
20223         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
20224         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20225         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
20226
20227         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
20228         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20229         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
20230 }
20231 run_test 312 "make sure ZFS adjusts its block size by write pattern"
20232
20233 test_313() {
20234         remote_ost_nodsh && skip "remote OST with nodsh"
20235
20236         local file=$DIR/$tfile
20237
20238         rm -f $file
20239         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
20240
20241         # define OBD_FAIL_TGT_RCVD_EIO           0x720
20242         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20243         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
20244                 error "write should failed"
20245         do_facet ost1 "$LCTL set_param fail_loc=0"
20246         rm -f $file
20247 }
20248 run_test 313 "io should fail after last_rcvd update fail"
20249
20250 test_314() {
20251         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
20252
20253         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
20254         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20255         rm -f $DIR/$tfile
20256         wait_delete_completed
20257         do_facet ost1 "$LCTL set_param fail_loc=0"
20258 }
20259 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
20260
20261 test_315() { # LU-618
20262         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
20263
20264         local file=$DIR/$tfile
20265         rm -f $file
20266
20267         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
20268                 error "multiop file write failed"
20269         $MULTIOP $file oO_RDONLY:r4063232_c &
20270         PID=$!
20271
20272         sleep 2
20273
20274         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
20275         kill -USR1 $PID
20276
20277         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
20278         rm -f $file
20279 }
20280 run_test 315 "read should be accounted"
20281
20282 test_316() {
20283         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20284         large_xattr_enabled || skip_env "ea_inode feature disabled"
20285
20286         rm -rf $DIR/$tdir/d
20287         mkdir -p $DIR/$tdir/d
20288         chown nobody $DIR/$tdir/d
20289         touch $DIR/$tdir/d/file
20290
20291         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
20292 }
20293 run_test 316 "lfs mv"
20294
20295 test_317() {
20296         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
20297                 skip "Need MDS version at least 2.11.53"
20298         if [ "$ost1_FSTYPE" == "zfs" ]; then
20299                 skip "LU-10370: no implementation for ZFS"
20300         fi
20301
20302         local trunc_sz
20303         local grant_blk_size
20304
20305         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
20306                         awk '/grant_block_size:/ { print $2; exit; }')
20307         #
20308         # Create File of size 5M. Truncate it to below size's and verify
20309         # blocks count.
20310         #
20311         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
20312                 error "Create file $DIR/$tfile failed"
20313         stack_trap "rm -f $DIR/$tfile" EXIT
20314
20315         for trunc_sz in 2097152 4097 4000 509 0; do
20316                 $TRUNCATE $DIR/$tfile $trunc_sz ||
20317                         error "truncate $tfile to $trunc_sz failed"
20318                 local sz=$(stat --format=%s $DIR/$tfile)
20319                 local blk=$(stat --format=%b $DIR/$tfile)
20320                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
20321                                      grant_blk_size) * 8))
20322
20323                 if [[ $blk -ne $trunc_blk ]]; then
20324                         $(which stat) $DIR/$tfile
20325                         error "Expected Block $trunc_blk got $blk for $tfile"
20326                 fi
20327
20328                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20329                         error "Expected Size $trunc_sz got $sz for $tfile"
20330         done
20331
20332         #
20333         # sparse file test
20334         # Create file with a hole and write actual two blocks. Block count
20335         # must be 16.
20336         #
20337         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
20338                 conv=fsync || error "Create file : $DIR/$tfile"
20339
20340         # Calculate the final truncate size.
20341         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
20342
20343         #
20344         # truncate to size $trunc_sz bytes. Strip the last block
20345         # The block count must drop to 8
20346         #
20347         $TRUNCATE $DIR/$tfile $trunc_sz ||
20348                 error "truncate $tfile to $trunc_sz failed"
20349
20350         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
20351         sz=$(stat --format=%s $DIR/$tfile)
20352         blk=$(stat --format=%b $DIR/$tfile)
20353
20354         if [[ $blk -ne $trunc_bsz ]]; then
20355                 $(which stat) $DIR/$tfile
20356                 error "Expected Block $trunc_bsz got $blk for $tfile"
20357         fi
20358
20359         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20360                 error "Expected Size $trunc_sz got $sz for $tfile"
20361 }
20362 run_test 317 "Verify blocks get correctly update after truncate"
20363
20364 test_318() {
20365         local old_max_active=$($LCTL get_param -n \
20366                             llite.*.max_read_ahead_async_active 2>/dev/null)
20367
20368         $LCTL set_param llite.*.max_read_ahead_async_active=256
20369         local max_active=$($LCTL get_param -n \
20370                            llite.*.max_read_ahead_async_active 2>/dev/null)
20371         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
20372
20373         # currently reset to 0 is unsupported, leave it 512 for now.
20374         $LCTL set_param llite.*.max_read_ahead_async_active=0 &&
20375                 error "set max_read_ahead_async_active should fail"
20376
20377         $LCTL set_param llite.*.max_read_ahead_async_active=512
20378         max_active=$($LCTL get_param -n \
20379                      llite.*.max_read_ahead_async_active 2>/dev/null)
20380         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
20381
20382         # restore @max_active
20383         [ $old_max_active -ne 0 ] && $LCTL set_param \
20384                 llite.*.max_read_ahead_async_active=$old_max_active
20385
20386         local old_threshold=$($LCTL get_param -n \
20387                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20388         local max_per_file_mb=$($LCTL get_param -n \
20389                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
20390
20391         local invalid=$(($max_per_file_mb + 1))
20392         $LCTL set_param \
20393                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
20394                         && error "set $invalid should fail"
20395
20396         local valid=$(($invalid - 1))
20397         $LCTL set_param \
20398                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
20399                         error "set $valid should succeed"
20400         local threshold=$($LCTL get_param -n \
20401                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20402         [ $threshold -eq $valid ] || error \
20403                 "expect threshold $valid got $threshold"
20404         $LCTL set_param \
20405                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
20406 }
20407 run_test 318 "Verify async readahead tunables"
20408
20409 test_319() {
20410         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
20411
20412         local before=$(date +%s)
20413         local evict
20414         local mdir=$DIR/$tdir
20415         local file=$mdir/xxx
20416
20417         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
20418         touch $file
20419
20420 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
20421         $LCTL set_param fail_val=5 fail_loc=0x8000032c
20422         $LFS mv -m1 $file &
20423
20424         sleep 1
20425         dd if=$file of=/dev/null
20426         wait
20427         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
20428           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
20429
20430         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
20431 }
20432 run_test 319 "lost lease lock on migrate error"
20433
20434 test_fake_rw() {
20435         local read_write=$1
20436         if [ "$read_write" = "write" ]; then
20437                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
20438         elif [ "$read_write" = "read" ]; then
20439                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
20440         else
20441                 error "argument error"
20442         fi
20443
20444         # turn off debug for performance testing
20445         local saved_debug=$($LCTL get_param -n debug)
20446         $LCTL set_param debug=0
20447
20448         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20449
20450         # get ost1 size - $FSNAME-OST0000
20451         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
20452         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
20453         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
20454
20455         if [ "$read_write" = "read" ]; then
20456                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
20457         fi
20458
20459         local start_time=$(date +%s.%N)
20460         $dd_cmd bs=1M count=$blocks oflag=sync ||
20461                 error "real dd $read_write error"
20462         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
20463
20464         if [ "$read_write" = "write" ]; then
20465                 rm -f $DIR/$tfile
20466         fi
20467
20468         # define OBD_FAIL_OST_FAKE_RW           0x238
20469         do_facet ost1 $LCTL set_param fail_loc=0x238
20470
20471         local start_time=$(date +%s.%N)
20472         $dd_cmd bs=1M count=$blocks oflag=sync ||
20473                 error "fake dd $read_write error"
20474         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
20475
20476         if [ "$read_write" = "write" ]; then
20477                 # verify file size
20478                 cancel_lru_locks osc
20479                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
20480                         error "$tfile size not $blocks MB"
20481         fi
20482         do_facet ost1 $LCTL set_param fail_loc=0
20483
20484         echo "fake $read_write $duration_fake vs. normal $read_write" \
20485                 "$duration in seconds"
20486         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
20487                 error_not_in_vm "fake write is slower"
20488
20489         $LCTL set_param -n debug="$saved_debug"
20490         rm -f $DIR/$tfile
20491 }
20492 test_399a() { # LU-7655 for OST fake write
20493         remote_ost_nodsh && skip "remote OST with nodsh"
20494
20495         test_fake_rw write
20496 }
20497 run_test 399a "fake write should not be slower than normal write"
20498
20499 test_399b() { # LU-8726 for OST fake read
20500         remote_ost_nodsh && skip "remote OST with nodsh"
20501         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
20502                 skip_env "ldiskfs only test"
20503         fi
20504
20505         test_fake_rw read
20506 }
20507 run_test 399b "fake read should not be slower than normal read"
20508
20509 test_400a() { # LU-1606, was conf-sanity test_74
20510         if ! which $CC > /dev/null 2>&1; then
20511                 skip_env "$CC is not installed"
20512         fi
20513
20514         local extra_flags=''
20515         local out=$TMP/$tfile
20516         local prefix=/usr/include/lustre
20517         local prog
20518
20519         if ! [[ -d $prefix ]]; then
20520                 # Assume we're running in tree and fixup the include path.
20521                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
20522                 extra_flags+=" -L$LUSTRE/utils/.lib"
20523         fi
20524
20525         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
20526                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
20527                         error "client api broken"
20528         done
20529         rm -f $out
20530 }
20531 run_test 400a "Lustre client api program can compile and link"
20532
20533 test_400b() { # LU-1606, LU-5011
20534         local header
20535         local out=$TMP/$tfile
20536         local prefix=/usr/include/linux/lustre
20537
20538         # We use a hard coded prefix so that this test will not fail
20539         # when run in tree. There are headers in lustre/include/lustre/
20540         # that are not packaged (like lustre_idl.h) and have more
20541         # complicated include dependencies (like config.h and lnet/types.h).
20542         # Since this test about correct packaging we just skip them when
20543         # they don't exist (see below) rather than try to fixup cppflags.
20544
20545         if ! which $CC > /dev/null 2>&1; then
20546                 skip_env "$CC is not installed"
20547         fi
20548
20549         for header in $prefix/*.h; do
20550                 if ! [[ -f "$header" ]]; then
20551                         continue
20552                 fi
20553
20554                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
20555                         continue # lustre_ioctl.h is internal header
20556                 fi
20557
20558                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
20559                         error "cannot compile '$header'"
20560         done
20561         rm -f $out
20562 }
20563 run_test 400b "packaged headers can be compiled"
20564
20565 test_401a() { #LU-7437
20566         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
20567         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
20568
20569         #count the number of parameters by "list_param -R"
20570         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
20571         #count the number of parameters by listing proc files
20572         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
20573         echo "proc_dirs='$proc_dirs'"
20574         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
20575         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
20576                       sort -u | wc -l)
20577
20578         [ $params -eq $procs ] ||
20579                 error "found $params parameters vs. $procs proc files"
20580
20581         # test the list_param -D option only returns directories
20582         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
20583         #count the number of parameters by listing proc directories
20584         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
20585                 sort -u | wc -l)
20586
20587         [ $params -eq $procs ] ||
20588                 error "found $params parameters vs. $procs proc files"
20589 }
20590 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
20591
20592 test_401b() {
20593         local save=$($LCTL get_param -n jobid_var)
20594         local tmp=testing
20595
20596         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
20597                 error "no error returned when setting bad parameters"
20598
20599         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
20600         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
20601
20602         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
20603         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
20604         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
20605 }
20606 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
20607
20608 test_401c() {
20609         local jobid_var_old=$($LCTL get_param -n jobid_var)
20610         local jobid_var_new
20611
20612         $LCTL set_param jobid_var= &&
20613                 error "no error returned for 'set_param a='"
20614
20615         jobid_var_new=$($LCTL get_param -n jobid_var)
20616         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
20617                 error "jobid_var was changed by setting without value"
20618
20619         $LCTL set_param jobid_var &&
20620                 error "no error returned for 'set_param a'"
20621
20622         jobid_var_new=$($LCTL get_param -n jobid_var)
20623         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
20624                 error "jobid_var was changed by setting without value"
20625 }
20626 run_test 401c "Verify 'lctl set_param' without value fails in either format."
20627
20628 test_401d() {
20629         local jobid_var_old=$($LCTL get_param -n jobid_var)
20630         local jobid_var_new
20631         local new_value="foo=bar"
20632
20633         $LCTL set_param jobid_var=$new_value ||
20634                 error "'set_param a=b' did not accept a value containing '='"
20635
20636         jobid_var_new=$($LCTL get_param -n jobid_var)
20637         [[ "$jobid_var_new" == "$new_value" ]] ||
20638                 error "'set_param a=b' failed on a value containing '='"
20639
20640         # Reset the jobid_var to test the other format
20641         $LCTL set_param jobid_var=$jobid_var_old
20642         jobid_var_new=$($LCTL get_param -n jobid_var)
20643         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
20644                 error "failed to reset jobid_var"
20645
20646         $LCTL set_param jobid_var $new_value ||
20647                 error "'set_param a b' did not accept a value containing '='"
20648
20649         jobid_var_new=$($LCTL get_param -n jobid_var)
20650         [[ "$jobid_var_new" == "$new_value" ]] ||
20651                 error "'set_param a b' failed on a value containing '='"
20652
20653         $LCTL set_param jobid_var $jobid_var_old
20654         jobid_var_new=$($LCTL get_param -n jobid_var)
20655         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
20656                 error "failed to reset jobid_var"
20657 }
20658 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
20659
20660 test_402() {
20661         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
20662         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
20663                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
20664         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
20665                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
20666                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
20667         remote_mds_nodsh && skip "remote MDS with nodsh"
20668
20669         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
20670 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
20671         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
20672         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
20673                 echo "Touch failed - OK"
20674 }
20675 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
20676
20677 test_403() {
20678         local file1=$DIR/$tfile.1
20679         local file2=$DIR/$tfile.2
20680         local tfile=$TMP/$tfile
20681
20682         rm -f $file1 $file2 $tfile
20683
20684         touch $file1
20685         ln $file1 $file2
20686
20687         # 30 sec OBD_TIMEOUT in ll_getattr()
20688         # right before populating st_nlink
20689         $LCTL set_param fail_loc=0x80001409
20690         stat -c %h $file1 > $tfile &
20691
20692         # create an alias, drop all locks and reclaim the dentry
20693         < $file2
20694         cancel_lru_locks mdc
20695         cancel_lru_locks osc
20696         sysctl -w vm.drop_caches=2
20697
20698         wait
20699
20700         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
20701
20702         rm -f $tfile $file1 $file2
20703 }
20704 run_test 403 "i_nlink should not drop to zero due to aliasing"
20705
20706 test_404() { # LU-6601
20707         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
20708                 skip "Need server version newer than 2.8.52"
20709         remote_mds_nodsh && skip "remote MDS with nodsh"
20710
20711         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
20712                 awk '/osp .*-osc-MDT/ { print $4}')
20713
20714         local osp
20715         for osp in $mosps; do
20716                 echo "Deactivate: " $osp
20717                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
20718                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
20719                         awk -vp=$osp '$4 == p { print $2 }')
20720                 [ $stat = IN ] || {
20721                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
20722                         error "deactivate error"
20723                 }
20724                 echo "Activate: " $osp
20725                 do_facet $SINGLEMDS $LCTL --device %$osp activate
20726                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
20727                         awk -vp=$osp '$4 == p { print $2 }')
20728                 [ $stat = UP ] || {
20729                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
20730                         error "activate error"
20731                 }
20732         done
20733 }
20734 run_test 404 "validate manual {de}activated works properly for OSPs"
20735
20736 test_405() {
20737         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20738         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
20739                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
20740                         skip "Layout swap lock is not supported"
20741
20742         check_swap_layouts_support
20743
20744         test_mkdir $DIR/$tdir
20745         swap_lock_test -d $DIR/$tdir ||
20746                 error "One layout swap locked test failed"
20747 }
20748 run_test 405 "Various layout swap lock tests"
20749
20750 test_406() {
20751         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20752         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20753         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20755         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
20756                 skip "Need MDS version at least 2.8.50"
20757
20758         local def_stripe_size=$($LFS getstripe -S $MOUNT)
20759         local test_pool=$TESTNAME
20760
20761         pool_add $test_pool || error "pool_add failed"
20762         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
20763                 error "pool_add_targets failed"
20764
20765         save_layout_restore_at_exit $MOUNT
20766
20767         # parent set default stripe count only, child will stripe from both
20768         # parent and fs default
20769         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
20770                 error "setstripe $MOUNT failed"
20771         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
20772         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
20773         for i in $(seq 10); do
20774                 local f=$DIR/$tdir/$tfile.$i
20775                 touch $f || error "touch failed"
20776                 local count=$($LFS getstripe -c $f)
20777                 [ $count -eq $OSTCOUNT ] ||
20778                         error "$f stripe count $count != $OSTCOUNT"
20779                 local offset=$($LFS getstripe -i $f)
20780                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
20781                 local size=$($LFS getstripe -S $f)
20782                 [ $size -eq $((def_stripe_size * 2)) ] ||
20783                         error "$f stripe size $size != $((def_stripe_size * 2))"
20784                 local pool=$($LFS getstripe -p $f)
20785                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
20786         done
20787
20788         # change fs default striping, delete parent default striping, now child
20789         # will stripe from new fs default striping only
20790         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
20791                 error "change $MOUNT default stripe failed"
20792         $LFS setstripe -c 0 $DIR/$tdir ||
20793                 error "delete $tdir default stripe failed"
20794         for i in $(seq 11 20); do
20795                 local f=$DIR/$tdir/$tfile.$i
20796                 touch $f || error "touch $f failed"
20797                 local count=$($LFS getstripe -c $f)
20798                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
20799                 local offset=$($LFS getstripe -i $f)
20800                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
20801                 local size=$($LFS getstripe -S $f)
20802                 [ $size -eq $def_stripe_size ] ||
20803                         error "$f stripe size $size != $def_stripe_size"
20804                 local pool=$($LFS getstripe -p $f)
20805                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
20806         done
20807
20808         unlinkmany $DIR/$tdir/$tfile. 1 20
20809
20810         local f=$DIR/$tdir/$tfile
20811         pool_remove_all_targets $test_pool $f
20812         pool_remove $test_pool $f
20813 }
20814 run_test 406 "DNE support fs default striping"
20815
20816 test_407() {
20817         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20818         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20819                 skip "Need MDS version at least 2.8.55"
20820         remote_mds_nodsh && skip "remote MDS with nodsh"
20821
20822         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
20823                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
20824         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
20825                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
20826         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
20827
20828         #define OBD_FAIL_DT_TXN_STOP    0x2019
20829         for idx in $(seq $MDSCOUNT); do
20830                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
20831         done
20832         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
20833         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
20834                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
20835         true
20836 }
20837 run_test 407 "transaction fail should cause operation fail"
20838
20839 test_408() {
20840         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20841
20842         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
20843         lctl set_param fail_loc=0x8000040a
20844         # let ll_prepare_partial_page() fail
20845         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
20846
20847         rm -f $DIR/$tfile
20848
20849         # create at least 100 unused inodes so that
20850         # shrink_icache_memory(0) should not return 0
20851         touch $DIR/$tfile-{0..100}
20852         rm -f $DIR/$tfile-{0..100}
20853         sync
20854
20855         echo 2 > /proc/sys/vm/drop_caches
20856 }
20857 run_test 408 "drop_caches should not hang due to page leaks"
20858
20859 test_409()
20860 {
20861         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20862
20863         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
20864         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
20865         touch $DIR/$tdir/guard || error "(2) Fail to create"
20866
20867         local PREFIX=$(str_repeat 'A' 128)
20868         echo "Create 1K hard links start at $(date)"
20869         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20870                 error "(3) Fail to hard link"
20871
20872         echo "Links count should be right although linkEA overflow"
20873         stat $DIR/$tdir/guard || error "(4) Fail to stat"
20874         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
20875         [ $linkcount -eq 1001 ] ||
20876                 error "(5) Unexpected hard links count: $linkcount"
20877
20878         echo "List all links start at $(date)"
20879         ls -l $DIR/$tdir/foo > /dev/null ||
20880                 error "(6) Fail to list $DIR/$tdir/foo"
20881
20882         echo "Unlink hard links start at $(date)"
20883         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20884                 error "(7) Fail to unlink"
20885         echo "Unlink hard links finished at $(date)"
20886 }
20887 run_test 409 "Large amount of cross-MDTs hard links on the same file"
20888
20889 test_410()
20890 {
20891         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
20892                 skip "Need client version at least 2.9.59"
20893
20894         # Create a file, and stat it from the kernel
20895         local testfile=$DIR/$tfile
20896         touch $testfile
20897
20898         local run_id=$RANDOM
20899         local my_ino=$(stat --format "%i" $testfile)
20900
20901         # Try to insert the module. This will always fail as the
20902         # module is designed to not be inserted.
20903         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
20904             &> /dev/null
20905
20906         # Anything but success is a test failure
20907         dmesg | grep -q \
20908             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
20909             error "no inode match"
20910 }
20911 run_test 410 "Test inode number returned from kernel thread"
20912
20913 cleanup_test411_cgroup() {
20914         trap 0
20915         rmdir "$1"
20916 }
20917
20918 test_411() {
20919         local cg_basedir=/sys/fs/cgroup/memory
20920         # LU-9966
20921         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
20922                 skip "no setup for cgroup"
20923
20924         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
20925                 error "test file creation failed"
20926         cancel_lru_locks osc
20927
20928         # Create a very small memory cgroup to force a slab allocation error
20929         local cgdir=$cg_basedir/osc_slab_alloc
20930         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
20931         trap "cleanup_test411_cgroup $cgdir" EXIT
20932         echo 2M > $cgdir/memory.kmem.limit_in_bytes
20933         echo 1M > $cgdir/memory.limit_in_bytes
20934
20935         # Should not LBUG, just be killed by oom-killer
20936         # dd will return 0 even allocation failure in some environment.
20937         # So don't check return value
20938         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
20939         cleanup_test411_cgroup $cgdir
20940
20941         return 0
20942 }
20943 run_test 411 "Slab allocation error with cgroup does not LBUG"
20944
20945 test_412() {
20946         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20947         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20948                 skip "Need server version at least 2.10.55"
20949         fi
20950
20951         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
20952                 error "mkdir failed"
20953         $LFS getdirstripe $DIR/$tdir
20954         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20955         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
20956                 error "expect $((MDSCOUT - 1)) get $stripe_index"
20957         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
20958         [ $stripe_count -eq 2 ] ||
20959                 error "expect 2 get $stripe_count"
20960 }
20961 run_test 412 "mkdir on specific MDTs"
20962
20963 test_qos_mkdir() {
20964         local mkdir_cmd=$1
20965         local stripe_count=$2
20966         local mdts=$(comma_list $(mdts_nodes))
20967
20968         local testdir
20969         local lmv_qos_prio_free
20970         local lmv_qos_threshold_rr
20971         local lmv_qos_maxage
20972         local lod_qos_prio_free
20973         local lod_qos_threshold_rr
20974         local lod_qos_maxage
20975         local count
20976         local i
20977
20978         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
20979         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
20980         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
20981                 head -n1)
20982         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
20983         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
20984         stack_trap "$LCTL set_param \
20985                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
20986         stack_trap "$LCTL set_param \
20987                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
20988         stack_trap "$LCTL set_param \
20989                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
20990
20991         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
20992                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
20993         lod_qos_prio_free=${lod_qos_prio_free%%%}
20994         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
20995                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
20996         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
20997         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
20998                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
20999         stack_trap "do_nodes $mdts $LCTL set_param \
21000                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
21001         stack_trap "do_nodes $mdts $LCTL set_param \
21002                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
21003                 EXIT
21004         stack_trap "do_nodes $mdts $LCTL set_param \
21005                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
21006
21007         echo
21008         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
21009
21010         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
21011         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
21012
21013         testdir=$DIR/$tdir-s$stripe_count/rr
21014
21015         for i in $(seq $((100 * MDSCOUNT))); do
21016                 eval $mkdir_cmd $testdir/subdir$i ||
21017                         error "$mkdir_cmd subdir$i failed"
21018         done
21019
21020         for i in $(seq $MDSCOUNT); do
21021                 count=$($LFS getdirstripe -i $testdir/* |
21022                                 grep ^$((i - 1))$ | wc -l)
21023                 echo "$count directories created on MDT$((i - 1))"
21024                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
21025
21026                 if [ $stripe_count -gt 1 ]; then
21027                         count=$($LFS getdirstripe $testdir/* |
21028                                 grep -P "^\s+$((i - 1))\t" | wc -l)
21029                         echo "$count stripes created on MDT$((i - 1))"
21030                         # deviation should < 5% of average
21031                         [ $count -lt $((95 * stripe_count)) ] ||
21032                         [ $count -gt $((105 * stripe_count)) ] &&
21033                                 error "stripes are not evenly distributed"
21034                 fi
21035         done
21036
21037         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
21038         do_nodes $mdts $LCTL set_param \
21039                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
21040
21041         echo
21042         echo "Check for uneven MDTs: "
21043
21044         local ffree
21045         local bavail
21046         local max
21047         local min
21048         local max_index
21049         local min_index
21050         local tmp
21051
21052         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
21053         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
21054         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
21055
21056         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
21057         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
21058         max_index=0
21059         min_index=0
21060         for ((i = 1; i < ${#ffree[@]}; i++)); do
21061                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
21062                 if [ $tmp -gt $max ]; then
21063                         max=$tmp
21064                         max_index=$i
21065                 fi
21066                 if [ $tmp -lt $min ]; then
21067                         min=$tmp
21068                         min_index=$i
21069                 fi
21070         done
21071
21072         [ ${ffree[min_index]} -eq 0 ] &&
21073                 skip "no free files in MDT$min_index"
21074         [ ${ffree[min_index]} -gt 100000000 ] &&
21075                 skip "too much free files in MDT$min_index"
21076
21077         # Check if we need to generate uneven MDTs
21078         local threshold=50
21079         local diff=$(((max - min) * 100 / min))
21080         local value="$(generate_string 1024)"
21081
21082         while [ $diff -lt $threshold ]; do
21083                 # generate uneven MDTs, create till $threshold% diff
21084                 echo -n "weight diff=$diff% must be > $threshold% ..."
21085                 count=$((${ffree[min_index]} / 10))
21086                 # 50 sec per 10000 files in vm
21087                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
21088                         skip "$count files to create"
21089                 echo "Fill MDT$min_index with $count files"
21090                 [ -d $DIR/$tdir-MDT$min_index ] ||
21091                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
21092                         error "mkdir $tdir-MDT$min_index failed"
21093                 for i in $(seq $count); do
21094                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
21095                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
21096                                 error "create f$j_$i failed"
21097                         setfattr -n user.413b -v $value \
21098                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
21099                                 error "setfattr f$j_$i failed"
21100                 done
21101
21102                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
21103                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
21104                 max=$(((${ffree[max_index]} >> 8) * \
21105                         (${bavail[max_index]} * bsize >> 16)))
21106                 min=$(((${ffree[min_index]} >> 8) * \
21107                         (${bavail[min_index]} * bsize >> 16)))
21108                 diff=$(((max - min) * 100 / min))
21109         done
21110
21111         echo "MDT filesfree available: ${ffree[@]}"
21112         echo "MDT blocks available: ${bavail[@]}"
21113         echo "weight diff=$diff%"
21114
21115         echo
21116         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
21117
21118         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
21119         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
21120         # decrease statfs age, so that it can be updated in time
21121         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
21122         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
21123
21124         sleep 1
21125
21126         testdir=$DIR/$tdir-s$stripe_count/qos
21127
21128         for i in $(seq $((100 * MDSCOUNT))); do
21129                 eval $mkdir_cmd $testdir/subdir$i ||
21130                         error "$mkdir_cmd subdir$i failed"
21131         done
21132
21133         for i in $(seq $MDSCOUNT); do
21134                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
21135                         wc -l)
21136                 echo "$count directories created on MDT$((i - 1))"
21137
21138                 if [ $stripe_count -gt 1 ]; then
21139                         count=$($LFS getdirstripe $testdir/* |
21140                                 grep -P "^\s+$((i - 1))\t" | wc -l)
21141                         echo "$count stripes created on MDT$((i - 1))"
21142                 fi
21143         done
21144
21145         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
21146         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
21147
21148         # D-value should > 10% of averge
21149         [ $((max - min)) -lt 10 ] &&
21150                 error "subdirs shouldn't be evenly distributed"
21151
21152         # ditto
21153         if [ $stripe_count -gt 1 ]; then
21154                 max=$($LFS getdirstripe $testdir/* |
21155                         grep -P "^\s+$max_index\t" | wc -l)
21156                 min=$($LFS getdirstripe $testdir/* |
21157                         grep -P "^\s+$min_index\t" | wc -l)
21158                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
21159                         error "stripes shouldn't be evenly distributed"|| true
21160         fi
21161 }
21162
21163 test_413a() {
21164         [ $MDSCOUNT -lt 2 ] &&
21165                 skip "We need at least 2 MDTs for this test"
21166
21167         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
21168                 skip "Need server version at least 2.12.52"
21169
21170         local stripe_count
21171
21172         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
21173                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
21174                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
21175                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
21176                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
21177         done
21178 }
21179 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
21180
21181 test_413b() {
21182         [ $MDSCOUNT -lt 2 ] &&
21183                 skip "We need at least 2 MDTs for this test"
21184
21185         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
21186                 skip "Need server version at least 2.12.52"
21187
21188         local stripe_count
21189
21190         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
21191                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
21192                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
21193                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
21194                 $LFS setdirstripe -D -c $stripe_count \
21195                         $DIR/$tdir-s$stripe_count/rr ||
21196                         error "setdirstripe failed"
21197                 $LFS setdirstripe -D -c $stripe_count \
21198                         $DIR/$tdir-s$stripe_count/qos ||
21199                         error "setdirstripe failed"
21200                 test_qos_mkdir "mkdir" $stripe_count
21201         done
21202 }
21203 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
21204
21205 test_414() {
21206 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
21207         $LCTL set_param fail_loc=0x80000521
21208         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
21209         rm -f $DIR/$tfile
21210 }
21211 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
21212
21213 test_415() {
21214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21215         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
21216                 skip "Need server version at least 2.11.52"
21217
21218         # LU-11102
21219         local total
21220         local setattr_pid
21221         local start_time
21222         local end_time
21223         local duration
21224
21225         total=500
21226         # this test may be slow on ZFS
21227         [ "$mds1_FSTYPE" == "zfs" ] && total=100
21228
21229         # though this test is designed for striped directory, let's test normal
21230         # directory too since lock is always saved as CoS lock.
21231         test_mkdir $DIR/$tdir || error "mkdir $tdir"
21232         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
21233
21234         (
21235                 while true; do
21236                         touch $DIR/$tdir
21237                 done
21238         ) &
21239         setattr_pid=$!
21240
21241         start_time=$(date +%s)
21242         for i in $(seq $total); do
21243                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
21244                         > /dev/null
21245         done
21246         end_time=$(date +%s)
21247         duration=$((end_time - start_time))
21248
21249         kill -9 $setattr_pid
21250
21251         echo "rename $total files took $duration sec"
21252         [ $duration -lt 100 ] || error "rename took $duration sec"
21253 }
21254 run_test 415 "lock revoke is not missing"
21255
21256 test_416() {
21257         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
21258                 skip "Need server version at least 2.11.55"
21259
21260         # define OBD_FAIL_OSD_TXN_START    0x19a
21261         do_facet mds1 lctl set_param fail_loc=0x19a
21262
21263         lfs mkdir -c $MDSCOUNT $DIR/$tdir
21264
21265         true
21266 }
21267 run_test 416 "transaction start failure won't cause system hung"
21268
21269 cleanup_417() {
21270         trap 0
21271         do_nodes $(comma_list $(mdts_nodes)) \
21272                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
21273         do_nodes $(comma_list $(mdts_nodes)) \
21274                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
21275         do_nodes $(comma_list $(mdts_nodes)) \
21276                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
21277 }
21278
21279 test_417() {
21280         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21281         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
21282                 skip "Need MDS version at least 2.11.56"
21283
21284         trap cleanup_417 RETURN EXIT
21285
21286         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
21287         do_nodes $(comma_list $(mdts_nodes)) \
21288                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
21289         $LFS migrate -m 0 $DIR/$tdir.1 &&
21290                 error "migrate dir $tdir.1 should fail"
21291
21292         do_nodes $(comma_list $(mdts_nodes)) \
21293                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
21294         $LFS mkdir -i 1 $DIR/$tdir.2 &&
21295                 error "create remote dir $tdir.2 should fail"
21296
21297         do_nodes $(comma_list $(mdts_nodes)) \
21298                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
21299         $LFS mkdir -c 2 $DIR/$tdir.3 &&
21300                 error "create striped dir $tdir.3 should fail"
21301         true
21302 }
21303 run_test 417 "disable remote dir, striped dir and dir migration"
21304
21305 # Checks that the outputs of df [-i] and lfs df [-i] match
21306 #
21307 # usage: check_lfs_df <blocks | inodes> <mountpoint>
21308 check_lfs_df() {
21309         local dir=$2
21310         local inodes
21311         local df_out
21312         local lfs_df_out
21313         local count
21314         local passed=false
21315
21316         # blocks or inodes
21317         [ "$1" == "blocks" ] && inodes= || inodes="-i"
21318
21319         for count in {1..100}; do
21320                 cancel_lru_locks
21321                 sync; sleep 0.2
21322
21323                 # read the lines of interest
21324                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
21325                         error "df $inodes $dir | tail -n +2 failed"
21326                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
21327                         error "lfs df $inodes $dir | grep summary: failed"
21328
21329                 # skip first substrings of each output as they are different
21330                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
21331                 # compare the two outputs
21332                 passed=true
21333                 for i in {1..5}; do
21334                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
21335                 done
21336                 $passed && break
21337         done
21338
21339         if ! $passed; then
21340                 df -P $inodes $dir
21341                 echo
21342                 lfs df $inodes $dir
21343                 error "df and lfs df $1 output mismatch: "      \
21344                       "df ${inodes}: ${df_out[*]}, "            \
21345                       "lfs df ${inodes}: ${lfs_df_out[*]}"
21346         fi
21347 }
21348
21349 test_418() {
21350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21351
21352         local dir=$DIR/$tdir
21353         local numfiles=$((RANDOM % 4096 + 2))
21354         local numblocks=$((RANDOM % 256 + 1))
21355
21356         wait_delete_completed
21357         test_mkdir $dir
21358
21359         # check block output
21360         check_lfs_df blocks $dir
21361         # check inode output
21362         check_lfs_df inodes $dir
21363
21364         # create a single file and retest
21365         echo "Creating a single file and testing"
21366         createmany -o $dir/$tfile- 1 &>/dev/null ||
21367                 error "creating 1 file in $dir failed"
21368         check_lfs_df blocks $dir
21369         check_lfs_df inodes $dir
21370
21371         # create a random number of files
21372         echo "Creating $((numfiles - 1)) files and testing"
21373         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
21374                 error "creating $((numfiles - 1)) files in $dir failed"
21375
21376         # write a random number of blocks to the first test file
21377         echo "Writing $numblocks 4K blocks and testing"
21378         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
21379                 count=$numblocks &>/dev/null ||
21380                 error "dd to $dir/${tfile}-0 failed"
21381
21382         # retest
21383         check_lfs_df blocks $dir
21384         check_lfs_df inodes $dir
21385
21386         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
21387                 error "unlinking $numfiles files in $dir failed"
21388 }
21389 run_test 418 "df and lfs df outputs match"
21390
21391 test_419()
21392 {
21393         local dir=$DIR/$tdir
21394
21395         mkdir -p $dir
21396         touch $dir/file
21397
21398         cancel_lru_locks mdc
21399
21400         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
21401         $LCTL set_param fail_loc=0x1410
21402         cat $dir/file
21403         $LCTL set_param fail_loc=0
21404         rm -rf $dir
21405 }
21406 run_test 419 "Verify open file by name doesn't crash kernel"
21407
21408 test_420()
21409 {
21410         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
21411                 skip "Need MDS version at least 2.12.53"
21412
21413         local SAVE_UMASK=$(umask)
21414         local dir=$DIR/$tdir
21415         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
21416
21417         mkdir -p $dir
21418         umask 0000
21419         mkdir -m03777 $dir/testdir
21420         ls -dn $dir/testdir
21421         # Need to remove trailing '.' when SELinux is enabled
21422         local dirperms=$(ls -dn $dir/testdir |
21423                          awk '{ sub(/\.$/, "", $1); print $1}')
21424         [ $dirperms == "drwxrwsrwt" ] ||
21425                 error "incorrect perms on $dir/testdir"
21426
21427         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
21428                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
21429         ls -n $dir/testdir/testfile
21430         local fileperms=$(ls -n $dir/testdir/testfile |
21431                           awk '{ sub(/\.$/, "", $1); print $1}')
21432         [ $fileperms == "-rwxr-xr-x" ] ||
21433                 error "incorrect perms on $dir/testdir/testfile"
21434
21435         umask $SAVE_UMASK
21436 }
21437 run_test 420 "clear SGID bit on non-directories for non-members"
21438
21439 test_421a() {
21440         local cnt
21441         local fid1
21442         local fid2
21443
21444         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21445                 skip "Need MDS version at least 2.12.54"
21446
21447         test_mkdir $DIR/$tdir
21448         createmany -o $DIR/$tdir/f 3
21449         cnt=$(ls -1 $DIR/$tdir | wc -l)
21450         [ $cnt != 3 ] && error "unexpected #files: $cnt"
21451
21452         fid1=$(lfs path2fid $DIR/$tdir/f1)
21453         fid2=$(lfs path2fid $DIR/$tdir/f2)
21454         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
21455
21456         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
21457         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
21458
21459         cnt=$(ls -1 $DIR/$tdir | wc -l)
21460         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
21461
21462         rm -f $DIR/$tdir/f3 || error "can't remove f3"
21463         createmany -o $DIR/$tdir/f 3
21464         cnt=$(ls -1 $DIR/$tdir | wc -l)
21465         [ $cnt != 3 ] && error "unexpected #files: $cnt"
21466
21467         fid1=$(lfs path2fid $DIR/$tdir/f1)
21468         fid2=$(lfs path2fid $DIR/$tdir/f2)
21469         echo "remove using fsname $FSNAME"
21470         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
21471
21472         cnt=$(ls -1 $DIR/$tdir | wc -l)
21473         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
21474 }
21475 run_test 421a "simple rm by fid"
21476
21477 test_421b() {
21478         local cnt
21479         local FID1
21480         local FID2
21481
21482         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21483                 skip "Need MDS version at least 2.12.54"
21484
21485         test_mkdir $DIR/$tdir
21486         createmany -o $DIR/$tdir/f 3
21487         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
21488         MULTIPID=$!
21489
21490         FID1=$(lfs path2fid $DIR/$tdir/f1)
21491         FID2=$(lfs path2fid $DIR/$tdir/f2)
21492         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
21493
21494         kill -USR1 $MULTIPID
21495         wait
21496
21497         cnt=$(ls $DIR/$tdir | wc -l)
21498         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
21499 }
21500 run_test 421b "rm by fid on open file"
21501
21502 test_421c() {
21503         local cnt
21504         local FIDS
21505
21506         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21507                 skip "Need MDS version at least 2.12.54"
21508
21509         test_mkdir $DIR/$tdir
21510         createmany -o $DIR/$tdir/f 3
21511         touch $DIR/$tdir/$tfile
21512         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
21513         cnt=$(ls -1 $DIR/$tdir | wc -l)
21514         [ $cnt != 184 ] && error "unexpected #files: $cnt"
21515
21516         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
21517         $LFS rmfid $DIR $FID1 || error "rmfid failed"
21518
21519         cnt=$(ls $DIR/$tdir | wc -l)
21520         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
21521 }
21522 run_test 421c "rm by fid against hardlinked files"
21523
21524 test_421d() {
21525         local cnt
21526         local FIDS
21527
21528         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21529                 skip "Need MDS version at least 2.12.54"
21530
21531         test_mkdir $DIR/$tdir
21532         createmany -o $DIR/$tdir/f 4097
21533         cnt=$(ls -1 $DIR/$tdir | wc -l)
21534         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
21535
21536         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
21537         $LFS rmfid $DIR $FIDS || error "rmfid failed"
21538
21539         cnt=$(ls $DIR/$tdir | wc -l)
21540         rm -rf $DIR/$tdir
21541         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21542 }
21543 run_test 421d "rmfid en masse"
21544
21545 test_421e() {
21546         local cnt
21547         local FID
21548
21549         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21550         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21551                 skip "Need MDS version at least 2.12.54"
21552
21553         mkdir -p $DIR/$tdir
21554         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21555         createmany -o $DIR/$tdir/striped_dir/f 512
21556         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21557         [ $cnt != 512 ] && error "unexpected #files: $cnt"
21558
21559         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
21560                 sed "s/[/][^:]*://g")
21561         $LFS rmfid $DIR $FIDS || error "rmfid failed"
21562
21563         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
21564         rm -rf $DIR/$tdir
21565         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21566 }
21567 run_test 421e "rmfid in DNE"
21568
21569 test_421f() {
21570         local cnt
21571         local FID
21572
21573         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21574                 skip "Need MDS version at least 2.12.54"
21575
21576         test_mkdir $DIR/$tdir
21577         touch $DIR/$tdir/f
21578         cnt=$(ls -1 $DIR/$tdir | wc -l)
21579         [ $cnt != 1 ] && error "unexpected #files: $cnt"
21580
21581         FID=$(lfs path2fid $DIR/$tdir/f)
21582         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
21583         # rmfid should fail
21584         cnt=$(ls -1 $DIR/$tdir | wc -l)
21585         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
21586
21587         chmod a+rw $DIR/$tdir
21588         ls -la $DIR/$tdir
21589         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
21590         # rmfid should fail
21591         cnt=$(ls -1 $DIR/$tdir | wc -l)
21592         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
21593
21594         rm -f $DIR/$tdir/f
21595         $RUNAS touch $DIR/$tdir/f
21596         FID=$(lfs path2fid $DIR/$tdir/f)
21597         echo "rmfid as root"
21598         $LFS rmfid $DIR $FID || error "rmfid as root failed"
21599         cnt=$(ls -1 $DIR/$tdir | wc -l)
21600         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
21601
21602         rm -f $DIR/$tdir/f
21603         $RUNAS touch $DIR/$tdir/f
21604         cnt=$(ls -1 $DIR/$tdir | wc -l)
21605         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
21606         FID=$(lfs path2fid $DIR/$tdir/f)
21607         # rmfid w/o user_fid2path mount option should fail
21608         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
21609         cnt=$(ls -1 $DIR/$tdir | wc -l)
21610         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
21611
21612         umount_client $MOUNT || error "failed to umount client"
21613         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
21614                 error "failed to mount client'"
21615
21616         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
21617         # rmfid should succeed
21618         cnt=$(ls -1 $DIR/$tdir | wc -l)
21619         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
21620
21621         # rmfid shouldn't allow to remove files due to dir's permission
21622         chmod a+rwx $DIR/$tdir
21623         touch $DIR/$tdir/f
21624         ls -la $DIR/$tdir
21625         FID=$(lfs path2fid $DIR/$tdir/f)
21626         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
21627
21628         umount_client $MOUNT || error "failed to umount client"
21629         mount_client $MOUNT "$MOUNT_OPTS" ||
21630                 error "failed to mount client'"
21631
21632 }
21633 run_test 421f "rmfid checks permissions"
21634
21635 test_421g() {
21636         local cnt
21637         local FIDS
21638
21639         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21640         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21641                 skip "Need MDS version at least 2.12.54"
21642
21643         mkdir -p $DIR/$tdir
21644         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21645         createmany -o $DIR/$tdir/striped_dir/f 512
21646         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21647         [ $cnt != 512 ] && error "unexpected #files: $cnt"
21648
21649         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
21650                 sed "s/[/][^:]*://g")
21651
21652         rm -f $DIR/$tdir/striped_dir/f1*
21653         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21654         removed=$((512 - cnt))
21655
21656         # few files have been just removed, so we expect
21657         # rmfid to fail on their fids
21658         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
21659         [ $removed != $errors ] && error "$errors != $removed"
21660
21661         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
21662         rm -rf $DIR/$tdir
21663         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21664 }
21665 run_test 421g "rmfid to return errors properly"
21666
21667 test_422() {
21668         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
21669         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
21670         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
21671         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
21672         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
21673
21674         local amc=$(at_max_get client)
21675         local amo=$(at_max_get mds1)
21676         local timeout=`lctl get_param -n timeout`
21677
21678         at_max_set 0 client
21679         at_max_set 0 mds1
21680
21681 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
21682         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
21683                         fail_val=$(((2*timeout + 10)*1000))
21684         touch $DIR/$tdir/d3/file &
21685         sleep 2
21686 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
21687         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
21688                         fail_val=$((2*timeout + 5))
21689         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
21690         local pid=$!
21691         sleep 1
21692         kill -9 $pid
21693         sleep $((2 * timeout))
21694         echo kill $pid
21695         kill -9 $pid
21696         lctl mark touch
21697         touch $DIR/$tdir/d2/file3
21698         touch $DIR/$tdir/d2/file4
21699         touch $DIR/$tdir/d2/file5
21700
21701         wait
21702         at_max_set $amc client
21703         at_max_set $amo mds1
21704
21705         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
21706         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
21707                 error "Watchdog is always throttled"
21708 }
21709 run_test 422 "kill a process with RPC in progress"
21710
21711 prep_801() {
21712         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
21713         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
21714                 skip "Need server version at least 2.9.55"
21715
21716         start_full_debug_logging
21717 }
21718
21719 post_801() {
21720         stop_full_debug_logging
21721 }
21722
21723 barrier_stat() {
21724         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
21725                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
21726                            awk '/The barrier for/ { print $7 }')
21727                 echo $st
21728         else
21729                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
21730                 echo \'$st\'
21731         fi
21732 }
21733
21734 barrier_expired() {
21735         local expired
21736
21737         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
21738                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
21739                           awk '/will be expired/ { print $7 }')
21740         else
21741                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
21742         fi
21743
21744         echo $expired
21745 }
21746
21747 test_801a() {
21748         prep_801
21749
21750         echo "Start barrier_freeze at: $(date)"
21751         #define OBD_FAIL_BARRIER_DELAY          0x2202
21752         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
21753         # Do not reduce barrier time - See LU-11873
21754         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
21755
21756         sleep 2
21757         local b_status=$(barrier_stat)
21758         echo "Got barrier status at: $(date)"
21759         [ "$b_status" = "'freezing_p1'" ] ||
21760                 error "(1) unexpected barrier status $b_status"
21761
21762         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
21763         wait
21764         b_status=$(barrier_stat)
21765         [ "$b_status" = "'frozen'" ] ||
21766                 error "(2) unexpected barrier status $b_status"
21767
21768         local expired=$(barrier_expired)
21769         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
21770         sleep $((expired + 3))
21771
21772         b_status=$(barrier_stat)
21773         [ "$b_status" = "'expired'" ] ||
21774                 error "(3) unexpected barrier status $b_status"
21775
21776         # Do not reduce barrier time - See LU-11873
21777         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
21778                 error "(4) fail to freeze barrier"
21779
21780         b_status=$(barrier_stat)
21781         [ "$b_status" = "'frozen'" ] ||
21782                 error "(5) unexpected barrier status $b_status"
21783
21784         echo "Start barrier_thaw at: $(date)"
21785         #define OBD_FAIL_BARRIER_DELAY          0x2202
21786         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
21787         do_facet mgs $LCTL barrier_thaw $FSNAME &
21788
21789         sleep 2
21790         b_status=$(barrier_stat)
21791         echo "Got barrier status at: $(date)"
21792         [ "$b_status" = "'thawing'" ] ||
21793                 error "(6) unexpected barrier status $b_status"
21794
21795         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
21796         wait
21797         b_status=$(barrier_stat)
21798         [ "$b_status" = "'thawed'" ] ||
21799                 error "(7) unexpected barrier status $b_status"
21800
21801         #define OBD_FAIL_BARRIER_FAILURE        0x2203
21802         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
21803         do_facet mgs $LCTL barrier_freeze $FSNAME
21804
21805         b_status=$(barrier_stat)
21806         [ "$b_status" = "'failed'" ] ||
21807                 error "(8) unexpected barrier status $b_status"
21808
21809         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21810         do_facet mgs $LCTL barrier_thaw $FSNAME
21811
21812         post_801
21813 }
21814 run_test 801a "write barrier user interfaces and stat machine"
21815
21816 test_801b() {
21817         prep_801
21818
21819         mkdir $DIR/$tdir || error "(1) fail to mkdir"
21820         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
21821         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
21822         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
21823         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
21824
21825         cancel_lru_locks mdc
21826
21827         # 180 seconds should be long enough
21828         do_facet mgs $LCTL barrier_freeze $FSNAME 180
21829
21830         local b_status=$(barrier_stat)
21831         [ "$b_status" = "'frozen'" ] ||
21832                 error "(6) unexpected barrier status $b_status"
21833
21834         mkdir $DIR/$tdir/d0/d10 &
21835         mkdir_pid=$!
21836
21837         touch $DIR/$tdir/d1/f13 &
21838         touch_pid=$!
21839
21840         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
21841         ln_pid=$!
21842
21843         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
21844         mv_pid=$!
21845
21846         rm -f $DIR/$tdir/d4/f12 &
21847         rm_pid=$!
21848
21849         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
21850
21851         # To guarantee taht the 'stat' is not blocked
21852         b_status=$(barrier_stat)
21853         [ "$b_status" = "'frozen'" ] ||
21854                 error "(8) unexpected barrier status $b_status"
21855
21856         # let above commands to run at background
21857         sleep 5
21858
21859         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
21860         ps -p $touch_pid || error "(10) touch should be blocked"
21861         ps -p $ln_pid || error "(11) link should be blocked"
21862         ps -p $mv_pid || error "(12) rename should be blocked"
21863         ps -p $rm_pid || error "(13) unlink should be blocked"
21864
21865         b_status=$(barrier_stat)
21866         [ "$b_status" = "'frozen'" ] ||
21867                 error "(14) unexpected barrier status $b_status"
21868
21869         do_facet mgs $LCTL barrier_thaw $FSNAME
21870         b_status=$(barrier_stat)
21871         [ "$b_status" = "'thawed'" ] ||
21872                 error "(15) unexpected barrier status $b_status"
21873
21874         wait $mkdir_pid || error "(16) mkdir should succeed"
21875         wait $touch_pid || error "(17) touch should succeed"
21876         wait $ln_pid || error "(18) link should succeed"
21877         wait $mv_pid || error "(19) rename should succeed"
21878         wait $rm_pid || error "(20) unlink should succeed"
21879
21880         post_801
21881 }
21882 run_test 801b "modification will be blocked by write barrier"
21883
21884 test_801c() {
21885         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21886
21887         prep_801
21888
21889         stop mds2 || error "(1) Fail to stop mds2"
21890
21891         do_facet mgs $LCTL barrier_freeze $FSNAME 30
21892
21893         local b_status=$(barrier_stat)
21894         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
21895                 do_facet mgs $LCTL barrier_thaw $FSNAME
21896                 error "(2) unexpected barrier status $b_status"
21897         }
21898
21899         do_facet mgs $LCTL barrier_rescan $FSNAME ||
21900                 error "(3) Fail to rescan barrier bitmap"
21901
21902         # Do not reduce barrier time - See LU-11873
21903         do_facet mgs $LCTL barrier_freeze $FSNAME 20
21904
21905         b_status=$(barrier_stat)
21906         [ "$b_status" = "'frozen'" ] ||
21907                 error "(4) unexpected barrier status $b_status"
21908
21909         do_facet mgs $LCTL barrier_thaw $FSNAME
21910         b_status=$(barrier_stat)
21911         [ "$b_status" = "'thawed'" ] ||
21912                 error "(5) unexpected barrier status $b_status"
21913
21914         local devname=$(mdsdevname 2)
21915
21916         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
21917
21918         do_facet mgs $LCTL barrier_rescan $FSNAME ||
21919                 error "(7) Fail to rescan barrier bitmap"
21920
21921         post_801
21922 }
21923 run_test 801c "rescan barrier bitmap"
21924
21925 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
21926 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
21927 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
21928 saved_MOUNT_OPTS=$MOUNT_OPTS
21929
21930 cleanup_802a() {
21931         trap 0
21932
21933         stopall
21934         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
21935         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
21936         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
21937         MOUNT_OPTS=$saved_MOUNT_OPTS
21938         setupall
21939 }
21940
21941 test_802a() {
21942         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
21943         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
21944         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
21945                 skip "Need server version at least 2.9.55"
21946
21947         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
21948
21949         mkdir $DIR/$tdir || error "(1) fail to mkdir"
21950
21951         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
21952                 error "(2) Fail to copy"
21953
21954         trap cleanup_802a EXIT
21955
21956         # sync by force before remount as readonly
21957         sync; sync_all_data; sleep 3; sync_all_data
21958
21959         stopall
21960
21961         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
21962         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
21963         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
21964
21965         echo "Mount the server as read only"
21966         setupall server_only || error "(3) Fail to start servers"
21967
21968         echo "Mount client without ro should fail"
21969         mount_client $MOUNT &&
21970                 error "(4) Mount client without 'ro' should fail"
21971
21972         echo "Mount client with ro should succeed"
21973         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
21974         mount_client $MOUNT ||
21975                 error "(5) Mount client with 'ro' should succeed"
21976
21977         echo "Modify should be refused"
21978         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
21979
21980         echo "Read should be allowed"
21981         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
21982                 error "(7) Read should succeed under ro mode"
21983
21984         cleanup_802a
21985 }
21986 run_test 802a "simulate readonly device"
21987
21988 test_802b() {
21989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21990         remote_mds_nodsh && skip "remote MDS with nodsh"
21991
21992         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
21993                 skip "readonly option not available"
21994
21995         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
21996
21997         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
21998                 error "(2) Fail to copy"
21999
22000         # write back all cached data before setting MDT to readonly
22001         cancel_lru_locks
22002         sync_all_data
22003
22004         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
22005         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
22006
22007         echo "Modify should be refused"
22008         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
22009
22010         echo "Read should be allowed"
22011         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
22012                 error "(7) Read should succeed under ro mode"
22013
22014         # disable readonly
22015         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
22016 }
22017 run_test 802b "be able to set MDTs to readonly"
22018
22019 test_803() {
22020         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
22021         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
22022                 skip "MDS needs to be newer than 2.10.54"
22023
22024         mkdir -p $DIR/$tdir
22025         # Create some objects on all MDTs to trigger related logs objects
22026         for idx in $(seq $MDSCOUNT); do
22027                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
22028                         $DIR/$tdir/dir${idx} ||
22029                         error "Fail to create $DIR/$tdir/dir${idx}"
22030         done
22031
22032         sync; sleep 3
22033         wait_delete_completed # ensure old test cleanups are finished
22034         echo "before create:"
22035         $LFS df -i $MOUNT
22036         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22037
22038         for i in {1..10}; do
22039                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
22040                         error "Fail to create $DIR/$tdir/foo$i"
22041         done
22042
22043         sync; sleep 3
22044         echo "after create:"
22045         $LFS df -i $MOUNT
22046         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22047
22048         # allow for an llog to be cleaned up during the test
22049         [ $after_used -ge $((before_used + 10 - 1)) ] ||
22050                 error "before ($before_used) + 10 > after ($after_used)"
22051
22052         for i in {1..10}; do
22053                 rm -rf $DIR/$tdir/foo$i ||
22054                         error "Fail to remove $DIR/$tdir/foo$i"
22055         done
22056
22057         sleep 3 # avoid MDT return cached statfs
22058         wait_delete_completed
22059         echo "after unlink:"
22060         $LFS df -i $MOUNT
22061         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22062
22063         # allow for an llog to be created during the test
22064         [ $after_used -le $((before_used + 1)) ] ||
22065                 error "after ($after_used) > before ($before_used) + 1"
22066 }
22067 run_test 803 "verify agent object for remote object"
22068
22069 test_804() {
22070         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
22071         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
22072                 skip "MDS needs to be newer than 2.10.54"
22073         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22074
22075         mkdir -p $DIR/$tdir
22076         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
22077                 error "Fail to create $DIR/$tdir/dir0"
22078
22079         local fid=$($LFS path2fid $DIR/$tdir/dir0)
22080         local dev=$(mdsdevname 2)
22081
22082         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22083                 grep ${fid} || error "NOT found agent entry for dir0"
22084
22085         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
22086                 error "Fail to create $DIR/$tdir/dir1"
22087
22088         touch $DIR/$tdir/dir1/foo0 ||
22089                 error "Fail to create $DIR/$tdir/dir1/foo0"
22090         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
22091         local rc=0
22092
22093         for idx in $(seq $MDSCOUNT); do
22094                 dev=$(mdsdevname $idx)
22095                 do_facet mds${idx} \
22096                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22097                         grep ${fid} && rc=$idx
22098         done
22099
22100         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
22101                 error "Fail to rename foo0 to foo1"
22102         if [ $rc -eq 0 ]; then
22103                 for idx in $(seq $MDSCOUNT); do
22104                         dev=$(mdsdevname $idx)
22105                         do_facet mds${idx} \
22106                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22107                         grep ${fid} && rc=$idx
22108                 done
22109         fi
22110
22111         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
22112                 error "Fail to rename foo1 to foo2"
22113         if [ $rc -eq 0 ]; then
22114                 for idx in $(seq $MDSCOUNT); do
22115                         dev=$(mdsdevname $idx)
22116                         do_facet mds${idx} \
22117                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22118                         grep ${fid} && rc=$idx
22119                 done
22120         fi
22121
22122         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
22123
22124         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
22125                 error "Fail to link to $DIR/$tdir/dir1/foo2"
22126         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
22127                 error "Fail to rename foo2 to foo0"
22128         unlink $DIR/$tdir/dir1/foo0 ||
22129                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
22130         rm -rf $DIR/$tdir/dir0 ||
22131                 error "Fail to rm $DIR/$tdir/dir0"
22132
22133         for idx in $(seq $MDSCOUNT); do
22134                 dev=$(mdsdevname $idx)
22135                 rc=0
22136
22137                 stop mds${idx}
22138                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
22139                         rc=$?
22140                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
22141                         error "mount mds$idx failed"
22142                 df $MOUNT > /dev/null 2>&1
22143
22144                 # e2fsck should not return error
22145                 [ $rc -eq 0 ] ||
22146                         error "e2fsck detected error on MDT${idx}: rc=$rc"
22147         done
22148 }
22149 run_test 804 "verify agent entry for remote entry"
22150
22151 cleanup_805() {
22152         do_facet $SINGLEMDS zfs set quota=$old $fsset
22153         unlinkmany $DIR/$tdir/f- 1000000
22154         trap 0
22155 }
22156
22157 test_805() {
22158         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
22159         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
22160         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
22161                 skip "netfree not implemented before 0.7"
22162         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
22163                 skip "Need MDS version at least 2.10.57"
22164
22165         local fsset
22166         local freekb
22167         local usedkb
22168         local old
22169         local quota
22170         local pref="osd-zfs.$FSNAME-MDT0000."
22171
22172         # limit available space on MDS dataset to meet nospace issue
22173         # quickly. then ZFS 0.7.2 can use reserved space if asked
22174         # properly (using netfree flag in osd_declare_destroy()
22175         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
22176         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
22177                 gawk '{print $3}')
22178         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
22179         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
22180         let "usedkb=usedkb-freekb"
22181         let "freekb=freekb/2"
22182         if let "freekb > 5000"; then
22183                 let "freekb=5000"
22184         fi
22185         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
22186         trap cleanup_805 EXIT
22187         mkdir $DIR/$tdir
22188         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
22189         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
22190         rm -rf $DIR/$tdir || error "not able to remove"
22191         do_facet $SINGLEMDS zfs set quota=$old $fsset
22192         trap 0
22193 }
22194 run_test 805 "ZFS can remove from full fs"
22195
22196 # Size-on-MDS test
22197 check_lsom_data()
22198 {
22199         local file=$1
22200         local size=$($LFS getsom -s $file)
22201         local expect=$(stat -c %s $file)
22202
22203         [[ $size == $expect ]] ||
22204                 error "$file expected size: $expect, got: $size"
22205
22206         local blocks=$($LFS getsom -b $file)
22207         expect=$(stat -c %b $file)
22208         [[ $blocks == $expect ]] ||
22209                 error "$file expected blocks: $expect, got: $blocks"
22210 }
22211
22212 check_lsom_size()
22213 {
22214         local size=$($LFS getsom -s $1)
22215         local expect=$2
22216
22217         [[ $size == $expect ]] ||
22218                 error "$file expected size: $expect, got: $size"
22219 }
22220
22221 test_806() {
22222         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22223                 skip "Need MDS version at least 2.11.52"
22224
22225         local bs=1048576
22226
22227         touch $DIR/$tfile || error "touch $tfile failed"
22228
22229         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22230         save_lustre_params client "llite.*.xattr_cache" > $save
22231         lctl set_param llite.*.xattr_cache=0
22232         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22233
22234         # single-threaded write
22235         echo "Test SOM for single-threaded write"
22236         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
22237                 error "write $tfile failed"
22238         check_lsom_size $DIR/$tfile $bs
22239
22240         local num=32
22241         local size=$(($num * $bs))
22242         local offset=0
22243         local i
22244
22245         echo "Test SOM for single client multi-threaded($num) write"
22246         $TRUNCATE $DIR/$tfile 0
22247         for ((i = 0; i < $num; i++)); do
22248                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22249                 local pids[$i]=$!
22250                 offset=$((offset + $bs))
22251         done
22252         for (( i=0; i < $num; i++ )); do
22253                 wait ${pids[$i]}
22254         done
22255         check_lsom_size $DIR/$tfile $size
22256
22257         $TRUNCATE $DIR/$tfile 0
22258         for ((i = 0; i < $num; i++)); do
22259                 offset=$((offset - $bs))
22260                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22261                 local pids[$i]=$!
22262         done
22263         for (( i=0; i < $num; i++ )); do
22264                 wait ${pids[$i]}
22265         done
22266         check_lsom_size $DIR/$tfile $size
22267
22268         # multi-client writes
22269         num=$(get_node_count ${CLIENTS//,/ })
22270         size=$(($num * $bs))
22271         offset=0
22272         i=0
22273
22274         echo "Test SOM for multi-client ($num) writes"
22275         $TRUNCATE $DIR/$tfile 0
22276         for client in ${CLIENTS//,/ }; do
22277                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22278                 local pids[$i]=$!
22279                 i=$((i + 1))
22280                 offset=$((offset + $bs))
22281         done
22282         for (( i=0; i < $num; i++ )); do
22283                 wait ${pids[$i]}
22284         done
22285         check_lsom_size $DIR/$tfile $offset
22286
22287         i=0
22288         $TRUNCATE $DIR/$tfile 0
22289         for client in ${CLIENTS//,/ }; do
22290                 offset=$((offset - $bs))
22291                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22292                 local pids[$i]=$!
22293                 i=$((i + 1))
22294         done
22295         for (( i=0; i < $num; i++ )); do
22296                 wait ${pids[$i]}
22297         done
22298         check_lsom_size $DIR/$tfile $size
22299
22300         # verify truncate
22301         echo "Test SOM for truncate"
22302         $TRUNCATE $DIR/$tfile 1048576
22303         check_lsom_size $DIR/$tfile 1048576
22304         $TRUNCATE $DIR/$tfile 1234
22305         check_lsom_size $DIR/$tfile 1234
22306
22307         # verify SOM blocks count
22308         echo "Verify SOM block count"
22309         $TRUNCATE $DIR/$tfile 0
22310         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
22311                 error "failed to write file $tfile"
22312         check_lsom_data $DIR/$tfile
22313 }
22314 run_test 806 "Verify Lazy Size on MDS"
22315
22316 test_807() {
22317         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22318         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22319                 skip "Need MDS version at least 2.11.52"
22320
22321         # Registration step
22322         changelog_register || error "changelog_register failed"
22323         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
22324         changelog_users $SINGLEMDS | grep -q $cl_user ||
22325                 error "User $cl_user not found in changelog_users"
22326
22327         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22328         save_lustre_params client "llite.*.xattr_cache" > $save
22329         lctl set_param llite.*.xattr_cache=0
22330         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22331
22332         rm -rf $DIR/$tdir || error "rm $tdir failed"
22333         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22334         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
22335         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
22336         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
22337                 error "truncate $tdir/trunc failed"
22338
22339         local bs=1048576
22340         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
22341                 error "write $tfile failed"
22342
22343         # multi-client wirtes
22344         local num=$(get_node_count ${CLIENTS//,/ })
22345         local offset=0
22346         local i=0
22347
22348         echo "Test SOM for multi-client ($num) writes"
22349         touch $DIR/$tfile || error "touch $tfile failed"
22350         $TRUNCATE $DIR/$tfile 0
22351         for client in ${CLIENTS//,/ }; do
22352                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22353                 local pids[$i]=$!
22354                 i=$((i + 1))
22355                 offset=$((offset + $bs))
22356         done
22357         for (( i=0; i < $num; i++ )); do
22358                 wait ${pids[$i]}
22359         done
22360
22361         sleep 5
22362         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
22363         check_lsom_data $DIR/$tdir/trunc
22364         check_lsom_data $DIR/$tdir/single_dd
22365         check_lsom_data $DIR/$tfile
22366
22367         rm -rf $DIR/$tdir
22368         # Deregistration step
22369         changelog_deregister || error "changelog_deregister failed"
22370 }
22371 run_test 807 "verify LSOM syncing tool"
22372
22373 check_som_nologged()
22374 {
22375         local lines=$($LFS changelog $FSNAME-MDT0000 |
22376                 grep 'x=trusted.som' | wc -l)
22377         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
22378 }
22379
22380 test_808() {
22381         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22382                 skip "Need MDS version at least 2.11.55"
22383
22384         # Registration step
22385         changelog_register || error "changelog_register failed"
22386
22387         touch $DIR/$tfile || error "touch $tfile failed"
22388         check_som_nologged
22389
22390         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
22391                 error "write $tfile failed"
22392         check_som_nologged
22393
22394         $TRUNCATE $DIR/$tfile 1234
22395         check_som_nologged
22396
22397         $TRUNCATE $DIR/$tfile 1048576
22398         check_som_nologged
22399
22400         # Deregistration step
22401         changelog_deregister || error "changelog_deregister failed"
22402 }
22403 run_test 808 "Check trusted.som xattr not logged in Changelogs"
22404
22405 check_som_nodata()
22406 {
22407         $LFS getsom $1
22408         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
22409 }
22410
22411 test_809() {
22412         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22413                 skip "Need MDS version at least 2.11.56"
22414
22415         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
22416                 error "failed to create DoM-only file $DIR/$tfile"
22417         touch $DIR/$tfile || error "touch $tfile failed"
22418         check_som_nodata $DIR/$tfile
22419
22420         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
22421                 error "write $tfile failed"
22422         check_som_nodata $DIR/$tfile
22423
22424         $TRUNCATE $DIR/$tfile 1234
22425         check_som_nodata $DIR/$tfile
22426
22427         $TRUNCATE $DIR/$tfile 4097
22428         check_som_nodata $DIR/$file
22429 }
22430 run_test 809 "Verify no SOM xattr store for DoM-only files"
22431
22432 test_810() {
22433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22434         $GSS && skip_env "could not run with gss"
22435         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
22436                 skip "OST < 2.12.58 doesn't align checksum"
22437
22438         set_checksums 1
22439         stack_trap "set_checksums $ORIG_CSUM" EXIT
22440         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
22441
22442         local csum
22443         local before
22444         local after
22445         for csum in $CKSUM_TYPES; do
22446                 #define OBD_FAIL_OSC_NO_GRANT   0x411
22447                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
22448                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
22449                         eval set -- $i
22450                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
22451                         before=$(md5sum $DIR/$tfile)
22452                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
22453                         after=$(md5sum $DIR/$tfile)
22454                         [ "$before" == "$after" ] ||
22455                                 error "$csum: $before != $after bs=$1 seek=$2"
22456                 done
22457         done
22458 }
22459 run_test 810 "partial page writes on ZFS (LU-11663)"
22460
22461 test_811() {
22462         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
22463                 skip "Need MDS version at least 2.11.56"
22464
22465         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
22466         do_facet mds1 $LCTL set_param fail_loc=0x165
22467         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
22468
22469         stop mds1
22470         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22471
22472         sleep 5
22473         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
22474                 error "MDD orphan cleanup thread not quit"
22475 }
22476 run_test 811 "orphan name stub can be cleaned up in startup"
22477
22478 test_812a() {
22479         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
22480                 skip "OST < 2.12.51 doesn't support this fail_loc"
22481         [ "$SHARED_KEY" = true ] &&
22482                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22483
22484         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22485         # ensure ost1 is connected
22486         stat $DIR/$tfile >/dev/null || error "can't stat"
22487         wait_osc_import_state client ost1 FULL
22488         # no locks, no reqs to let the connection idle
22489         cancel_lru_locks osc
22490
22491         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
22492 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
22493         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
22494         wait_osc_import_state client ost1 CONNECTING
22495         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
22496
22497         stat $DIR/$tfile >/dev/null || error "can't stat file"
22498 }
22499 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
22500
22501 test_812b() { # LU-12378
22502         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
22503                 skip "OST < 2.12.51 doesn't support this fail_loc"
22504         [ "$SHARED_KEY" = true ] &&
22505                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22506
22507         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
22508         # ensure ost1 is connected
22509         stat $DIR/$tfile >/dev/null || error "can't stat"
22510         wait_osc_import_state client ost1 FULL
22511         # no locks, no reqs to let the connection idle
22512         cancel_lru_locks osc
22513
22514         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
22515 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
22516         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
22517         wait_osc_import_state client ost1 CONNECTING
22518         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
22519
22520         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
22521         wait_osc_import_state client ost1 IDLE
22522 }
22523 run_test 812b "do not drop no resend request for idle connect"
22524
22525 test_813() {
22526         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
22527         [ -z "$file_heat_sav" ] && skip "no file heat support"
22528
22529         local readsample
22530         local writesample
22531         local readbyte
22532         local writebyte
22533         local readsample1
22534         local writesample1
22535         local readbyte1
22536         local writebyte1
22537
22538         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
22539         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
22540
22541         $LCTL set_param -n llite.*.file_heat=1
22542         echo "Turn on file heat"
22543         echo "Period second: $period_second, Decay percentage: $decay_pct"
22544
22545         echo "QQQQ" > $DIR/$tfile
22546         echo "QQQQ" > $DIR/$tfile
22547         echo "QQQQ" > $DIR/$tfile
22548         cat $DIR/$tfile > /dev/null
22549         cat $DIR/$tfile > /dev/null
22550         cat $DIR/$tfile > /dev/null
22551         cat $DIR/$tfile > /dev/null
22552
22553         local out=$($LFS heat_get $DIR/$tfile)
22554
22555         $LFS heat_get $DIR/$tfile
22556         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22557         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22558         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22559         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22560
22561         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
22562         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
22563         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
22564         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
22565
22566         sleep $((period_second + 3))
22567         echo "Sleep $((period_second + 3)) seconds..."
22568         # The recursion formula to calculate the heat of the file f is as
22569         # follow:
22570         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
22571         # Where Hi is the heat value in the period between time points i*I and
22572         # (i+1)*I; Ci is the access count in the period; the symbol P refers
22573         # to the weight of Ci.
22574         out=$($LFS heat_get $DIR/$tfile)
22575         $LFS heat_get $DIR/$tfile
22576         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22577         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22578         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22579         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22580
22581         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
22582                 error "read sample ($readsample) is wrong"
22583         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
22584                 error "write sample ($writesample) is wrong"
22585         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
22586                 error "read bytes ($readbyte) is wrong"
22587         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
22588                 error "write bytes ($writebyte) is wrong"
22589
22590         echo "QQQQ" > $DIR/$tfile
22591         echo "QQQQ" > $DIR/$tfile
22592         echo "QQQQ" > $DIR/$tfile
22593         cat $DIR/$tfile > /dev/null
22594         cat $DIR/$tfile > /dev/null
22595         cat $DIR/$tfile > /dev/null
22596         cat $DIR/$tfile > /dev/null
22597
22598         sleep $((period_second + 3))
22599         echo "Sleep $((period_second + 3)) seconds..."
22600
22601         out=$($LFS heat_get $DIR/$tfile)
22602         $LFS heat_get $DIR/$tfile
22603         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22604         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22605         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22606         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22607
22608         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
22609                 4 * $decay_pct) / 100") -eq 1 ] ||
22610                 error "read sample ($readsample1) is wrong"
22611         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
22612                 3 * $decay_pct) / 100") -eq 1 ] ||
22613                 error "write sample ($writesample1) is wrong"
22614         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
22615                 20 * $decay_pct) / 100") -eq 1 ] ||
22616                 error "read bytes ($readbyte1) is wrong"
22617         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
22618                 15 * $decay_pct) / 100") -eq 1 ] ||
22619                 error "write bytes ($writebyte1) is wrong"
22620
22621         echo "Turn off file heat for the file $DIR/$tfile"
22622         $LFS heat_set -o $DIR/$tfile
22623
22624         echo "QQQQ" > $DIR/$tfile
22625         echo "QQQQ" > $DIR/$tfile
22626         echo "QQQQ" > $DIR/$tfile
22627         cat $DIR/$tfile > /dev/null
22628         cat $DIR/$tfile > /dev/null
22629         cat $DIR/$tfile > /dev/null
22630         cat $DIR/$tfile > /dev/null
22631
22632         out=$($LFS heat_get $DIR/$tfile)
22633         $LFS heat_get $DIR/$tfile
22634         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22635         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22636         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22637         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22638
22639         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
22640         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
22641         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
22642         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
22643
22644         echo "Trun on file heat for the file $DIR/$tfile"
22645         $LFS heat_set -O $DIR/$tfile
22646
22647         echo "QQQQ" > $DIR/$tfile
22648         echo "QQQQ" > $DIR/$tfile
22649         echo "QQQQ" > $DIR/$tfile
22650         cat $DIR/$tfile > /dev/null
22651         cat $DIR/$tfile > /dev/null
22652         cat $DIR/$tfile > /dev/null
22653         cat $DIR/$tfile > /dev/null
22654
22655         out=$($LFS heat_get $DIR/$tfile)
22656         $LFS heat_get $DIR/$tfile
22657         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22658         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22659         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22660         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22661
22662         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
22663         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
22664         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
22665         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
22666
22667         $LFS heat_set -c $DIR/$tfile
22668         $LCTL set_param -n llite.*.file_heat=0
22669         echo "Turn off file heat support for the Lustre filesystem"
22670
22671         echo "QQQQ" > $DIR/$tfile
22672         echo "QQQQ" > $DIR/$tfile
22673         echo "QQQQ" > $DIR/$tfile
22674         cat $DIR/$tfile > /dev/null
22675         cat $DIR/$tfile > /dev/null
22676         cat $DIR/$tfile > /dev/null
22677         cat $DIR/$tfile > /dev/null
22678
22679         out=$($LFS heat_get $DIR/$tfile)
22680         $LFS heat_get $DIR/$tfile
22681         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22682         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22683         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22684         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22685
22686         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
22687         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
22688         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
22689         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
22690
22691         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
22692         rm -f $DIR/$tfile
22693 }
22694 run_test 813 "File heat verfication"
22695
22696 test_814()
22697 {
22698         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
22699         echo -n y >> $DIR/$tfile
22700         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
22701         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
22702 }
22703 run_test 814 "sparse cp works as expected (LU-12361)"
22704
22705 test_815()
22706 {
22707         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
22708         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
22709 }
22710 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
22711
22712 test_816() {
22713         [ "$SHARED_KEY" = true ] &&
22714                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22715
22716         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22717         # ensure ost1 is connected
22718         stat $DIR/$tfile >/dev/null || error "can't stat"
22719         wait_osc_import_state client ost1 FULL
22720         # no locks, no reqs to let the connection idle
22721         cancel_lru_locks osc
22722         lru_resize_disable osc
22723         local before
22724         local now
22725         before=$($LCTL get_param -n \
22726                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
22727
22728         wait_osc_import_state client ost1 IDLE
22729         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
22730         now=$($LCTL get_param -n \
22731               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
22732         [ $before == $now ] || error "lru_size changed $before != $now"
22733 }
22734 run_test 816 "do not reset lru_resize on idle reconnect"
22735
22736 cleanup_817() {
22737         umount $tmpdir
22738         exportfs -u localhost:$DIR/nfsexp
22739         rm -rf $DIR/nfsexp
22740 }
22741
22742 test_817() {
22743         systemctl restart nfs-server.service || skip "failed to restart nfsd"
22744
22745         mkdir -p $DIR/nfsexp
22746         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
22747                 error "failed to export nfs"
22748
22749         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
22750         stack_trap cleanup_817 EXIT
22751
22752         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
22753                 error "failed to mount nfs to $tmpdir"
22754
22755         cp /bin/true $tmpdir
22756         $DIR/nfsexp/true || error "failed to execute 'true' command"
22757 }
22758 run_test 817 "nfsd won't cache write lock for exec file"
22759
22760 test_818() {
22761         mkdir $DIR/$tdir
22762         $LFS setstripe -c1 -i0 $DIR/$tfile
22763         $LFS setstripe -c1 -i1 $DIR/$tfile
22764         stop $SINGLEMDS
22765         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
22766         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
22767         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
22768                 error "start $SINGLEMDS failed"
22769         rm -rf $DIR/$tdir
22770 }
22771 run_test 818 "unlink with failed llog"
22772
22773 test_819a() {
22774         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22775         cancel_lru_locks osc
22776         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
22777         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
22778         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
22779         rm -f $TDIR/$tfile
22780 }
22781 run_test 819a "too big niobuf in read"
22782
22783 test_819b() {
22784         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
22785         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
22786         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22787         cancel_lru_locks osc
22788         sleep 1
22789         rm -f $TDIR/$tfile
22790 }
22791 run_test 819b "too big niobuf in write"
22792
22793 #
22794 # tests that do cleanup/setup should be run at the end
22795 #
22796
22797 test_900() {
22798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22799         local ls
22800
22801         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
22802         $LCTL set_param fail_loc=0x903
22803
22804         cancel_lru_locks MGC
22805
22806         FAIL_ON_ERROR=true cleanup
22807         FAIL_ON_ERROR=true setup
22808 }
22809 run_test 900 "umount should not race with any mgc requeue thread"
22810
22811 # LUS-6253/LU-11185
22812 test_901() {
22813         local oldc
22814         local newc
22815         local olds
22816         local news
22817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22818
22819         # some get_param have a bug to handle dot in param name
22820         cancel_lru_locks MGC
22821         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
22822         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
22823         umount_client $MOUNT || error "umount failed"
22824         mount_client $MOUNT || error "mount failed"
22825         cancel_lru_locks MGC
22826         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
22827         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
22828
22829         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
22830         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
22831
22832         return 0
22833 }
22834 run_test 901 "don't leak a mgc lock on client umount"
22835
22836 complete $SECONDS
22837 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
22838 check_and_cleanup_lustre
22839 if [ "$I_MOUNTED" != "yes" ]; then
22840         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
22841 fi
22842 exit_status