Whamcloud - gitweb
LU-12967 ofd: restore sync_on_lock_cancel tunable
[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         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8590                 local soc="obdfilter.*.sync_lock_cancel"
8591                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
8592
8593                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
8594                 if [ -z "$save" ]; then
8595                         soc="obdfilter.*.sync_on_lock_cancel"
8596                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
8597                 fi
8598
8599                 if [ "$save" != "never" ]; then
8600                         local hosts=$(comma_list $(osts_nodes))
8601
8602                         do_nodes $hosts $LCTL set_param $soc=never
8603                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
8604                 fi
8605         fi
8606
8607         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8608         sync; sleep 1; sync
8609         local before=$(date +%s)
8610         cancel_lru_locks osc
8611         local after=$(date +%s)
8612         local diff=$((after - before))
8613         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
8614
8615         rm -f $DIR/$tfile
8616 }
8617 run_test 80 "Page eviction is equally fast at high offsets too"
8618
8619 test_81a() { # LU-456
8620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8621         remote_ost_nodsh && skip "remote OST with nodsh"
8622
8623         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8624         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8625         do_facet ost1 lctl set_param fail_loc=0x80000228
8626
8627         # write should trigger a retry and success
8628         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8629         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8630         RC=$?
8631         if [ $RC -ne 0 ] ; then
8632                 error "write should success, but failed for $RC"
8633         fi
8634 }
8635 run_test 81a "OST should retry write when get -ENOSPC ==============="
8636
8637 test_81b() { # LU-456
8638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8639         remote_ost_nodsh && skip "remote OST with nodsh"
8640
8641         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8642         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8643         do_facet ost1 lctl set_param fail_loc=0x228
8644
8645         # write should retry several times and return -ENOSPC finally
8646         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8647         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8648         RC=$?
8649         ENOSPC=28
8650         if [ $RC -ne $ENOSPC ] ; then
8651                 error "dd should fail for -ENOSPC, but succeed."
8652         fi
8653 }
8654 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8655
8656 test_82() { # LU-1031
8657         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8658         local gid1=14091995
8659         local gid2=16022000
8660
8661         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8662         local MULTIPID1=$!
8663         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8664         local MULTIPID2=$!
8665         kill -USR1 $MULTIPID2
8666         sleep 2
8667         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8668                 error "First grouplock does not block second one"
8669         else
8670                 echo "Second grouplock blocks first one"
8671         fi
8672         kill -USR1 $MULTIPID1
8673         wait $MULTIPID1
8674         wait $MULTIPID2
8675 }
8676 run_test 82 "Basic grouplock test"
8677
8678 test_99() {
8679         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8680
8681         test_mkdir $DIR/$tdir.cvsroot
8682         chown $RUNAS_ID $DIR/$tdir.cvsroot
8683
8684         cd $TMP
8685         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8686
8687         cd /etc/init.d
8688         # some versions of cvs import exit(1) when asked to import links or
8689         # files they can't read.  ignore those files.
8690         local toignore=$(find . -type l -printf '-I %f\n' -o \
8691                          ! -perm /4 -printf '-I %f\n')
8692         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8693                 $tdir.reposname vtag rtag
8694
8695         cd $DIR
8696         test_mkdir $DIR/$tdir.reposname
8697         chown $RUNAS_ID $DIR/$tdir.reposname
8698         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8699
8700         cd $DIR/$tdir.reposname
8701         $RUNAS touch foo99
8702         $RUNAS cvs add -m 'addmsg' foo99
8703         $RUNAS cvs update
8704         $RUNAS cvs commit -m 'nomsg' foo99
8705         rm -fr $DIR/$tdir.cvsroot
8706 }
8707 run_test 99 "cvs strange file/directory operations"
8708
8709 test_100() {
8710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8711         [[ "$NETTYPE" =~ tcp ]] ||
8712                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8713         remote_ost_nodsh && skip "remote OST with nodsh"
8714         remote_mds_nodsh && skip "remote MDS with nodsh"
8715         remote_servers ||
8716                 skip "useless for local single node setup"
8717
8718         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8719                 [ "$PROT" != "tcp" ] && continue
8720                 RPORT=$(echo $REMOTE | cut -d: -f2)
8721                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8722
8723                 rc=0
8724                 LPORT=`echo $LOCAL | cut -d: -f2`
8725                 if [ $LPORT -ge 1024 ]; then
8726                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8727                         netstat -tna
8728                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8729                 fi
8730         done
8731         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8732 }
8733 run_test 100 "check local port using privileged port ==========="
8734
8735 function get_named_value()
8736 {
8737     local tag
8738
8739     tag=$1
8740     while read ;do
8741         line=$REPLY
8742         case $line in
8743         $tag*)
8744             echo $line | sed "s/^$tag[ ]*//"
8745             break
8746             ;;
8747         esac
8748     done
8749 }
8750
8751 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8752                    awk '/^max_cached_mb/ { print $2 }')
8753
8754 cleanup_101a() {
8755         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8756         trap 0
8757 }
8758
8759 test_101a() {
8760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8761
8762         local s
8763         local discard
8764         local nreads=10000
8765         local cache_limit=32
8766
8767         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8768         trap cleanup_101a EXIT
8769         $LCTL set_param -n llite.*.read_ahead_stats 0
8770         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8771
8772         #
8773         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8774         #
8775         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8776         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8777
8778         discard=0
8779         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8780                 get_named_value 'read but discarded' | cut -d" " -f1); do
8781                         discard=$(($discard + $s))
8782         done
8783         cleanup_101a
8784
8785         $LCTL get_param osc.*-osc*.rpc_stats
8786         $LCTL get_param llite.*.read_ahead_stats
8787
8788         # Discard is generally zero, but sometimes a few random reads line up
8789         # and trigger larger readahead, which is wasted & leads to discards.
8790         if [[ $(($discard)) -gt $nreads ]]; then
8791                 error "too many ($discard) discarded pages"
8792         fi
8793         rm -f $DIR/$tfile || true
8794 }
8795 run_test 101a "check read-ahead for random reads"
8796
8797 setup_test101bc() {
8798         test_mkdir $DIR/$tdir
8799         local ssize=$1
8800         local FILE_LENGTH=$2
8801         STRIPE_OFFSET=0
8802
8803         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
8804
8805         local list=$(comma_list $(osts_nodes))
8806         set_osd_param $list '' read_cache_enable 0
8807         set_osd_param $list '' writethrough_cache_enable 0
8808
8809         trap cleanup_test101bc EXIT
8810         # prepare the read-ahead file
8811         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
8812
8813         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
8814                                 count=$FILE_SIZE_MB 2> /dev/null
8815
8816 }
8817
8818 cleanup_test101bc() {
8819         trap 0
8820         rm -rf $DIR/$tdir
8821         rm -f $DIR/$tfile
8822
8823         local list=$(comma_list $(osts_nodes))
8824         set_osd_param $list '' read_cache_enable 1
8825         set_osd_param $list '' writethrough_cache_enable 1
8826 }
8827
8828 calc_total() {
8829         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
8830 }
8831
8832 ra_check_101() {
8833         local READ_SIZE=$1
8834         local STRIPE_SIZE=$2
8835         local FILE_LENGTH=$3
8836         local RA_INC=1048576
8837         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
8838         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
8839                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
8840         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
8841                         get_named_value 'read but discarded' |
8842                         cut -d" " -f1 | calc_total)
8843         if [[ $DISCARD -gt $discard_limit ]]; then
8844                 $LCTL get_param llite.*.read_ahead_stats
8845                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
8846         else
8847                 echo "Read-ahead success for size ${READ_SIZE}"
8848         fi
8849 }
8850
8851 test_101b() {
8852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8853         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8854
8855         local STRIPE_SIZE=1048576
8856         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
8857
8858         if [ $SLOW == "yes" ]; then
8859                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
8860         else
8861                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
8862         fi
8863
8864         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
8865
8866         # prepare the read-ahead file
8867         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8868         cancel_lru_locks osc
8869         for BIDX in 2 4 8 16 32 64 128 256
8870         do
8871                 local BSIZE=$((BIDX*4096))
8872                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
8873                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
8874                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
8875                 $LCTL set_param -n llite.*.read_ahead_stats 0
8876                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
8877                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
8878                 cancel_lru_locks osc
8879                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
8880         done
8881         cleanup_test101bc
8882         true
8883 }
8884 run_test 101b "check stride-io mode read-ahead ================="
8885
8886 test_101c() {
8887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8888
8889         local STRIPE_SIZE=1048576
8890         local FILE_LENGTH=$((STRIPE_SIZE*100))
8891         local nreads=10000
8892         local rsize=65536
8893         local osc_rpc_stats
8894
8895         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8896
8897         cancel_lru_locks osc
8898         $LCTL set_param osc.*.rpc_stats 0
8899         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
8900         $LCTL get_param osc.*.rpc_stats
8901         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
8902                 local stats=$($LCTL get_param -n $osc_rpc_stats)
8903                 local lines=$(echo "$stats" | awk 'END {print NR;}')
8904                 local size
8905
8906                 if [ $lines -le 20 ]; then
8907                         echo "continue debug"
8908                         continue
8909                 fi
8910                 for size in 1 2 4 8; do
8911                         local rpc=$(echo "$stats" |
8912                                     awk '($1 == "'$size':") {print $2; exit; }')
8913                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
8914                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
8915                 done
8916                 echo "$osc_rpc_stats check passed!"
8917         done
8918         cleanup_test101bc
8919         true
8920 }
8921 run_test 101c "check stripe_size aligned read-ahead ================="
8922
8923 set_read_ahead() {
8924         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
8925         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
8926 }
8927
8928 test_101d() {
8929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8930
8931         local file=$DIR/$tfile
8932         local sz_MB=${FILESIZE_101d:-500}
8933         local ra_MB=${READAHEAD_MB:-40}
8934
8935         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
8936         [ $free_MB -lt $sz_MB ] &&
8937                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
8938
8939         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
8940         $LFS setstripe -c -1 $file || error "setstripe failed"
8941
8942         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
8943         echo Cancel LRU locks on lustre client to flush the client cache
8944         cancel_lru_locks osc
8945
8946         echo Disable read-ahead
8947         local old_READAHEAD=$(set_read_ahead 0)
8948
8949         echo Reading the test file $file with read-ahead disabled
8950         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8951
8952         echo Cancel LRU locks on lustre client to flush the client cache
8953         cancel_lru_locks osc
8954         echo Enable read-ahead with ${ra_MB}MB
8955         set_read_ahead $ra_MB
8956
8957         echo Reading the test file $file with read-ahead enabled
8958         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8959
8960         echo "read-ahead disabled time read $raOFF"
8961         echo "read-ahead enabled  time read $raON"
8962
8963         set_read_ahead $old_READAHEAD
8964         rm -f $file
8965         wait_delete_completed
8966
8967         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
8968                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
8969 }
8970 run_test 101d "file read with and without read-ahead enabled"
8971
8972 test_101e() {
8973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8974
8975         local file=$DIR/$tfile
8976         local size_KB=500  #KB
8977         local count=100
8978         local bsize=1024
8979
8980         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8981         local need_KB=$((count * size_KB))
8982         [[ $free_KB -le $need_KB ]] &&
8983                 skip_env "Need free space $need_KB, have $free_KB"
8984
8985         echo "Creating $count ${size_KB}K test files"
8986         for ((i = 0; i < $count; i++)); do
8987                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8988         done
8989
8990         echo "Cancel LRU locks on lustre client to flush the client cache"
8991         cancel_lru_locks $OSC
8992
8993         echo "Reset readahead stats"
8994         $LCTL set_param -n llite.*.read_ahead_stats 0
8995
8996         for ((i = 0; i < $count; i++)); do
8997                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8998         done
8999
9000         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9001                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9002
9003         for ((i = 0; i < $count; i++)); do
9004                 rm -rf $file.$i 2>/dev/null
9005         done
9006
9007         #10000 means 20% reads are missing in readahead
9008         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9009 }
9010 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9011
9012 test_101f() {
9013         which iozone || skip_env "no iozone installed"
9014
9015         local old_debug=$($LCTL get_param debug)
9016         old_debug=${old_debug#*=}
9017         $LCTL set_param debug="reada mmap"
9018
9019         # create a test file
9020         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9021
9022         echo Cancel LRU locks on lustre client to flush the client cache
9023         cancel_lru_locks osc
9024
9025         echo Reset readahead stats
9026         $LCTL set_param -n llite.*.read_ahead_stats 0
9027
9028         echo mmap read the file with small block size
9029         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9030                 > /dev/null 2>&1
9031
9032         echo checking missing pages
9033         $LCTL get_param llite.*.read_ahead_stats
9034         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9035                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9036
9037         $LCTL set_param debug="$old_debug"
9038         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9039         rm -f $DIR/$tfile
9040 }
9041 run_test 101f "check mmap read performance"
9042
9043 test_101g_brw_size_test() {
9044         local mb=$1
9045         local pages=$((mb * 1048576 / PAGE_SIZE))
9046         local file=$DIR/$tfile
9047
9048         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9049                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9050         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9051                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9052                         return 2
9053         done
9054
9055         stack_trap "rm -f $file" EXIT
9056         $LCTL set_param -n osc.*.rpc_stats=0
9057
9058         # 10 RPCs should be enough for the test
9059         local count=10
9060         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9061                 { error "dd write ${mb} MB blocks failed"; return 3; }
9062         cancel_lru_locks osc
9063         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9064                 { error "dd write ${mb} MB blocks failed"; return 4; }
9065
9066         # calculate number of full-sized read and write RPCs
9067         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9068                 sed -n '/pages per rpc/,/^$/p' |
9069                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9070                 END { print reads,writes }'))
9071         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
9072                 return 5
9073         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
9074                 return 6
9075
9076         return 0
9077 }
9078
9079 test_101g() {
9080         remote_ost_nodsh && skip "remote OST with nodsh"
9081
9082         local rpcs
9083         local osts=$(get_facets OST)
9084         local list=$(comma_list $(osts_nodes))
9085         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9086         local brw_size="obdfilter.*.brw_size"
9087
9088         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9089
9090         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9091
9092         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9093                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9094                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9095            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9096                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9097                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9098
9099                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9100                         suffix="M"
9101
9102                 if [[ $orig_mb -lt 16 ]]; then
9103                         save_lustre_params $osts "$brw_size" > $p
9104                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9105                                 error "set 16MB RPC size failed"
9106
9107                         echo "remount client to enable new RPC size"
9108                         remount_client $MOUNT || error "remount_client failed"
9109                 fi
9110
9111                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9112                 # should be able to set brw_size=12, but no rpc_stats for that
9113                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9114         fi
9115
9116         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9117
9118         if [[ $orig_mb -lt 16 ]]; then
9119                 restore_lustre_params < $p
9120                 remount_client $MOUNT || error "remount_client restore failed"
9121         fi
9122
9123         rm -f $p $DIR/$tfile
9124 }
9125 run_test 101g "Big bulk(4/16 MiB) readahead"
9126
9127 test_101h() {
9128         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9129
9130         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9131                 error "dd 70M file failed"
9132         echo Cancel LRU locks on lustre client to flush the client cache
9133         cancel_lru_locks osc
9134
9135         echo "Reset readahead stats"
9136         $LCTL set_param -n llite.*.read_ahead_stats 0
9137
9138         echo "Read 10M of data but cross 64M bundary"
9139         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9140         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9141                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9142         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9143         rm -f $p $DIR/$tfile
9144 }
9145 run_test 101h "Readahead should cover current read window"
9146
9147 setup_test102() {
9148         test_mkdir $DIR/$tdir
9149         chown $RUNAS_ID $DIR/$tdir
9150         STRIPE_SIZE=65536
9151         STRIPE_OFFSET=1
9152         STRIPE_COUNT=$OSTCOUNT
9153         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9154
9155         trap cleanup_test102 EXIT
9156         cd $DIR
9157         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9158         cd $DIR/$tdir
9159         for num in 1 2 3 4; do
9160                 for count in $(seq 1 $STRIPE_COUNT); do
9161                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9162                                 local size=`expr $STRIPE_SIZE \* $num`
9163                                 local file=file"$num-$idx-$count"
9164                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9165                         done
9166                 done
9167         done
9168
9169         cd $DIR
9170         $1 tar cf $TMP/f102.tar $tdir --xattrs
9171 }
9172
9173 cleanup_test102() {
9174         trap 0
9175         rm -f $TMP/f102.tar
9176         rm -rf $DIR/d0.sanity/d102
9177 }
9178
9179 test_102a() {
9180         [ "$UID" != 0 ] && skip "must run as root"
9181         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9182                 skip_env "must have user_xattr"
9183
9184         [ -z "$(which setfattr 2>/dev/null)" ] &&
9185                 skip_env "could not find setfattr"
9186
9187         local testfile=$DIR/$tfile
9188
9189         touch $testfile
9190         echo "set/get xattr..."
9191         setfattr -n trusted.name1 -v value1 $testfile ||
9192                 error "setfattr -n trusted.name1=value1 $testfile failed"
9193         getfattr -n trusted.name1 $testfile 2> /dev/null |
9194           grep "trusted.name1=.value1" ||
9195                 error "$testfile missing trusted.name1=value1"
9196
9197         setfattr -n user.author1 -v author1 $testfile ||
9198                 error "setfattr -n user.author1=author1 $testfile failed"
9199         getfattr -n user.author1 $testfile 2> /dev/null |
9200           grep "user.author1=.author1" ||
9201                 error "$testfile missing trusted.author1=author1"
9202
9203         echo "listxattr..."
9204         setfattr -n trusted.name2 -v value2 $testfile ||
9205                 error "$testfile unable to set trusted.name2"
9206         setfattr -n trusted.name3 -v value3 $testfile ||
9207                 error "$testfile unable to set trusted.name3"
9208         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9209             grep "trusted.name" | wc -l) -eq 3 ] ||
9210                 error "$testfile missing 3 trusted.name xattrs"
9211
9212         setfattr -n user.author2 -v author2 $testfile ||
9213                 error "$testfile unable to set user.author2"
9214         setfattr -n user.author3 -v author3 $testfile ||
9215                 error "$testfile unable to set user.author3"
9216         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9217             grep "user.author" | wc -l) -eq 3 ] ||
9218                 error "$testfile missing 3 user.author xattrs"
9219
9220         echo "remove xattr..."
9221         setfattr -x trusted.name1 $testfile ||
9222                 error "$testfile error deleting trusted.name1"
9223         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9224                 error "$testfile did not delete trusted.name1 xattr"
9225
9226         setfattr -x user.author1 $testfile ||
9227                 error "$testfile error deleting user.author1"
9228         echo "set lustre special xattr ..."
9229         $LFS setstripe -c1 $testfile
9230         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9231                 awk -F "=" '/trusted.lov/ { print $2 }' )
9232         setfattr -n "trusted.lov" -v $lovea $testfile ||
9233                 error "$testfile doesn't ignore setting trusted.lov again"
9234         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9235                 error "$testfile allow setting invalid trusted.lov"
9236         rm -f $testfile
9237 }
9238 run_test 102a "user xattr test =================================="
9239
9240 test_102b() {
9241         [ -z "$(which setfattr 2>/dev/null)" ] &&
9242                 skip_env "could not find setfattr"
9243         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9244
9245         # b10930: get/set/list trusted.lov xattr
9246         echo "get/set/list trusted.lov xattr ..."
9247         local testfile=$DIR/$tfile
9248         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9249                 error "setstripe failed"
9250         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
9251                 error "getstripe failed"
9252         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
9253                 error "can't get trusted.lov from $testfile"
9254
9255         local testfile2=${testfile}2
9256         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
9257                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
9258
9259         $MCREATE $testfile2
9260         setfattr -n trusted.lov -v $value $testfile2
9261         local stripe_size=$($LFS getstripe -S $testfile2)
9262         local stripe_count=$($LFS getstripe -c $testfile2)
9263         [[ $stripe_size -eq 65536 ]] ||
9264                 error "stripe size $stripe_size != 65536"
9265         [[ $stripe_count -eq $STRIPECOUNT ]] ||
9266                 error "stripe count $stripe_count != $STRIPECOUNT"
9267         rm -f $DIR/$tfile
9268 }
9269 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
9270
9271 test_102c() {
9272         [ -z "$(which setfattr 2>/dev/null)" ] &&
9273                 skip_env "could not find setfattr"
9274         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9275
9276         # b10930: get/set/list lustre.lov xattr
9277         echo "get/set/list lustre.lov xattr ..."
9278         test_mkdir $DIR/$tdir
9279         chown $RUNAS_ID $DIR/$tdir
9280         local testfile=$DIR/$tdir/$tfile
9281         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9282                 error "setstripe failed"
9283         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9284                 error "getstripe failed"
9285         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9286         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9287
9288         local testfile2=${testfile}2
9289         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9290                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9291
9292         $RUNAS $MCREATE $testfile2
9293         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9294         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9295         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9296         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9297         [ $stripe_count -eq $STRIPECOUNT ] ||
9298                 error "stripe count $stripe_count != $STRIPECOUNT"
9299 }
9300 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9301
9302 compare_stripe_info1() {
9303         local stripe_index_all_zero=true
9304
9305         for num in 1 2 3 4; do
9306                 for count in $(seq 1 $STRIPE_COUNT); do
9307                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9308                                 local size=$((STRIPE_SIZE * num))
9309                                 local file=file"$num-$offset-$count"
9310                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9311                                 [[ $stripe_size -ne $size ]] &&
9312                                     error "$file: size $stripe_size != $size"
9313                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9314                                 # allow fewer stripes to be created, ORI-601
9315                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9316                                     error "$file: count $stripe_count != $count"
9317                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9318                                 [[ $stripe_index -ne 0 ]] &&
9319                                         stripe_index_all_zero=false
9320                         done
9321                 done
9322         done
9323         $stripe_index_all_zero &&
9324                 error "all files are being extracted starting from OST index 0"
9325         return 0
9326 }
9327
9328 have_xattrs_include() {
9329         tar --help | grep -q xattrs-include &&
9330                 echo --xattrs-include="lustre.*"
9331 }
9332
9333 test_102d() {
9334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9335         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9336
9337         XINC=$(have_xattrs_include)
9338         setup_test102
9339         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9340         cd $DIR/$tdir/$tdir
9341         compare_stripe_info1
9342 }
9343 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9344
9345 test_102f() {
9346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9347         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9348
9349         XINC=$(have_xattrs_include)
9350         setup_test102
9351         test_mkdir $DIR/$tdir.restore
9352         cd $DIR
9353         tar cf - --xattrs $tdir | tar xf - \
9354                 -C $DIR/$tdir.restore --xattrs $XINC
9355         cd $DIR/$tdir.restore/$tdir
9356         compare_stripe_info1
9357 }
9358 run_test 102f "tar copy files, not keep osts"
9359
9360 grow_xattr() {
9361         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9362                 skip "must have user_xattr"
9363         [ -z "$(which setfattr 2>/dev/null)" ] &&
9364                 skip_env "could not find setfattr"
9365         [ -z "$(which getfattr 2>/dev/null)" ] &&
9366                 skip_env "could not find getfattr"
9367
9368         local xsize=${1:-1024}  # in bytes
9369         local file=$DIR/$tfile
9370         local value="$(generate_string $xsize)"
9371         local xbig=trusted.big
9372         local toobig=$2
9373
9374         touch $file
9375         log "save $xbig on $file"
9376         if [ -z "$toobig" ]
9377         then
9378                 setfattr -n $xbig -v $value $file ||
9379                         error "saving $xbig on $file failed"
9380         else
9381                 setfattr -n $xbig -v $value $file &&
9382                         error "saving $xbig on $file succeeded"
9383                 return 0
9384         fi
9385
9386         local orig=$(get_xattr_value $xbig $file)
9387         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9388
9389         local xsml=trusted.sml
9390         log "save $xsml on $file"
9391         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9392
9393         local new=$(get_xattr_value $xbig $file)
9394         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9395
9396         log "grow $xsml on $file"
9397         setfattr -n $xsml -v "$value" $file ||
9398                 error "growing $xsml on $file failed"
9399
9400         new=$(get_xattr_value $xbig $file)
9401         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9402         log "$xbig still valid after growing $xsml"
9403
9404         rm -f $file
9405 }
9406
9407 test_102h() { # bug 15777
9408         grow_xattr 1024
9409 }
9410 run_test 102h "grow xattr from inside inode to external block"
9411
9412 test_102ha() {
9413         large_xattr_enabled || skip_env "ea_inode feature disabled"
9414
9415         echo "setting xattr of max xattr size: $(max_xattr_size)"
9416         grow_xattr $(max_xattr_size)
9417
9418         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9419         echo "This should fail:"
9420         grow_xattr $(($(max_xattr_size) + 10)) 1
9421 }
9422 run_test 102ha "grow xattr from inside inode to external inode"
9423
9424 test_102i() { # bug 17038
9425         [ -z "$(which getfattr 2>/dev/null)" ] &&
9426                 skip "could not find getfattr"
9427
9428         touch $DIR/$tfile
9429         ln -s $DIR/$tfile $DIR/${tfile}link
9430         getfattr -n trusted.lov $DIR/$tfile ||
9431                 error "lgetxattr on $DIR/$tfile failed"
9432         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9433                 grep -i "no such attr" ||
9434                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9435         rm -f $DIR/$tfile $DIR/${tfile}link
9436 }
9437 run_test 102i "lgetxattr test on symbolic link ============"
9438
9439 test_102j() {
9440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9441         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9442
9443         XINC=$(have_xattrs_include)
9444         setup_test102 "$RUNAS"
9445         chown $RUNAS_ID $DIR/$tdir
9446         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9447         cd $DIR/$tdir/$tdir
9448         compare_stripe_info1 "$RUNAS"
9449 }
9450 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9451
9452 test_102k() {
9453         [ -z "$(which setfattr 2>/dev/null)" ] &&
9454                 skip "could not find setfattr"
9455
9456         touch $DIR/$tfile
9457         # b22187 just check that does not crash for regular file.
9458         setfattr -n trusted.lov $DIR/$tfile
9459         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9460         local test_kdir=$DIR/$tdir
9461         test_mkdir $test_kdir
9462         local default_size=$($LFS getstripe -S $test_kdir)
9463         local default_count=$($LFS getstripe -c $test_kdir)
9464         local default_offset=$($LFS getstripe -i $test_kdir)
9465         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
9466                 error 'dir setstripe failed'
9467         setfattr -n trusted.lov $test_kdir
9468         local stripe_size=$($LFS getstripe -S $test_kdir)
9469         local stripe_count=$($LFS getstripe -c $test_kdir)
9470         local stripe_offset=$($LFS getstripe -i $test_kdir)
9471         [ $stripe_size -eq $default_size ] ||
9472                 error "stripe size $stripe_size != $default_size"
9473         [ $stripe_count -eq $default_count ] ||
9474                 error "stripe count $stripe_count != $default_count"
9475         [ $stripe_offset -eq $default_offset ] ||
9476                 error "stripe offset $stripe_offset != $default_offset"
9477         rm -rf $DIR/$tfile $test_kdir
9478 }
9479 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
9480
9481 test_102l() {
9482         [ -z "$(which getfattr 2>/dev/null)" ] &&
9483                 skip "could not find getfattr"
9484
9485         # LU-532 trusted. xattr is invisible to non-root
9486         local testfile=$DIR/$tfile
9487
9488         touch $testfile
9489
9490         echo "listxattr as user..."
9491         chown $RUNAS_ID $testfile
9492         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
9493             grep -q "trusted" &&
9494                 error "$testfile trusted xattrs are user visible"
9495
9496         return 0;
9497 }
9498 run_test 102l "listxattr size test =================================="
9499
9500 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
9501         local path=$DIR/$tfile
9502         touch $path
9503
9504         listxattr_size_check $path || error "listattr_size_check $path failed"
9505 }
9506 run_test 102m "Ensure listxattr fails on small bufffer ========"
9507
9508 cleanup_test102
9509
9510 getxattr() { # getxattr path name
9511         # Return the base64 encoding of the value of xattr name on path.
9512         local path=$1
9513         local name=$2
9514
9515         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
9516         # file: $path
9517         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9518         #
9519         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9520
9521         getfattr --absolute-names --encoding=base64 --name=$name $path |
9522                 awk -F= -v name=$name '$1 == name {
9523                         print substr($0, index($0, "=") + 1);
9524         }'
9525 }
9526
9527 test_102n() { # LU-4101 mdt: protect internal xattrs
9528         [ -z "$(which setfattr 2>/dev/null)" ] &&
9529                 skip "could not find setfattr"
9530         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
9531         then
9532                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
9533         fi
9534
9535         local file0=$DIR/$tfile.0
9536         local file1=$DIR/$tfile.1
9537         local xattr0=$TMP/$tfile.0
9538         local xattr1=$TMP/$tfile.1
9539         local namelist="lov lma lmv link fid version som hsm"
9540         local name
9541         local value
9542
9543         rm -rf $file0 $file1 $xattr0 $xattr1
9544         touch $file0 $file1
9545
9546         # Get 'before' xattrs of $file1.
9547         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9548
9549         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9550                 namelist+=" lfsck_namespace"
9551         for name in $namelist; do
9552                 # Try to copy xattr from $file0 to $file1.
9553                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9554
9555                 setfattr --name=trusted.$name --value="$value" $file1 ||
9556                         error "setxattr 'trusted.$name' failed"
9557
9558                 # Try to set a garbage xattr.
9559                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9560
9561                 if [[ x$name == "xlov" ]]; then
9562                         setfattr --name=trusted.lov --value="$value" $file1 &&
9563                         error "setxattr invalid 'trusted.lov' success"
9564                 else
9565                         setfattr --name=trusted.$name --value="$value" $file1 ||
9566                                 error "setxattr invalid 'trusted.$name' failed"
9567                 fi
9568
9569                 # Try to remove the xattr from $file1. We don't care if this
9570                 # appears to succeed or fail, we just don't want there to be
9571                 # any changes or crashes.
9572                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9573         done
9574
9575         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9576         then
9577                 name="lfsck_ns"
9578                 # Try to copy xattr from $file0 to $file1.
9579                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9580
9581                 setfattr --name=trusted.$name --value="$value" $file1 ||
9582                         error "setxattr 'trusted.$name' failed"
9583
9584                 # Try to set a garbage xattr.
9585                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9586
9587                 setfattr --name=trusted.$name --value="$value" $file1 ||
9588                         error "setxattr 'trusted.$name' failed"
9589
9590                 # Try to remove the xattr from $file1. We don't care if this
9591                 # appears to succeed or fail, we just don't want there to be
9592                 # any changes or crashes.
9593                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9594         fi
9595
9596         # Get 'after' xattrs of file1.
9597         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9598
9599         if ! diff $xattr0 $xattr1; then
9600                 error "before and after xattrs of '$file1' differ"
9601         fi
9602
9603         rm -rf $file0 $file1 $xattr0 $xattr1
9604
9605         return 0
9606 }
9607 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9608
9609 test_102p() { # LU-4703 setxattr did not check ownership
9610         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9611                 skip "MDS needs to be at least 2.5.56"
9612
9613         local testfile=$DIR/$tfile
9614
9615         touch $testfile
9616
9617         echo "setfacl as user..."
9618         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9619         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9620
9621         echo "setfattr as user..."
9622         setfacl -m "u:$RUNAS_ID:---" $testfile
9623         $RUNAS setfattr -x system.posix_acl_access $testfile
9624         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9625 }
9626 run_test 102p "check setxattr(2) correctly fails without permission"
9627
9628 test_102q() {
9629         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9630                 skip "MDS needs to be at least 2.6.92"
9631
9632         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9633 }
9634 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9635
9636 test_102r() {
9637         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9638                 skip "MDS needs to be at least 2.6.93"
9639
9640         touch $DIR/$tfile || error "touch"
9641         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9642         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9643         rm $DIR/$tfile || error "rm"
9644
9645         #normal directory
9646         mkdir -p $DIR/$tdir || error "mkdir"
9647         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9648         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9649         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9650                 error "$testfile error deleting user.author1"
9651         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9652                 grep "user.$(basename $tdir)" &&
9653                 error "$tdir did not delete user.$(basename $tdir)"
9654         rmdir $DIR/$tdir || error "rmdir"
9655
9656         #striped directory
9657         test_mkdir $DIR/$tdir
9658         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9659         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9660         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9661                 error "$testfile error deleting user.author1"
9662         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9663                 grep "user.$(basename $tdir)" &&
9664                 error "$tdir did not delete user.$(basename $tdir)"
9665         rmdir $DIR/$tdir || error "rm striped dir"
9666 }
9667 run_test 102r "set EAs with empty values"
9668
9669 test_102s() {
9670         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9671                 skip "MDS needs to be at least 2.11.52"
9672
9673         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9674
9675         save_lustre_params client "llite.*.xattr_cache" > $save
9676
9677         for cache in 0 1; do
9678                 lctl set_param llite.*.xattr_cache=$cache
9679
9680                 rm -f $DIR/$tfile
9681                 touch $DIR/$tfile || error "touch"
9682                 for prefix in lustre security system trusted user; do
9683                         # Note getxattr() may fail with 'Operation not
9684                         # supported' or 'No such attribute' depending
9685                         # on prefix and cache.
9686                         getfattr -n $prefix.n102s $DIR/$tfile &&
9687                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9688                 done
9689         done
9690
9691         restore_lustre_params < $save
9692 }
9693 run_test 102s "getting nonexistent xattrs should fail"
9694
9695 test_102t() {
9696         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9697                 skip "MDS needs to be at least 2.11.52"
9698
9699         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9700
9701         save_lustre_params client "llite.*.xattr_cache" > $save
9702
9703         for cache in 0 1; do
9704                 lctl set_param llite.*.xattr_cache=$cache
9705
9706                 for buf_size in 0 256; do
9707                         rm -f $DIR/$tfile
9708                         touch $DIR/$tfile || error "touch"
9709                         setfattr -n user.multiop $DIR/$tfile
9710                         $MULTIOP $DIR/$tfile oa$buf_size ||
9711                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9712                 done
9713         done
9714
9715         restore_lustre_params < $save
9716 }
9717 run_test 102t "zero length xattr values handled correctly"
9718
9719 run_acl_subtest()
9720 {
9721     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9722     return $?
9723 }
9724
9725 test_103a() {
9726         [ "$UID" != 0 ] && skip "must run as root"
9727         $GSS && skip_env "could not run under gss"
9728         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9729                 skip_env "must have acl enabled"
9730         [ -z "$(which setfacl 2>/dev/null)" ] &&
9731                 skip_env "could not find setfacl"
9732         remote_mds_nodsh && skip "remote MDS with nodsh"
9733
9734         gpasswd -a daemon bin                           # LU-5641
9735         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
9736
9737         declare -a identity_old
9738
9739         for num in $(seq $MDSCOUNT); do
9740                 switch_identity $num true || identity_old[$num]=$?
9741         done
9742
9743         SAVE_UMASK=$(umask)
9744         umask 0022
9745         mkdir -p $DIR/$tdir
9746         cd $DIR/$tdir
9747
9748         echo "performing cp ..."
9749         run_acl_subtest cp || error "run_acl_subtest cp failed"
9750         echo "performing getfacl-noacl..."
9751         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
9752         echo "performing misc..."
9753         run_acl_subtest misc || error  "misc test failed"
9754         echo "performing permissions..."
9755         run_acl_subtest permissions || error "permissions failed"
9756         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
9757         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
9758                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
9759                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
9760         then
9761                 echo "performing permissions xattr..."
9762                 run_acl_subtest permissions_xattr ||
9763                         error "permissions_xattr failed"
9764         fi
9765         echo "performing setfacl..."
9766         run_acl_subtest setfacl || error  "setfacl test failed"
9767
9768         # inheritance test got from HP
9769         echo "performing inheritance..."
9770         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
9771         chmod +x make-tree || error "chmod +x failed"
9772         run_acl_subtest inheritance || error "inheritance test failed"
9773         rm -f make-tree
9774
9775         echo "LU-974 ignore umask when acl is enabled..."
9776         run_acl_subtest 974 || error "LU-974 umask test failed"
9777         if [ $MDSCOUNT -ge 2 ]; then
9778                 run_acl_subtest 974_remote ||
9779                         error "LU-974 umask test failed under remote dir"
9780         fi
9781
9782         echo "LU-2561 newly created file is same size as directory..."
9783         if [ "$mds1_FSTYPE" != "zfs" ]; then
9784                 run_acl_subtest 2561 || error "LU-2561 test failed"
9785         else
9786                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
9787         fi
9788
9789         run_acl_subtest 4924 || error "LU-4924 test failed"
9790
9791         cd $SAVE_PWD
9792         umask $SAVE_UMASK
9793
9794         for num in $(seq $MDSCOUNT); do
9795                 if [ "${identity_old[$num]}" = 1 ]; then
9796                         switch_identity $num false || identity_old[$num]=$?
9797                 fi
9798         done
9799 }
9800 run_test 103a "acl test"
9801
9802 test_103b() {
9803         declare -a pids
9804         local U
9805
9806         for U in {0..511}; do
9807                 {
9808                 local O=$(printf "%04o" $U)
9809
9810                 umask $(printf "%04o" $((511 ^ $O)))
9811                 $LFS setstripe -c 1 $DIR/$tfile.s$O
9812                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
9813
9814                 (( $S == ($O & 0666) )) ||
9815                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
9816
9817                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
9818                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
9819                 (( $S == ($O & 0666) )) ||
9820                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
9821
9822                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
9823                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
9824                 (( $S == ($O & 0666) )) ||
9825                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
9826                 rm -f $DIR/$tfile.[smp]$0
9827                 } &
9828                 local pid=$!
9829
9830                 # limit the concurrently running threads to 64. LU-11878
9831                 local idx=$((U % 64))
9832                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
9833                 pids[idx]=$pid
9834         done
9835         wait
9836 }
9837 run_test 103b "umask lfs setstripe"
9838
9839 test_103c() {
9840         mkdir -p $DIR/$tdir
9841         cp -rp $DIR/$tdir $DIR/$tdir.bak
9842
9843         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
9844                 error "$DIR/$tdir shouldn't contain default ACL"
9845         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
9846                 error "$DIR/$tdir.bak shouldn't contain default ACL"
9847         true
9848 }
9849 run_test 103c "'cp -rp' won't set empty acl"
9850
9851 test_104a() {
9852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9853
9854         touch $DIR/$tfile
9855         lfs df || error "lfs df failed"
9856         lfs df -ih || error "lfs df -ih failed"
9857         lfs df -h $DIR || error "lfs df -h $DIR failed"
9858         lfs df -i $DIR || error "lfs df -i $DIR failed"
9859         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
9860         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
9861
9862         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
9863         lctl --device %$OSC deactivate
9864         lfs df || error "lfs df with deactivated OSC failed"
9865         lctl --device %$OSC activate
9866         # wait the osc back to normal
9867         wait_osc_import_ready client ost
9868
9869         lfs df || error "lfs df with reactivated OSC failed"
9870         rm -f $DIR/$tfile
9871 }
9872 run_test 104a "lfs df [-ih] [path] test ========================="
9873
9874 test_104b() {
9875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9876         [ $RUNAS_ID -eq $UID ] &&
9877                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9878
9879         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
9880                         grep "Permission denied" | wc -l)))
9881         if [ $denied_cnt -ne 0 ]; then
9882                 error "lfs check servers test failed"
9883         fi
9884 }
9885 run_test 104b "$RUNAS lfs check servers test ===================="
9886
9887 test_105a() {
9888         # doesn't work on 2.4 kernels
9889         touch $DIR/$tfile
9890         if $(flock_is_enabled); then
9891                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
9892         else
9893                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
9894         fi
9895         rm -f $DIR/$tfile
9896 }
9897 run_test 105a "flock when mounted without -o flock test ========"
9898
9899 test_105b() {
9900         touch $DIR/$tfile
9901         if $(flock_is_enabled); then
9902                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
9903         else
9904                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
9905         fi
9906         rm -f $DIR/$tfile
9907 }
9908 run_test 105b "fcntl when mounted without -o flock test ========"
9909
9910 test_105c() {
9911         touch $DIR/$tfile
9912         if $(flock_is_enabled); then
9913                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
9914         else
9915                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
9916         fi
9917         rm -f $DIR/$tfile
9918 }
9919 run_test 105c "lockf when mounted without -o flock test"
9920
9921 test_105d() { # bug 15924
9922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9923
9924         test_mkdir $DIR/$tdir
9925         flock_is_enabled || skip_env "mount w/o flock enabled"
9926         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
9927         $LCTL set_param fail_loc=0x80000315
9928         flocks_test 2 $DIR/$tdir
9929 }
9930 run_test 105d "flock race (should not freeze) ========"
9931
9932 test_105e() { # bug 22660 && 22040
9933         flock_is_enabled || skip_env "mount w/o flock enabled"
9934
9935         touch $DIR/$tfile
9936         flocks_test 3 $DIR/$tfile
9937 }
9938 run_test 105e "Two conflicting flocks from same process"
9939
9940 test_106() { #bug 10921
9941         test_mkdir $DIR/$tdir
9942         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
9943         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
9944 }
9945 run_test 106 "attempt exec of dir followed by chown of that dir"
9946
9947 test_107() {
9948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9949
9950         CDIR=`pwd`
9951         local file=core
9952
9953         cd $DIR
9954         rm -f $file
9955
9956         local save_pattern=$(sysctl -n kernel.core_pattern)
9957         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
9958         sysctl -w kernel.core_pattern=$file
9959         sysctl -w kernel.core_uses_pid=0
9960
9961         ulimit -c unlimited
9962         sleep 60 &
9963         SLEEPPID=$!
9964
9965         sleep 1
9966
9967         kill -s 11 $SLEEPPID
9968         wait $SLEEPPID
9969         if [ -e $file ]; then
9970                 size=`stat -c%s $file`
9971                 [ $size -eq 0 ] && error "Fail to create core file $file"
9972         else
9973                 error "Fail to create core file $file"
9974         fi
9975         rm -f $file
9976         sysctl -w kernel.core_pattern=$save_pattern
9977         sysctl -w kernel.core_uses_pid=$save_uses_pid
9978         cd $CDIR
9979 }
9980 run_test 107 "Coredump on SIG"
9981
9982 test_110() {
9983         test_mkdir $DIR/$tdir
9984         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
9985         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
9986                 error "mkdir with 256 char should fail, but did not"
9987         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
9988                 error "create with 255 char failed"
9989         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
9990                 error "create with 256 char should fail, but did not"
9991
9992         ls -l $DIR/$tdir
9993         rm -rf $DIR/$tdir
9994 }
9995 run_test 110 "filename length checking"
9996
9997 #
9998 # Purpose: To verify dynamic thread (OSS) creation.
9999 #
10000 test_115() {
10001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10002         remote_ost_nodsh && skip "remote OST with nodsh"
10003
10004         # Lustre does not stop service threads once they are started.
10005         # Reset number of running threads to default.
10006         stopall
10007         setupall
10008
10009         local OSTIO_pre
10010         local save_params="$TMP/sanity-$TESTNAME.parameters"
10011
10012         # Get ll_ost_io count before I/O
10013         OSTIO_pre=$(do_facet ost1 \
10014                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10015         # Exit if lustre is not running (ll_ost_io not running).
10016         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10017
10018         echo "Starting with $OSTIO_pre threads"
10019         local thread_max=$((OSTIO_pre * 2))
10020         local rpc_in_flight=$((thread_max * 2))
10021         # Number of I/O Process proposed to be started.
10022         local nfiles
10023         local facets=$(get_facets OST)
10024
10025         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10026         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10027
10028         # Set in_flight to $rpc_in_flight
10029         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10030                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10031         nfiles=${rpc_in_flight}
10032         # Set ost thread_max to $thread_max
10033         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10034
10035         # 5 Minutes should be sufficient for max number of OSS
10036         # threads(thread_max) to be created.
10037         local timeout=300
10038
10039         # Start I/O.
10040         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10041         test_mkdir $DIR/$tdir
10042         for i in $(seq $nfiles); do
10043                 local file=$DIR/$tdir/${tfile}-$i
10044                 $LFS setstripe -c -1 -i 0 $file
10045                 ($WTL $file $timeout)&
10046         done
10047
10048         # I/O Started - Wait for thread_started to reach thread_max or report
10049         # error if thread_started is more than thread_max.
10050         echo "Waiting for thread_started to reach thread_max"
10051         local thread_started=0
10052         local end_time=$((SECONDS + timeout))
10053
10054         while [ $SECONDS -le $end_time ] ; do
10055                 echo -n "."
10056                 # Get ost i/o thread_started count.
10057                 thread_started=$(do_facet ost1 \
10058                         "$LCTL get_param \
10059                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10060                 # Break out if thread_started is equal/greater than thread_max
10061                 if [[ $thread_started -ge $thread_max ]]; then
10062                         echo ll_ost_io thread_started $thread_started, \
10063                                 equal/greater than thread_max $thread_max
10064                         break
10065                 fi
10066                 sleep 1
10067         done
10068
10069         # Cleanup - We have the numbers, Kill i/o jobs if running.
10070         jobcount=($(jobs -p))
10071         for i in $(seq 0 $((${#jobcount[@]}-1)))
10072         do
10073                 kill -9 ${jobcount[$i]}
10074                 if [ $? -ne 0 ] ; then
10075                         echo Warning: \
10076                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10077                 fi
10078         done
10079
10080         # Cleanup files left by WTL binary.
10081         for i in $(seq $nfiles); do
10082                 local file=$DIR/$tdir/${tfile}-$i
10083                 rm -rf $file
10084                 if [ $? -ne 0 ] ; then
10085                         echo "Warning: Failed to delete file $file"
10086                 fi
10087         done
10088
10089         restore_lustre_params <$save_params
10090         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10091
10092         # Error out if no new thread has started or Thread started is greater
10093         # than thread max.
10094         if [[ $thread_started -le $OSTIO_pre ||
10095                         $thread_started -gt $thread_max ]]; then
10096                 error "ll_ost_io: thread_started $thread_started" \
10097                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10098                       "No new thread started or thread started greater " \
10099                       "than thread_max."
10100         fi
10101 }
10102 run_test 115 "verify dynamic thread creation===================="
10103
10104 free_min_max () {
10105         wait_delete_completed
10106         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10107         echo "OST kbytes available: ${AVAIL[@]}"
10108         MAXV=${AVAIL[0]}
10109         MAXI=0
10110         MINV=${AVAIL[0]}
10111         MINI=0
10112         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10113                 #echo OST $i: ${AVAIL[i]}kb
10114                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10115                         MAXV=${AVAIL[i]}
10116                         MAXI=$i
10117                 fi
10118                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10119                         MINV=${AVAIL[i]}
10120                         MINI=$i
10121                 fi
10122         done
10123         echo "Min free space: OST $MINI: $MINV"
10124         echo "Max free space: OST $MAXI: $MAXV"
10125 }
10126
10127 test_116a() { # was previously test_116()
10128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10129         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10130         remote_mds_nodsh && skip "remote MDS with nodsh"
10131
10132         echo -n "Free space priority "
10133         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10134                 head -n1
10135         declare -a AVAIL
10136         free_min_max
10137
10138         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10139         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10140         trap simple_cleanup_common EXIT
10141
10142         # Check if we need to generate uneven OSTs
10143         test_mkdir -p $DIR/$tdir/OST${MINI}
10144         local FILL=$((MINV / 4))
10145         local DIFF=$((MAXV - MINV))
10146         local DIFF2=$((DIFF * 100 / MINV))
10147
10148         local threshold=$(do_facet $SINGLEMDS \
10149                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10150         threshold=${threshold%%%}
10151         echo -n "Check for uneven OSTs: "
10152         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10153
10154         if [[ $DIFF2 -gt $threshold ]]; then
10155                 echo "ok"
10156                 echo "Don't need to fill OST$MINI"
10157         else
10158                 # generate uneven OSTs. Write 2% over the QOS threshold value
10159                 echo "no"
10160                 DIFF=$((threshold - DIFF2 + 2))
10161                 DIFF2=$((MINV * DIFF / 100))
10162                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10163                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10164                         error "setstripe failed"
10165                 DIFF=$((DIFF2 / 2048))
10166                 i=0
10167                 while [ $i -lt $DIFF ]; do
10168                         i=$((i + 1))
10169                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10170                                 bs=2M count=1 2>/dev/null
10171                         echo -n .
10172                 done
10173                 echo .
10174                 sync
10175                 sleep_maxage
10176                 free_min_max
10177         fi
10178
10179         DIFF=$((MAXV - MINV))
10180         DIFF2=$((DIFF * 100 / MINV))
10181         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10182         if [ $DIFF2 -gt $threshold ]; then
10183                 echo "ok"
10184         else
10185                 echo "failed - QOS mode won't be used"
10186                 simple_cleanup_common
10187                 skip "QOS imbalance criteria not met"
10188         fi
10189
10190         MINI1=$MINI
10191         MINV1=$MINV
10192         MAXI1=$MAXI
10193         MAXV1=$MAXV
10194
10195         # now fill using QOS
10196         $LFS setstripe -c 1 $DIR/$tdir
10197         FILL=$((FILL / 200))
10198         if [ $FILL -gt 600 ]; then
10199                 FILL=600
10200         fi
10201         echo "writing $FILL files to QOS-assigned OSTs"
10202         i=0
10203         while [ $i -lt $FILL ]; do
10204                 i=$((i + 1))
10205                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10206                         count=1 2>/dev/null
10207                 echo -n .
10208         done
10209         echo "wrote $i 200k files"
10210         sync
10211         sleep_maxage
10212
10213         echo "Note: free space may not be updated, so measurements might be off"
10214         free_min_max
10215         DIFF2=$((MAXV - MINV))
10216         echo "free space delta: orig $DIFF final $DIFF2"
10217         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10218         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10219         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10220         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10221         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10222         if [[ $DIFF -gt 0 ]]; then
10223                 FILL=$((DIFF2 * 100 / DIFF - 100))
10224                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10225         fi
10226
10227         # Figure out which files were written where
10228         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10229                awk '/'$MINI1': / {print $2; exit}')
10230         echo $UUID
10231         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10232         echo "$MINC files created on smaller OST $MINI1"
10233         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10234                awk '/'$MAXI1': / {print $2; exit}')
10235         echo $UUID
10236         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10237         echo "$MAXC files created on larger OST $MAXI1"
10238         if [[ $MINC -gt 0 ]]; then
10239                 FILL=$((MAXC * 100 / MINC - 100))
10240                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10241         fi
10242         [[ $MAXC -gt $MINC ]] ||
10243                 error_ignore LU-9 "stripe QOS didn't balance free space"
10244         simple_cleanup_common
10245 }
10246 run_test 116a "stripe QOS: free space balance ==================="
10247
10248 test_116b() { # LU-2093
10249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10250         remote_mds_nodsh && skip "remote MDS with nodsh"
10251
10252 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10253         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10254                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10255         [ -z "$old_rr" ] && skip "no QOS"
10256         do_facet $SINGLEMDS lctl set_param \
10257                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10258         mkdir -p $DIR/$tdir
10259         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10260         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10261         do_facet $SINGLEMDS lctl set_param fail_loc=0
10262         rm -rf $DIR/$tdir
10263         do_facet $SINGLEMDS lctl set_param \
10264                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10265 }
10266 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10267
10268 test_117() # bug 10891
10269 {
10270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10271
10272         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10273         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10274         lctl set_param fail_loc=0x21e
10275         > $DIR/$tfile || error "truncate failed"
10276         lctl set_param fail_loc=0
10277         echo "Truncate succeeded."
10278         rm -f $DIR/$tfile
10279 }
10280 run_test 117 "verify osd extend =========="
10281
10282 NO_SLOW_RESENDCOUNT=4
10283 export OLD_RESENDCOUNT=""
10284 set_resend_count () {
10285         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10286         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10287         lctl set_param -n $PROC_RESENDCOUNT $1
10288         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10289 }
10290
10291 # for reduce test_118* time (b=14842)
10292 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10293
10294 # Reset async IO behavior after error case
10295 reset_async() {
10296         FILE=$DIR/reset_async
10297
10298         # Ensure all OSCs are cleared
10299         $LFS setstripe -c -1 $FILE
10300         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10301         sync
10302         rm $FILE
10303 }
10304
10305 test_118a() #bug 11710
10306 {
10307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10308
10309         reset_async
10310
10311         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10312         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10313         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10314
10315         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10316                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10317                 return 1;
10318         fi
10319         rm -f $DIR/$tfile
10320 }
10321 run_test 118a "verify O_SYNC works =========="
10322
10323 test_118b()
10324 {
10325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10326         remote_ost_nodsh && skip "remote OST with nodsh"
10327
10328         reset_async
10329
10330         #define OBD_FAIL_SRV_ENOENT 0x217
10331         set_nodes_failloc "$(osts_nodes)" 0x217
10332         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10333         RC=$?
10334         set_nodes_failloc "$(osts_nodes)" 0
10335         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10336         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10337                     grep -c writeback)
10338
10339         if [[ $RC -eq 0 ]]; then
10340                 error "Must return error due to dropped pages, rc=$RC"
10341                 return 1;
10342         fi
10343
10344         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10345                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10346                 return 1;
10347         fi
10348
10349         echo "Dirty pages not leaked on ENOENT"
10350
10351         # Due to the above error the OSC will issue all RPCs syncronously
10352         # until a subsequent RPC completes successfully without error.
10353         $MULTIOP $DIR/$tfile Ow4096yc
10354         rm -f $DIR/$tfile
10355
10356         return 0
10357 }
10358 run_test 118b "Reclaim dirty pages on fatal error =========="
10359
10360 test_118c()
10361 {
10362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10363
10364         # for 118c, restore the original resend count, LU-1940
10365         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10366                                 set_resend_count $OLD_RESENDCOUNT
10367         remote_ost_nodsh && skip "remote OST with nodsh"
10368
10369         reset_async
10370
10371         #define OBD_FAIL_OST_EROFS               0x216
10372         set_nodes_failloc "$(osts_nodes)" 0x216
10373
10374         # multiop should block due to fsync until pages are written
10375         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10376         MULTIPID=$!
10377         sleep 1
10378
10379         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10380                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10381         fi
10382
10383         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10384                     grep -c writeback)
10385         if [[ $WRITEBACK -eq 0 ]]; then
10386                 error "No page in writeback, writeback=$WRITEBACK"
10387         fi
10388
10389         set_nodes_failloc "$(osts_nodes)" 0
10390         wait $MULTIPID
10391         RC=$?
10392         if [[ $RC -ne 0 ]]; then
10393                 error "Multiop fsync failed, rc=$RC"
10394         fi
10395
10396         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10397         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10398                     grep -c writeback)
10399         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10400                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10401         fi
10402
10403         rm -f $DIR/$tfile
10404         echo "Dirty pages flushed via fsync on EROFS"
10405         return 0
10406 }
10407 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10408
10409 # continue to use small resend count to reduce test_118* time (b=14842)
10410 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10411
10412 test_118d()
10413 {
10414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10415         remote_ost_nodsh && skip "remote OST with nodsh"
10416
10417         reset_async
10418
10419         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10420         set_nodes_failloc "$(osts_nodes)" 0x214
10421         # multiop should block due to fsync until pages are written
10422         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10423         MULTIPID=$!
10424         sleep 1
10425
10426         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10427                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10428         fi
10429
10430         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10431                     grep -c writeback)
10432         if [[ $WRITEBACK -eq 0 ]]; then
10433                 error "No page in writeback, writeback=$WRITEBACK"
10434         fi
10435
10436         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10437         set_nodes_failloc "$(osts_nodes)" 0
10438
10439         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10440         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10441                     grep -c writeback)
10442         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10443                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10444         fi
10445
10446         rm -f $DIR/$tfile
10447         echo "Dirty pages gaurenteed flushed via fsync"
10448         return 0
10449 }
10450 run_test 118d "Fsync validation inject a delay of the bulk =========="
10451
10452 test_118f() {
10453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10454
10455         reset_async
10456
10457         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10458         lctl set_param fail_loc=0x8000040a
10459
10460         # Should simulate EINVAL error which is fatal
10461         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10462         RC=$?
10463         if [[ $RC -eq 0 ]]; then
10464                 error "Must return error due to dropped pages, rc=$RC"
10465         fi
10466
10467         lctl set_param fail_loc=0x0
10468
10469         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10470         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10471         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10472                     grep -c writeback)
10473         if [[ $LOCKED -ne 0 ]]; then
10474                 error "Locked pages remain in cache, locked=$LOCKED"
10475         fi
10476
10477         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10478                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10479         fi
10480
10481         rm -f $DIR/$tfile
10482         echo "No pages locked after fsync"
10483
10484         reset_async
10485         return 0
10486 }
10487 run_test 118f "Simulate unrecoverable OSC side error =========="
10488
10489 test_118g() {
10490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10491
10492         reset_async
10493
10494         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
10495         lctl set_param fail_loc=0x406
10496
10497         # simulate local -ENOMEM
10498         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10499         RC=$?
10500
10501         lctl set_param fail_loc=0
10502         if [[ $RC -eq 0 ]]; then
10503                 error "Must return error due to dropped pages, rc=$RC"
10504         fi
10505
10506         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10507         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10508         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10509                         grep -c writeback)
10510         if [[ $LOCKED -ne 0 ]]; then
10511                 error "Locked pages remain in cache, locked=$LOCKED"
10512         fi
10513
10514         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10515                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10516         fi
10517
10518         rm -f $DIR/$tfile
10519         echo "No pages locked after fsync"
10520
10521         reset_async
10522         return 0
10523 }
10524 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
10525
10526 test_118h() {
10527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10528         remote_ost_nodsh && skip "remote OST with nodsh"
10529
10530         reset_async
10531
10532         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10533         set_nodes_failloc "$(osts_nodes)" 0x20e
10534         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10535         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10536         RC=$?
10537
10538         set_nodes_failloc "$(osts_nodes)" 0
10539         if [[ $RC -eq 0 ]]; then
10540                 error "Must return error due to dropped pages, rc=$RC"
10541         fi
10542
10543         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10544         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10545         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10546                     grep -c writeback)
10547         if [[ $LOCKED -ne 0 ]]; then
10548                 error "Locked pages remain in cache, locked=$LOCKED"
10549         fi
10550
10551         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10552                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10553         fi
10554
10555         rm -f $DIR/$tfile
10556         echo "No pages locked after fsync"
10557
10558         return 0
10559 }
10560 run_test 118h "Verify timeout in handling recoverables errors  =========="
10561
10562 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10563
10564 test_118i() {
10565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10566         remote_ost_nodsh && skip "remote OST with nodsh"
10567
10568         reset_async
10569
10570         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10571         set_nodes_failloc "$(osts_nodes)" 0x20e
10572
10573         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10574         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10575         PID=$!
10576         sleep 5
10577         set_nodes_failloc "$(osts_nodes)" 0
10578
10579         wait $PID
10580         RC=$?
10581         if [[ $RC -ne 0 ]]; then
10582                 error "got error, but should be not, rc=$RC"
10583         fi
10584
10585         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10586         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10587         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10588         if [[ $LOCKED -ne 0 ]]; then
10589                 error "Locked pages remain in cache, locked=$LOCKED"
10590         fi
10591
10592         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10593                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10594         fi
10595
10596         rm -f $DIR/$tfile
10597         echo "No pages locked after fsync"
10598
10599         return 0
10600 }
10601 run_test 118i "Fix error before timeout in recoverable error  =========="
10602
10603 [ "$SLOW" = "no" ] && set_resend_count 4
10604
10605 test_118j() {
10606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10607         remote_ost_nodsh && skip "remote OST with nodsh"
10608
10609         reset_async
10610
10611         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10612         set_nodes_failloc "$(osts_nodes)" 0x220
10613
10614         # return -EIO from OST
10615         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10616         RC=$?
10617         set_nodes_failloc "$(osts_nodes)" 0x0
10618         if [[ $RC -eq 0 ]]; then
10619                 error "Must return error due to dropped pages, rc=$RC"
10620         fi
10621
10622         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10623         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10624         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10625         if [[ $LOCKED -ne 0 ]]; then
10626                 error "Locked pages remain in cache, locked=$LOCKED"
10627         fi
10628
10629         # in recoverable error on OST we want resend and stay until it finished
10630         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10631                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10632         fi
10633
10634         rm -f $DIR/$tfile
10635         echo "No pages locked after fsync"
10636
10637         return 0
10638 }
10639 run_test 118j "Simulate unrecoverable OST side error =========="
10640
10641 test_118k()
10642 {
10643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10644         remote_ost_nodsh && skip "remote OSTs with nodsh"
10645
10646         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10647         set_nodes_failloc "$(osts_nodes)" 0x20e
10648         test_mkdir $DIR/$tdir
10649
10650         for ((i=0;i<10;i++)); do
10651                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10652                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10653                 SLEEPPID=$!
10654                 sleep 0.500s
10655                 kill $SLEEPPID
10656                 wait $SLEEPPID
10657         done
10658
10659         set_nodes_failloc "$(osts_nodes)" 0
10660         rm -rf $DIR/$tdir
10661 }
10662 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10663
10664 test_118l() # LU-646
10665 {
10666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10667
10668         test_mkdir $DIR/$tdir
10669         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10670         rm -rf $DIR/$tdir
10671 }
10672 run_test 118l "fsync dir"
10673
10674 test_118m() # LU-3066
10675 {
10676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10677
10678         test_mkdir $DIR/$tdir
10679         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10680         rm -rf $DIR/$tdir
10681 }
10682 run_test 118m "fdatasync dir ========="
10683
10684 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10685
10686 test_118n()
10687 {
10688         local begin
10689         local end
10690
10691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10692         remote_ost_nodsh && skip "remote OSTs with nodsh"
10693
10694         # Sleep to avoid a cached response.
10695         #define OBD_STATFS_CACHE_SECONDS 1
10696         sleep 2
10697
10698         # Inject a 10 second delay in the OST_STATFS handler.
10699         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10700         set_nodes_failloc "$(osts_nodes)" 0x242
10701
10702         begin=$SECONDS
10703         stat --file-system $MOUNT > /dev/null
10704         end=$SECONDS
10705
10706         set_nodes_failloc "$(osts_nodes)" 0
10707
10708         if ((end - begin > 20)); then
10709             error "statfs took $((end - begin)) seconds, expected 10"
10710         fi
10711 }
10712 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10713
10714 test_119a() # bug 11737
10715 {
10716         BSIZE=$((512 * 1024))
10717         directio write $DIR/$tfile 0 1 $BSIZE
10718         # We ask to read two blocks, which is more than a file size.
10719         # directio will indicate an error when requested and actual
10720         # sizes aren't equeal (a normal situation in this case) and
10721         # print actual read amount.
10722         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10723         if [ "$NOB" != "$BSIZE" ]; then
10724                 error "read $NOB bytes instead of $BSIZE"
10725         fi
10726         rm -f $DIR/$tfile
10727 }
10728 run_test 119a "Short directIO read must return actual read amount"
10729
10730 test_119b() # bug 11737
10731 {
10732         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10733
10734         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
10735         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
10736         sync
10737         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
10738                 error "direct read failed"
10739         rm -f $DIR/$tfile
10740 }
10741 run_test 119b "Sparse directIO read must return actual read amount"
10742
10743 test_119c() # bug 13099
10744 {
10745         BSIZE=1048576
10746         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
10747         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
10748         rm -f $DIR/$tfile
10749 }
10750 run_test 119c "Testing for direct read hitting hole"
10751
10752 test_119d() # bug 15950
10753 {
10754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10755
10756         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
10757         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
10758         BSIZE=1048576
10759         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
10760         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
10761         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
10762         lctl set_param fail_loc=0x40d
10763         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
10764         pid_dio=$!
10765         sleep 1
10766         cat $DIR/$tfile > /dev/null &
10767         lctl set_param fail_loc=0
10768         pid_reads=$!
10769         wait $pid_dio
10770         log "the DIO writes have completed, now wait for the reads (should not block very long)"
10771         sleep 2
10772         [ -n "`ps h -p $pid_reads -o comm`" ] && \
10773         error "the read rpcs have not completed in 2s"
10774         rm -f $DIR/$tfile
10775         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
10776 }
10777 run_test 119d "The DIO path should try to send a new rpc once one is completed"
10778
10779 test_120a() {
10780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10781         remote_mds_nodsh && skip "remote MDS with nodsh"
10782         test_mkdir -i0 -c1 $DIR/$tdir
10783         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10784                 skip_env "no early lock cancel on server"
10785
10786         lru_resize_disable mdc
10787         lru_resize_disable osc
10788         cancel_lru_locks mdc
10789         # asynchronous object destroy at MDT could cause bl ast to client
10790         cancel_lru_locks osc
10791
10792         stat $DIR/$tdir > /dev/null
10793         can1=$(do_facet mds1 \
10794                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10795                awk '/ldlm_cancel/ {print $2}')
10796         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10797                awk '/ldlm_bl_callback/ {print $2}')
10798         test_mkdir -i0 -c1 $DIR/$tdir/d1
10799         can2=$(do_facet mds1 \
10800                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10801                awk '/ldlm_cancel/ {print $2}')
10802         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10803                awk '/ldlm_bl_callback/ {print $2}')
10804         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10805         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10806         lru_resize_enable mdc
10807         lru_resize_enable osc
10808 }
10809 run_test 120a "Early Lock Cancel: mkdir test"
10810
10811 test_120b() {
10812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10813         remote_mds_nodsh && skip "remote MDS with nodsh"
10814         test_mkdir $DIR/$tdir
10815         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10816                 skip_env "no early lock cancel on server"
10817
10818         lru_resize_disable mdc
10819         lru_resize_disable osc
10820         cancel_lru_locks mdc
10821         stat $DIR/$tdir > /dev/null
10822         can1=$(do_facet $SINGLEMDS \
10823                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10824                awk '/ldlm_cancel/ {print $2}')
10825         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10826                awk '/ldlm_bl_callback/ {print $2}')
10827         touch $DIR/$tdir/f1
10828         can2=$(do_facet $SINGLEMDS \
10829                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10830                awk '/ldlm_cancel/ {print $2}')
10831         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10832                awk '/ldlm_bl_callback/ {print $2}')
10833         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10834         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10835         lru_resize_enable mdc
10836         lru_resize_enable osc
10837 }
10838 run_test 120b "Early Lock Cancel: create test"
10839
10840 test_120c() {
10841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10842         remote_mds_nodsh && skip "remote MDS with nodsh"
10843         test_mkdir -i0 -c1 $DIR/$tdir
10844         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10845                 skip "no early lock cancel on server"
10846
10847         lru_resize_disable mdc
10848         lru_resize_disable osc
10849         test_mkdir -i0 -c1 $DIR/$tdir/d1
10850         test_mkdir -i0 -c1 $DIR/$tdir/d2
10851         touch $DIR/$tdir/d1/f1
10852         cancel_lru_locks mdc
10853         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
10854         can1=$(do_facet mds1 \
10855                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10856                awk '/ldlm_cancel/ {print $2}')
10857         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10858                awk '/ldlm_bl_callback/ {print $2}')
10859         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10860         can2=$(do_facet mds1 \
10861                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10862                awk '/ldlm_cancel/ {print $2}')
10863         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10864                awk '/ldlm_bl_callback/ {print $2}')
10865         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10866         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10867         lru_resize_enable mdc
10868         lru_resize_enable osc
10869 }
10870 run_test 120c "Early Lock Cancel: link test"
10871
10872 test_120d() {
10873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10874         remote_mds_nodsh && skip "remote MDS with nodsh"
10875         test_mkdir -i0 -c1 $DIR/$tdir
10876         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10877                 skip_env "no early lock cancel on server"
10878
10879         lru_resize_disable mdc
10880         lru_resize_disable osc
10881         touch $DIR/$tdir
10882         cancel_lru_locks mdc
10883         stat $DIR/$tdir > /dev/null
10884         can1=$(do_facet mds1 \
10885                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10886                awk '/ldlm_cancel/ {print $2}')
10887         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10888                awk '/ldlm_bl_callback/ {print $2}')
10889         chmod a+x $DIR/$tdir
10890         can2=$(do_facet mds1 \
10891                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10892                awk '/ldlm_cancel/ {print $2}')
10893         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10894                awk '/ldlm_bl_callback/ {print $2}')
10895         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10896         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10897         lru_resize_enable mdc
10898         lru_resize_enable osc
10899 }
10900 run_test 120d "Early Lock Cancel: setattr test"
10901
10902 test_120e() {
10903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10904         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10905                 skip_env "no early lock cancel on server"
10906         remote_mds_nodsh && skip "remote MDS with nodsh"
10907
10908         local dlmtrace_set=false
10909
10910         test_mkdir -i0 -c1 $DIR/$tdir
10911         lru_resize_disable mdc
10912         lru_resize_disable osc
10913         ! $LCTL get_param debug | grep -q dlmtrace &&
10914                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
10915         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
10916         cancel_lru_locks mdc
10917         cancel_lru_locks osc
10918         dd if=$DIR/$tdir/f1 of=/dev/null
10919         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
10920         # XXX client can not do early lock cancel of OST lock
10921         # during unlink (LU-4206), so cancel osc lock now.
10922         sleep 2
10923         cancel_lru_locks osc
10924         can1=$(do_facet mds1 \
10925                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10926                awk '/ldlm_cancel/ {print $2}')
10927         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10928                awk '/ldlm_bl_callback/ {print $2}')
10929         unlink $DIR/$tdir/f1
10930         sleep 5
10931         can2=$(do_facet mds1 \
10932                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10933                awk '/ldlm_cancel/ {print $2}')
10934         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10935                awk '/ldlm_bl_callback/ {print $2}')
10936         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
10937                 $LCTL dk $TMP/cancel.debug.txt
10938         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
10939                 $LCTL dk $TMP/blocking.debug.txt
10940         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
10941         lru_resize_enable mdc
10942         lru_resize_enable osc
10943 }
10944 run_test 120e "Early Lock Cancel: unlink test"
10945
10946 test_120f() {
10947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10948         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10949                 skip_env "no early lock cancel on server"
10950         remote_mds_nodsh && skip "remote MDS with nodsh"
10951
10952         test_mkdir -i0 -c1 $DIR/$tdir
10953         lru_resize_disable mdc
10954         lru_resize_disable osc
10955         test_mkdir -i0 -c1 $DIR/$tdir/d1
10956         test_mkdir -i0 -c1 $DIR/$tdir/d2
10957         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
10958         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
10959         cancel_lru_locks mdc
10960         cancel_lru_locks osc
10961         dd if=$DIR/$tdir/d1/f1 of=/dev/null
10962         dd if=$DIR/$tdir/d2/f2 of=/dev/null
10963         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
10964         # XXX client can not do early lock cancel of OST lock
10965         # during rename (LU-4206), so cancel osc lock now.
10966         sleep 2
10967         cancel_lru_locks osc
10968         can1=$(do_facet mds1 \
10969                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10970                awk '/ldlm_cancel/ {print $2}')
10971         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10972                awk '/ldlm_bl_callback/ {print $2}')
10973         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10974         sleep 5
10975         can2=$(do_facet mds1 \
10976                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10977                awk '/ldlm_cancel/ {print $2}')
10978         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10979                awk '/ldlm_bl_callback/ {print $2}')
10980         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10981         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10982         lru_resize_enable mdc
10983         lru_resize_enable osc
10984 }
10985 run_test 120f "Early Lock Cancel: rename test"
10986
10987 test_120g() {
10988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10989         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10990                 skip_env "no early lock cancel on server"
10991         remote_mds_nodsh && skip "remote MDS with nodsh"
10992
10993         lru_resize_disable mdc
10994         lru_resize_disable osc
10995         count=10000
10996         echo create $count files
10997         test_mkdir $DIR/$tdir
10998         cancel_lru_locks mdc
10999         cancel_lru_locks osc
11000         t0=$(date +%s)
11001
11002         can0=$(do_facet $SINGLEMDS \
11003                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11004                awk '/ldlm_cancel/ {print $2}')
11005         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11006                awk '/ldlm_bl_callback/ {print $2}')
11007         createmany -o $DIR/$tdir/f $count
11008         sync
11009         can1=$(do_facet $SINGLEMDS \
11010                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11011                awk '/ldlm_cancel/ {print $2}')
11012         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11013                awk '/ldlm_bl_callback/ {print $2}')
11014         t1=$(date +%s)
11015         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11016         echo rm $count files
11017         rm -r $DIR/$tdir
11018         sync
11019         can2=$(do_facet $SINGLEMDS \
11020                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11021                awk '/ldlm_cancel/ {print $2}')
11022         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11023                awk '/ldlm_bl_callback/ {print $2}')
11024         t2=$(date +%s)
11025         echo total: $count removes in $((t2-t1))
11026         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11027         sleep 2
11028         # wait for commitment of removal
11029         lru_resize_enable mdc
11030         lru_resize_enable osc
11031 }
11032 run_test 120g "Early Lock Cancel: performance test"
11033
11034 test_121() { #bug #10589
11035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11036
11037         rm -rf $DIR/$tfile
11038         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11039 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11040         lctl set_param fail_loc=0x310
11041         cancel_lru_locks osc > /dev/null
11042         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11043         lctl set_param fail_loc=0
11044         [[ $reads -eq $writes ]] ||
11045                 error "read $reads blocks, must be $writes blocks"
11046 }
11047 run_test 121 "read cancel race ========="
11048
11049 test_123a() { # was test 123, statahead(bug 11401)
11050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11051
11052         SLOWOK=0
11053         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11054                 log "testing UP system. Performance may be lower than expected."
11055                 SLOWOK=1
11056         fi
11057
11058         rm -rf $DIR/$tdir
11059         test_mkdir $DIR/$tdir
11060         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11061         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11062         MULT=10
11063         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11064                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11065
11066                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
11067                 lctl set_param -n llite.*.statahead_max 0
11068                 lctl get_param llite.*.statahead_max
11069                 cancel_lru_locks mdc
11070                 cancel_lru_locks osc
11071                 stime=`date +%s`
11072                 time ls -l $DIR/$tdir | wc -l
11073                 etime=`date +%s`
11074                 delta=$((etime - stime))
11075                 log "ls $i files without statahead: $delta sec"
11076                 lctl set_param llite.*.statahead_max=$max
11077
11078                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
11079                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11080                 cancel_lru_locks mdc
11081                 cancel_lru_locks osc
11082                 stime=`date +%s`
11083                 time ls -l $DIR/$tdir | wc -l
11084                 etime=`date +%s`
11085                 delta_sa=$((etime - stime))
11086                 log "ls $i files with statahead: $delta_sa sec"
11087                 lctl get_param -n llite.*.statahead_stats
11088                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
11089
11090                 [[ $swrong -lt $ewrong ]] &&
11091                         log "statahead was stopped, maybe too many locks held!"
11092                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11093
11094                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11095                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
11096                     lctl set_param -n llite.*.statahead_max 0
11097                     lctl get_param llite.*.statahead_max
11098                     cancel_lru_locks mdc
11099                     cancel_lru_locks osc
11100                     stime=`date +%s`
11101                     time ls -l $DIR/$tdir | wc -l
11102                     etime=`date +%s`
11103                     delta=$((etime - stime))
11104                     log "ls $i files again without statahead: $delta sec"
11105                     lctl set_param llite.*.statahead_max=$max
11106                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11107                         if [  $SLOWOK -eq 0 ]; then
11108                                 error "ls $i files is slower with statahead!"
11109                         else
11110                                 log "ls $i files is slower with statahead!"
11111                         fi
11112                         break
11113                     fi
11114                 fi
11115
11116                 [ $delta -gt 20 ] && break
11117                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11118                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11119         done
11120         log "ls done"
11121
11122         stime=`date +%s`
11123         rm -r $DIR/$tdir
11124         sync
11125         etime=`date +%s`
11126         delta=$((etime - stime))
11127         log "rm -r $DIR/$tdir/: $delta seconds"
11128         log "rm done"
11129         lctl get_param -n llite.*.statahead_stats
11130 }
11131 run_test 123a "verify statahead work"
11132
11133 test_123b () { # statahead(bug 15027)
11134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11135
11136         test_mkdir $DIR/$tdir
11137         createmany -o $DIR/$tdir/$tfile-%d 1000
11138
11139         cancel_lru_locks mdc
11140         cancel_lru_locks osc
11141
11142 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11143         lctl set_param fail_loc=0x80000803
11144         ls -lR $DIR/$tdir > /dev/null
11145         log "ls done"
11146         lctl set_param fail_loc=0x0
11147         lctl get_param -n llite.*.statahead_stats
11148         rm -r $DIR/$tdir
11149         sync
11150
11151 }
11152 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11153
11154 test_124a() {
11155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11156         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11157                 skip_env "no lru resize on server"
11158
11159         local NR=2000
11160
11161         test_mkdir $DIR/$tdir
11162
11163         log "create $NR files at $DIR/$tdir"
11164         createmany -o $DIR/$tdir/f $NR ||
11165                 error "failed to create $NR files in $DIR/$tdir"
11166
11167         cancel_lru_locks mdc
11168         ls -l $DIR/$tdir > /dev/null
11169
11170         local NSDIR=""
11171         local LRU_SIZE=0
11172         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11173                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11174                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11175                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11176                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11177                         log "NSDIR=$NSDIR"
11178                         log "NS=$(basename $NSDIR)"
11179                         break
11180                 fi
11181         done
11182
11183         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11184                 skip "Not enough cached locks created!"
11185         fi
11186         log "LRU=$LRU_SIZE"
11187
11188         local SLEEP=30
11189
11190         # We know that lru resize allows one client to hold $LIMIT locks
11191         # for 10h. After that locks begin to be killed by client.
11192         local MAX_HRS=10
11193         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11194         log "LIMIT=$LIMIT"
11195         if [ $LIMIT -lt $LRU_SIZE ]; then
11196                 skip "Limit is too small $LIMIT"
11197         fi
11198
11199         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11200         # killing locks. Some time was spent for creating locks. This means
11201         # that up to the moment of sleep finish we must have killed some of
11202         # them (10-100 locks). This depends on how fast ther were created.
11203         # Many of them were touched in almost the same moment and thus will
11204         # be killed in groups.
11205         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11206
11207         # Use $LRU_SIZE_B here to take into account real number of locks
11208         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11209         local LRU_SIZE_B=$LRU_SIZE
11210         log "LVF=$LVF"
11211         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11212         log "OLD_LVF=$OLD_LVF"
11213         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11214
11215         # Let's make sure that we really have some margin. Client checks
11216         # cached locks every 10 sec.
11217         SLEEP=$((SLEEP+20))
11218         log "Sleep ${SLEEP} sec"
11219         local SEC=0
11220         while ((SEC<$SLEEP)); do
11221                 echo -n "..."
11222                 sleep 5
11223                 SEC=$((SEC+5))
11224                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11225                 echo -n "$LRU_SIZE"
11226         done
11227         echo ""
11228         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11229         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11230
11231         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11232                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11233                 unlinkmany $DIR/$tdir/f $NR
11234                 return
11235         }
11236
11237         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11238         log "unlink $NR files at $DIR/$tdir"
11239         unlinkmany $DIR/$tdir/f $NR
11240 }
11241 run_test 124a "lru resize ======================================="
11242
11243 get_max_pool_limit()
11244 {
11245         local limit=$($LCTL get_param \
11246                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11247         local max=0
11248         for l in $limit; do
11249                 if [[ $l -gt $max ]]; then
11250                         max=$l
11251                 fi
11252         done
11253         echo $max
11254 }
11255
11256 test_124b() {
11257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11258         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11259                 skip_env "no lru resize on server"
11260
11261         LIMIT=$(get_max_pool_limit)
11262
11263         NR=$(($(default_lru_size)*20))
11264         if [[ $NR -gt $LIMIT ]]; then
11265                 log "Limit lock number by $LIMIT locks"
11266                 NR=$LIMIT
11267         fi
11268
11269         IFree=$(mdsrate_inodes_available)
11270         if [ $IFree -lt $NR ]; then
11271                 log "Limit lock number by $IFree inodes"
11272                 NR=$IFree
11273         fi
11274
11275         lru_resize_disable mdc
11276         test_mkdir -p $DIR/$tdir/disable_lru_resize
11277
11278         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11279         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11280         cancel_lru_locks mdc
11281         stime=`date +%s`
11282         PID=""
11283         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11284         PID="$PID $!"
11285         sleep 2
11286         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11287         PID="$PID $!"
11288         sleep 2
11289         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11290         PID="$PID $!"
11291         wait $PID
11292         etime=`date +%s`
11293         nolruresize_delta=$((etime-stime))
11294         log "ls -la time: $nolruresize_delta seconds"
11295         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11296         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11297
11298         lru_resize_enable mdc
11299         test_mkdir -p $DIR/$tdir/enable_lru_resize
11300
11301         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11302         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11303         cancel_lru_locks mdc
11304         stime=`date +%s`
11305         PID=""
11306         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11307         PID="$PID $!"
11308         sleep 2
11309         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11310         PID="$PID $!"
11311         sleep 2
11312         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11313         PID="$PID $!"
11314         wait $PID
11315         etime=`date +%s`
11316         lruresize_delta=$((etime-stime))
11317         log "ls -la time: $lruresize_delta seconds"
11318         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11319
11320         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11321                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11322         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11323                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11324         else
11325                 log "lru resize performs the same with no lru resize"
11326         fi
11327         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11328 }
11329 run_test 124b "lru resize (performance test) ======================="
11330
11331 test_124c() {
11332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11333         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11334                 skip_env "no lru resize on server"
11335
11336         # cache ununsed locks on client
11337         local nr=100
11338         cancel_lru_locks mdc
11339         test_mkdir $DIR/$tdir
11340         createmany -o $DIR/$tdir/f $nr ||
11341                 error "failed to create $nr files in $DIR/$tdir"
11342         ls -l $DIR/$tdir > /dev/null
11343
11344         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11345         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11346         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11347         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11348         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11349
11350         # set lru_max_age to 1 sec
11351         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11352         echo "sleep $((recalc_p * 2)) seconds..."
11353         sleep $((recalc_p * 2))
11354
11355         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11356         # restore lru_max_age
11357         $LCTL set_param -n $nsdir.lru_max_age $max_age
11358         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11359         unlinkmany $DIR/$tdir/f $nr
11360 }
11361 run_test 124c "LRUR cancel very aged locks"
11362
11363 test_124d() {
11364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11365         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11366                 skip_env "no lru resize on server"
11367
11368         # cache ununsed locks on client
11369         local nr=100
11370
11371         lru_resize_disable mdc
11372         stack_trap "lru_resize_enable mdc" EXIT
11373
11374         cancel_lru_locks mdc
11375
11376         # asynchronous object destroy at MDT could cause bl ast to client
11377         test_mkdir $DIR/$tdir
11378         createmany -o $DIR/$tdir/f $nr ||
11379                 error "failed to create $nr files in $DIR/$tdir"
11380         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11381
11382         ls -l $DIR/$tdir > /dev/null
11383
11384         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11385         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11386         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11387         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11388
11389         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11390
11391         # set lru_max_age to 1 sec
11392         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11393         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
11394
11395         echo "sleep $((recalc_p * 2)) seconds..."
11396         sleep $((recalc_p * 2))
11397
11398         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11399
11400         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11401 }
11402 run_test 124d "cancel very aged locks if lru-resize diasbaled"
11403
11404 test_125() { # 13358
11405         $LCTL get_param -n llite.*.client_type | grep -q local ||
11406                 skip "must run as local client"
11407         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
11408                 skip_env "must have acl enabled"
11409         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11410
11411         test_mkdir $DIR/$tdir
11412         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
11413         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
11414         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
11415 }
11416 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
11417
11418 test_126() { # bug 12829/13455
11419         $GSS && skip_env "must run as gss disabled"
11420         $LCTL get_param -n llite.*.client_type | grep -q local ||
11421                 skip "must run as local client"
11422         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
11423
11424         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
11425         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
11426         rm -f $DIR/$tfile
11427         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
11428 }
11429 run_test 126 "check that the fsgid provided by the client is taken into account"
11430
11431 test_127a() { # bug 15521
11432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11433         local name count samp unit min max sum sumsq
11434
11435         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
11436         echo "stats before reset"
11437         $LCTL get_param osc.*.stats
11438         $LCTL set_param osc.*.stats=0
11439         local fsize=$((2048 * 1024))
11440
11441         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
11442         cancel_lru_locks osc
11443         dd if=$DIR/$tfile of=/dev/null bs=$fsize
11444
11445         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
11446         stack_trap "rm -f $TMP/$tfile.tmp"
11447         while read name count samp unit min max sum sumsq; do
11448                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
11449                 [ ! $min ] && error "Missing min value for $name proc entry"
11450                 eval $name=$count || error "Wrong proc format"
11451
11452                 case $name in
11453                 read_bytes|write_bytes)
11454                         [[ "$unit" =~ "bytes" ]] ||
11455                                 error "unit is not 'bytes': $unit"
11456                         (( $min >= 4096 )) || error "min is too small: $min"
11457                         (( $min <= $fsize )) || error "min is too big: $min"
11458                         (( $max >= 4096 )) || error "max is too small: $max"
11459                         (( $max <= $fsize )) || error "max is too big: $max"
11460                         (( $sum == $fsize )) || error "sum is wrong: $sum"
11461                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
11462                                 error "sumsquare is too small: $sumsq"
11463                         (( $sumsq <= $fsize * $fsize )) ||
11464                                 error "sumsquare is too big: $sumsq"
11465                         ;;
11466                 ost_read|ost_write)
11467                         [[ "$unit" =~ "usec" ]] ||
11468                                 error "unit is not 'usec': $unit"
11469                         ;;
11470                 *)      ;;
11471                 esac
11472         done < $DIR/$tfile.tmp
11473
11474         #check that we actually got some stats
11475         [ "$read_bytes" ] || error "Missing read_bytes stats"
11476         [ "$write_bytes" ] || error "Missing write_bytes stats"
11477         [ "$read_bytes" != 0 ] || error "no read done"
11478         [ "$write_bytes" != 0 ] || error "no write done"
11479 }
11480 run_test 127a "verify the client stats are sane"
11481
11482 test_127b() { # bug LU-333
11483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11484         local name count samp unit min max sum sumsq
11485
11486         echo "stats before reset"
11487         $LCTL get_param llite.*.stats
11488         $LCTL set_param llite.*.stats=0
11489
11490         # perform 2 reads and writes so MAX is different from SUM.
11491         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11492         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11493         cancel_lru_locks osc
11494         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11495         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11496
11497         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
11498         stack_trap "rm -f $TMP/$tfile.tmp"
11499         while read name count samp unit min max sum sumsq; do
11500                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
11501                 eval $name=$count || error "Wrong proc format"
11502
11503                 case $name in
11504                 read_bytes|write_bytes)
11505                         [[ "$unit" =~ "bytes" ]] ||
11506                                 error "unit is not 'bytes': $unit"
11507                         (( $count == 2 )) || error "count is not 2: $count"
11508                         (( $min == $PAGE_SIZE )) ||
11509                                 error "min is not $PAGE_SIZE: $min"
11510                         (( $max == $PAGE_SIZE )) ||
11511                                 error "max is not $PAGE_SIZE: $max"
11512                         (( $sum == $PAGE_SIZE * 2 )) ||
11513                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
11514                         ;;
11515                 read|write)
11516                         [[ "$unit" =~ "usec" ]] ||
11517                                 error "unit is not 'usec': $unit"
11518                         ;;
11519                 *)      ;;
11520                 esac
11521         done < $TMP/$tfile.tmp
11522
11523         #check that we actually got some stats
11524         [ "$read_bytes" ] || error "Missing read_bytes stats"
11525         [ "$write_bytes" ] || error "Missing write_bytes stats"
11526         [ "$read_bytes" != 0 ] || error "no read done"
11527         [ "$write_bytes" != 0 ] || error "no write done"
11528 }
11529 run_test 127b "verify the llite client stats are sane"
11530
11531 test_127c() { # LU-12394
11532         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11533         local size
11534         local bsize
11535         local reads
11536         local writes
11537         local count
11538
11539         $LCTL set_param llite.*.extents_stats=1
11540         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
11541
11542         # Use two stripes so there is enough space in default config
11543         $LFS setstripe -c 2 $DIR/$tfile
11544
11545         # Extent stats start at 0-4K and go in power of two buckets
11546         # LL_HIST_START = 12 --> 2^12 = 4K
11547         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
11548         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
11549         # small configs
11550         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
11551                 do
11552                 # Write and read, 2x each, second time at a non-zero offset
11553                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
11554                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
11555                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
11556                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
11557                 rm -f $DIR/$tfile
11558         done
11559
11560         $LCTL get_param llite.*.extents_stats
11561
11562         count=2
11563         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
11564                 do
11565                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
11566                                 grep -m 1 $bsize)
11567                 reads=$(echo $bucket | awk '{print $5}')
11568                 writes=$(echo $bucket | awk '{print $9}')
11569                 [ "$reads" -eq $count ] ||
11570                         error "$reads reads in < $bsize bucket, expect $count"
11571                 [ "$writes" -eq $count ] ||
11572                         error "$writes writes in < $bsize bucket, expect $count"
11573         done
11574
11575         # Test mmap write and read
11576         $LCTL set_param llite.*.extents_stats=c
11577         size=512
11578         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
11579         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
11580         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
11581
11582         $LCTL get_param llite.*.extents_stats
11583
11584         count=$(((size*1024) / PAGE_SIZE))
11585
11586         bsize=$((2 * PAGE_SIZE / 1024))K
11587
11588         bucket=$($LCTL get_param -n llite.*.extents_stats |
11589                         grep -m 1 $bsize)
11590         reads=$(echo $bucket | awk '{print $5}')
11591         writes=$(echo $bucket | awk '{print $9}')
11592         # mmap writes fault in the page first, creating an additonal read
11593         [ "$reads" -eq $((2 * count)) ] ||
11594                 error "$reads reads in < $bsize bucket, expect $count"
11595         [ "$writes" -eq $count ] ||
11596                 error "$writes writes in < $bsize bucket, expect $count"
11597 }
11598 run_test 127c "test llite extent stats with regular & mmap i/o"
11599
11600 test_128() { # bug 15212
11601         touch $DIR/$tfile
11602         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
11603                 find $DIR/$tfile
11604                 find $DIR/$tfile
11605         EOF
11606
11607         result=$(grep error $TMP/$tfile.log)
11608         rm -f $DIR/$tfile $TMP/$tfile.log
11609         [ -z "$result" ] ||
11610                 error "consecutive find's under interactive lfs failed"
11611 }
11612 run_test 128 "interactive lfs for 2 consecutive find's"
11613
11614 set_dir_limits () {
11615         local mntdev
11616         local canondev
11617         local node
11618
11619         local ldproc=/proc/fs/ldiskfs
11620         local facets=$(get_facets MDS)
11621
11622         for facet in ${facets//,/ }; do
11623                 canondev=$(ldiskfs_canon \
11624                            *.$(convert_facet2label $facet).mntdev $facet)
11625                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
11626                         ldproc=/sys/fs/ldiskfs
11627                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
11628                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
11629         done
11630 }
11631
11632 check_mds_dmesg() {
11633         local facets=$(get_facets MDS)
11634         for facet in ${facets//,/ }; do
11635                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
11636         done
11637         return 1
11638 }
11639
11640 test_129() {
11641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11642         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
11643                 skip "Need MDS version with at least 2.5.56"
11644         if [ "$mds1_FSTYPE" != ldiskfs ]; then
11645                 skip_env "ldiskfs only test"
11646         fi
11647         remote_mds_nodsh && skip "remote MDS with nodsh"
11648
11649         local ENOSPC=28
11650         local EFBIG=27
11651         local has_warning=false
11652
11653         rm -rf $DIR/$tdir
11654         mkdir -p $DIR/$tdir
11655
11656         # block size of mds1
11657         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
11658         set_dir_limits $maxsize $maxsize
11659         local dirsize=$(stat -c%s "$DIR/$tdir")
11660         local nfiles=0
11661         while [[ $dirsize -le $maxsize ]]; do
11662                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
11663                 rc=$?
11664                 if ! $has_warning; then
11665                         check_mds_dmesg '"is approaching"' && has_warning=true
11666                 fi
11667                 # check two errors:
11668                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11669                 # EFBIG for previous versions included in ldiskfs series
11670                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11671                         set_dir_limits 0 0
11672                         echo "return code $rc received as expected"
11673
11674                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11675                                 error_exit "create failed w/o dir size limit"
11676
11677                         check_mds_dmesg '"has reached"' ||
11678                                 error_exit "reached message should be output"
11679
11680                         [ $has_warning = "false" ] &&
11681                                 error_exit "warning message should be output"
11682
11683                         dirsize=$(stat -c%s "$DIR/$tdir")
11684
11685                         [[ $dirsize -ge $maxsize ]] && return 0
11686                         error_exit "current dir size $dirsize, " \
11687                                    "previous limit $maxsize"
11688                 elif [ $rc -ne 0 ]; then
11689                         set_dir_limits 0 0
11690                         error_exit "return $rc received instead of expected " \
11691                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11692                 fi
11693                 nfiles=$((nfiles + 1))
11694                 dirsize=$(stat -c%s "$DIR/$tdir")
11695         done
11696
11697         set_dir_limits 0 0
11698         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11699 }
11700 run_test 129 "test directory size limit ========================"
11701
11702 OLDIFS="$IFS"
11703 cleanup_130() {
11704         trap 0
11705         IFS="$OLDIFS"
11706 }
11707
11708 test_130a() {
11709         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11710         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11711
11712         trap cleanup_130 EXIT RETURN
11713
11714         local fm_file=$DIR/$tfile
11715         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
11716         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
11717                 error "dd failed for $fm_file"
11718
11719         # LU-1795: test filefrag/FIEMAP once, even if unsupported
11720         filefrag -ves $fm_file
11721         RC=$?
11722         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11723                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11724         [ $RC != 0 ] && error "filefrag $fm_file failed"
11725
11726         filefrag_op=$(filefrag -ve -k $fm_file |
11727                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11728         lun=$($LFS getstripe -i $fm_file)
11729
11730         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
11731         IFS=$'\n'
11732         tot_len=0
11733         for line in $filefrag_op
11734         do
11735                 frag_lun=`echo $line | cut -d: -f5`
11736                 ext_len=`echo $line | cut -d: -f4`
11737                 if (( $frag_lun != $lun )); then
11738                         cleanup_130
11739                         error "FIEMAP on 1-stripe file($fm_file) failed"
11740                         return
11741                 fi
11742                 (( tot_len += ext_len ))
11743         done
11744
11745         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
11746                 cleanup_130
11747                 error "FIEMAP on 1-stripe file($fm_file) failed;"
11748                 return
11749         fi
11750
11751         cleanup_130
11752
11753         echo "FIEMAP on single striped file succeeded"
11754 }
11755 run_test 130a "FIEMAP (1-stripe file)"
11756
11757 test_130b() {
11758         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11759
11760         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11761         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11762
11763         trap cleanup_130 EXIT RETURN
11764
11765         local fm_file=$DIR/$tfile
11766         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11767                         error "setstripe on $fm_file"
11768         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11769                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11770
11771         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
11772                 error "dd failed on $fm_file"
11773
11774         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11775         filefrag_op=$(filefrag -ve -k $fm_file |
11776                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11777
11778         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11779                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11780
11781         IFS=$'\n'
11782         tot_len=0
11783         num_luns=1
11784         for line in $filefrag_op
11785         do
11786                 frag_lun=$(echo $line | cut -d: -f5 |
11787                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11788                 ext_len=$(echo $line | cut -d: -f4)
11789                 if (( $frag_lun != $last_lun )); then
11790                         if (( tot_len != 1024 )); then
11791                                 cleanup_130
11792                                 error "FIEMAP on $fm_file failed; returned " \
11793                                 "len $tot_len for OST $last_lun instead of 1024"
11794                                 return
11795                         else
11796                                 (( num_luns += 1 ))
11797                                 tot_len=0
11798                         fi
11799                 fi
11800                 (( tot_len += ext_len ))
11801                 last_lun=$frag_lun
11802         done
11803         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
11804                 cleanup_130
11805                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11806                         "luns or wrong len for OST $last_lun"
11807                 return
11808         fi
11809
11810         cleanup_130
11811
11812         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
11813 }
11814 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
11815
11816 test_130c() {
11817         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11818
11819         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11820         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11821
11822         trap cleanup_130 EXIT RETURN
11823
11824         local fm_file=$DIR/$tfile
11825         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
11826         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11827                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11828
11829         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
11830                         error "dd failed on $fm_file"
11831
11832         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11833         filefrag_op=$(filefrag -ve -k $fm_file |
11834                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11835
11836         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11837                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11838
11839         IFS=$'\n'
11840         tot_len=0
11841         num_luns=1
11842         for line in $filefrag_op
11843         do
11844                 frag_lun=$(echo $line | cut -d: -f5 |
11845                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11846                 ext_len=$(echo $line | cut -d: -f4)
11847                 if (( $frag_lun != $last_lun )); then
11848                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
11849                         if (( logical != 512 )); then
11850                                 cleanup_130
11851                                 error "FIEMAP on $fm_file failed; returned " \
11852                                 "logical start for lun $logical instead of 512"
11853                                 return
11854                         fi
11855                         if (( tot_len != 512 )); then
11856                                 cleanup_130
11857                                 error "FIEMAP on $fm_file failed; returned " \
11858                                 "len $tot_len for OST $last_lun instead of 1024"
11859                                 return
11860                         else
11861                                 (( num_luns += 1 ))
11862                                 tot_len=0
11863                         fi
11864                 fi
11865                 (( tot_len += ext_len ))
11866                 last_lun=$frag_lun
11867         done
11868         if (( num_luns != 2 || tot_len != 512 )); then
11869                 cleanup_130
11870                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11871                         "luns or wrong len for OST $last_lun"
11872                 return
11873         fi
11874
11875         cleanup_130
11876
11877         echo "FIEMAP on 2-stripe file with hole succeeded"
11878 }
11879 run_test 130c "FIEMAP (2-stripe file with hole)"
11880
11881 test_130d() {
11882         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
11883
11884         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11885         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11886
11887         trap cleanup_130 EXIT RETURN
11888
11889         local fm_file=$DIR/$tfile
11890         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11891                         error "setstripe on $fm_file"
11892         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11893                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11894
11895         local actual_stripe_count=$($LFS getstripe -c $fm_file)
11896         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
11897                 error "dd failed on $fm_file"
11898
11899         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11900         filefrag_op=$(filefrag -ve -k $fm_file |
11901                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11902
11903         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11904                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11905
11906         IFS=$'\n'
11907         tot_len=0
11908         num_luns=1
11909         for line in $filefrag_op
11910         do
11911                 frag_lun=$(echo $line | cut -d: -f5 |
11912                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11913                 ext_len=$(echo $line | cut -d: -f4)
11914                 if (( $frag_lun != $last_lun )); then
11915                         if (( tot_len != 1024 )); then
11916                                 cleanup_130
11917                                 error "FIEMAP on $fm_file failed; returned " \
11918                                 "len $tot_len for OST $last_lun instead of 1024"
11919                                 return
11920                         else
11921                                 (( num_luns += 1 ))
11922                                 tot_len=0
11923                         fi
11924                 fi
11925                 (( tot_len += ext_len ))
11926                 last_lun=$frag_lun
11927         done
11928         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
11929                 cleanup_130
11930                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11931                         "luns or wrong len for OST $last_lun"
11932                 return
11933         fi
11934
11935         cleanup_130
11936
11937         echo "FIEMAP on N-stripe file succeeded"
11938 }
11939 run_test 130d "FIEMAP (N-stripe file)"
11940
11941 test_130e() {
11942         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11943
11944         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11945         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11946
11947         trap cleanup_130 EXIT RETURN
11948
11949         local fm_file=$DIR/$tfile
11950         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
11951         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11952                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11953
11954         NUM_BLKS=512
11955         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
11956         for ((i = 0; i < $NUM_BLKS; i++))
11957         do
11958                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
11959         done
11960
11961         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11962         filefrag_op=$(filefrag -ve -k $fm_file |
11963                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11964
11965         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11966                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11967
11968         IFS=$'\n'
11969         tot_len=0
11970         num_luns=1
11971         for line in $filefrag_op
11972         do
11973                 frag_lun=$(echo $line | cut -d: -f5 |
11974                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11975                 ext_len=$(echo $line | cut -d: -f4)
11976                 if (( $frag_lun != $last_lun )); then
11977                         if (( tot_len != $EXPECTED_LEN )); then
11978                                 cleanup_130
11979                                 error "FIEMAP on $fm_file failed; returned " \
11980                                 "len $tot_len for OST $last_lun instead " \
11981                                 "of $EXPECTED_LEN"
11982                                 return
11983                         else
11984                                 (( num_luns += 1 ))
11985                                 tot_len=0
11986                         fi
11987                 fi
11988                 (( tot_len += ext_len ))
11989                 last_lun=$frag_lun
11990         done
11991         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
11992                 cleanup_130
11993                 error "FIEMAP on $fm_file failed; returned wrong number " \
11994                         "of luns or wrong len for OST $last_lun"
11995                 return
11996         fi
11997
11998         cleanup_130
11999
12000         echo "FIEMAP with continuation calls succeeded"
12001 }
12002 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12003
12004 test_130f() {
12005         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12006         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12007
12008         local fm_file=$DIR/$tfile
12009         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12010                 error "multiop create with lov_delay_create on $fm_file"
12011
12012         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12013         filefrag_extents=$(filefrag -vek $fm_file |
12014                            awk '/extents? found/ { print $2 }')
12015         if [[ "$filefrag_extents" != "0" ]]; then
12016                 error "FIEMAP on $fm_file failed; " \
12017                       "returned $filefrag_extents expected 0"
12018         fi
12019
12020         rm -f $fm_file
12021 }
12022 run_test 130f "FIEMAP (unstriped file)"
12023
12024 # Test for writev/readv
12025 test_131a() {
12026         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12027                 error "writev test failed"
12028         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12029                 error "readv failed"
12030         rm -f $DIR/$tfile
12031 }
12032 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12033
12034 test_131b() {
12035         local fsize=$((524288 + 1048576 + 1572864))
12036         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12037                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12038                         error "append writev test failed"
12039
12040         ((fsize += 1572864 + 1048576))
12041         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12042                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12043                         error "append writev test failed"
12044         rm -f $DIR/$tfile
12045 }
12046 run_test 131b "test append writev"
12047
12048 test_131c() {
12049         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12050         error "NOT PASS"
12051 }
12052 run_test 131c "test read/write on file w/o objects"
12053
12054 test_131d() {
12055         rwv -f $DIR/$tfile -w -n 1 1572864
12056         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12057         if [ "$NOB" != 1572864 ]; then
12058                 error "Short read filed: read $NOB bytes instead of 1572864"
12059         fi
12060         rm -f $DIR/$tfile
12061 }
12062 run_test 131d "test short read"
12063
12064 test_131e() {
12065         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12066         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12067         error "read hitting hole failed"
12068         rm -f $DIR/$tfile
12069 }
12070 run_test 131e "test read hitting hole"
12071
12072 check_stats() {
12073         local facet=$1
12074         local op=$2
12075         local want=${3:-0}
12076         local res
12077
12078         case $facet in
12079         mds*) res=$(do_facet $facet \
12080                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12081                  ;;
12082         ost*) res=$(do_facet $facet \
12083                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12084                  ;;
12085         *) error "Wrong facet '$facet'" ;;
12086         esac
12087         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12088         # if the argument $3 is zero, it means any stat increment is ok.
12089         if [[ $want -gt 0 ]]; then
12090                 local count=$(echo $res | awk '{ print $2 }')
12091                 [[ $count -ne $want ]] &&
12092                         error "The $op counter on $facet is $count, not $want"
12093         fi
12094 }
12095
12096 test_133a() {
12097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12098         remote_ost_nodsh && skip "remote OST with nodsh"
12099         remote_mds_nodsh && skip "remote MDS with nodsh"
12100         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12101                 skip_env "MDS doesn't support rename stats"
12102
12103         local testdir=$DIR/${tdir}/stats_testdir
12104
12105         mkdir -p $DIR/${tdir}
12106
12107         # clear stats.
12108         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12109         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12110
12111         # verify mdt stats first.
12112         mkdir ${testdir} || error "mkdir failed"
12113         check_stats $SINGLEMDS "mkdir" 1
12114         touch ${testdir}/${tfile} || error "touch failed"
12115         check_stats $SINGLEMDS "open" 1
12116         check_stats $SINGLEMDS "close" 1
12117         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12118                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12119                 check_stats $SINGLEMDS "mknod" 2
12120         }
12121         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12122         check_stats $SINGLEMDS "unlink" 1
12123         rm -f ${testdir}/${tfile} || error "file remove failed"
12124         check_stats $SINGLEMDS "unlink" 2
12125
12126         # remove working dir and check mdt stats again.
12127         rmdir ${testdir} || error "rmdir failed"
12128         check_stats $SINGLEMDS "rmdir" 1
12129
12130         local testdir1=$DIR/${tdir}/stats_testdir1
12131         mkdir -p ${testdir}
12132         mkdir -p ${testdir1}
12133         touch ${testdir1}/test1
12134         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12135         check_stats $SINGLEMDS "crossdir_rename" 1
12136
12137         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12138         check_stats $SINGLEMDS "samedir_rename" 1
12139
12140         rm -rf $DIR/${tdir}
12141 }
12142 run_test 133a "Verifying MDT stats ========================================"
12143
12144 test_133b() {
12145         local res
12146
12147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12148         remote_ost_nodsh && skip "remote OST with nodsh"
12149         remote_mds_nodsh && skip "remote MDS with nodsh"
12150
12151         local testdir=$DIR/${tdir}/stats_testdir
12152
12153         mkdir -p ${testdir} || error "mkdir failed"
12154         touch ${testdir}/${tfile} || error "touch failed"
12155         cancel_lru_locks mdc
12156
12157         # clear stats.
12158         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12159         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12160
12161         # extra mdt stats verification.
12162         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12163         check_stats $SINGLEMDS "setattr" 1
12164         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12165         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12166         then            # LU-1740
12167                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12168                 check_stats $SINGLEMDS "getattr" 1
12169         fi
12170         rm -rf $DIR/${tdir}
12171
12172         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12173         # so the check below is not reliable
12174         [ $MDSCOUNT -eq 1 ] || return 0
12175
12176         # Sleep to avoid a cached response.
12177         #define OBD_STATFS_CACHE_SECONDS 1
12178         sleep 2
12179         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12180         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12181         $LFS df || error "lfs failed"
12182         check_stats $SINGLEMDS "statfs" 1
12183
12184         # check aggregated statfs (LU-10018)
12185         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12186                 return 0
12187         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12188                 return 0
12189         sleep 2
12190         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12191         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12192         df $DIR
12193         check_stats $SINGLEMDS "statfs" 1
12194
12195         # We want to check that the client didn't send OST_STATFS to
12196         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12197         # extra care is needed here.
12198         if remote_mds; then
12199                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12200                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12201
12202                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12203                 [ "$res" ] && error "OST got STATFS"
12204         fi
12205
12206         return 0
12207 }
12208 run_test 133b "Verifying extra MDT stats =================================="
12209
12210 test_133c() {
12211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12212         remote_ost_nodsh && skip "remote OST with nodsh"
12213         remote_mds_nodsh && skip "remote MDS with nodsh"
12214
12215         local testdir=$DIR/$tdir/stats_testdir
12216
12217         test_mkdir -p $testdir
12218
12219         # verify obdfilter stats.
12220         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12221         sync
12222         cancel_lru_locks osc
12223         wait_delete_completed
12224
12225         # clear stats.
12226         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12227         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12228
12229         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12230                 error "dd failed"
12231         sync
12232         cancel_lru_locks osc
12233         check_stats ost1 "write" 1
12234
12235         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12236         check_stats ost1 "read" 1
12237
12238         > $testdir/$tfile || error "truncate failed"
12239         check_stats ost1 "punch" 1
12240
12241         rm -f $testdir/$tfile || error "file remove failed"
12242         wait_delete_completed
12243         check_stats ost1 "destroy" 1
12244
12245         rm -rf $DIR/$tdir
12246 }
12247 run_test 133c "Verifying OST stats ========================================"
12248
12249 order_2() {
12250         local value=$1
12251         local orig=$value
12252         local order=1
12253
12254         while [ $value -ge 2 ]; do
12255                 order=$((order*2))
12256                 value=$((value/2))
12257         done
12258
12259         if [ $orig -gt $order ]; then
12260                 order=$((order*2))
12261         fi
12262         echo $order
12263 }
12264
12265 size_in_KMGT() {
12266     local value=$1
12267     local size=('K' 'M' 'G' 'T');
12268     local i=0
12269     local size_string=$value
12270
12271     while [ $value -ge 1024 ]; do
12272         if [ $i -gt 3 ]; then
12273             #T is the biggest unit we get here, if that is bigger,
12274             #just return XXXT
12275             size_string=${value}T
12276             break
12277         fi
12278         value=$((value >> 10))
12279         if [ $value -lt 1024 ]; then
12280             size_string=${value}${size[$i]}
12281             break
12282         fi
12283         i=$((i + 1))
12284     done
12285
12286     echo $size_string
12287 }
12288
12289 get_rename_size() {
12290         local size=$1
12291         local context=${2:-.}
12292         local sample=$(do_facet $SINGLEMDS $LCTL \
12293                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12294                 grep -A1 $context |
12295                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12296         echo $sample
12297 }
12298
12299 test_133d() {
12300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12301         remote_ost_nodsh && skip "remote OST with nodsh"
12302         remote_mds_nodsh && skip "remote MDS with nodsh"
12303         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12304                 skip_env "MDS doesn't support rename stats"
12305
12306         local testdir1=$DIR/${tdir}/stats_testdir1
12307         local testdir2=$DIR/${tdir}/stats_testdir2
12308         mkdir -p $DIR/${tdir}
12309
12310         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12311
12312         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12313         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12314
12315         createmany -o $testdir1/test 512 || error "createmany failed"
12316
12317         # check samedir rename size
12318         mv ${testdir1}/test0 ${testdir1}/test_0
12319
12320         local testdir1_size=$(ls -l $DIR/${tdir} |
12321                 awk '/stats_testdir1/ {print $5}')
12322         local testdir2_size=$(ls -l $DIR/${tdir} |
12323                 awk '/stats_testdir2/ {print $5}')
12324
12325         testdir1_size=$(order_2 $testdir1_size)
12326         testdir2_size=$(order_2 $testdir2_size)
12327
12328         testdir1_size=$(size_in_KMGT $testdir1_size)
12329         testdir2_size=$(size_in_KMGT $testdir2_size)
12330
12331         echo "source rename dir size: ${testdir1_size}"
12332         echo "target rename dir size: ${testdir2_size}"
12333
12334         local cmd="do_facet $SINGLEMDS $LCTL "
12335         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12336
12337         eval $cmd || error "$cmd failed"
12338         local samedir=$($cmd | grep 'same_dir')
12339         local same_sample=$(get_rename_size $testdir1_size)
12340         [ -z "$samedir" ] && error "samedir_rename_size count error"
12341         [[ $same_sample -eq 1 ]] ||
12342                 error "samedir_rename_size error $same_sample"
12343         echo "Check same dir rename stats success"
12344
12345         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12346
12347         # check crossdir rename size
12348         mv ${testdir1}/test_0 ${testdir2}/test_0
12349
12350         testdir1_size=$(ls -l $DIR/${tdir} |
12351                 awk '/stats_testdir1/ {print $5}')
12352         testdir2_size=$(ls -l $DIR/${tdir} |
12353                 awk '/stats_testdir2/ {print $5}')
12354
12355         testdir1_size=$(order_2 $testdir1_size)
12356         testdir2_size=$(order_2 $testdir2_size)
12357
12358         testdir1_size=$(size_in_KMGT $testdir1_size)
12359         testdir2_size=$(size_in_KMGT $testdir2_size)
12360
12361         echo "source rename dir size: ${testdir1_size}"
12362         echo "target rename dir size: ${testdir2_size}"
12363
12364         eval $cmd || error "$cmd failed"
12365         local crossdir=$($cmd | grep 'crossdir')
12366         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12367         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12368         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12369         [[ $src_sample -eq 1 ]] ||
12370                 error "crossdir_rename_size error $src_sample"
12371         [[ $tgt_sample -eq 1 ]] ||
12372                 error "crossdir_rename_size error $tgt_sample"
12373         echo "Check cross dir rename stats success"
12374         rm -rf $DIR/${tdir}
12375 }
12376 run_test 133d "Verifying rename_stats ========================================"
12377
12378 test_133e() {
12379         remote_mds_nodsh && skip "remote MDS with nodsh"
12380         remote_ost_nodsh && skip "remote OST with nodsh"
12381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12382
12383         local testdir=$DIR/${tdir}/stats_testdir
12384         local ctr f0 f1 bs=32768 count=42 sum
12385
12386         mkdir -p ${testdir} || error "mkdir failed"
12387
12388         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12389
12390         for ctr in {write,read}_bytes; do
12391                 sync
12392                 cancel_lru_locks osc
12393
12394                 do_facet ost1 $LCTL set_param -n \
12395                         "obdfilter.*.exports.clear=clear"
12396
12397                 if [ $ctr = write_bytes ]; then
12398                         f0=/dev/zero
12399                         f1=${testdir}/${tfile}
12400                 else
12401                         f0=${testdir}/${tfile}
12402                         f1=/dev/null
12403                 fi
12404
12405                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
12406                         error "dd failed"
12407                 sync
12408                 cancel_lru_locks osc
12409
12410                 sum=$(do_facet ost1 $LCTL get_param \
12411                         "obdfilter.*.exports.*.stats" |
12412                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
12413                                 $1 == ctr { sum += $7 }
12414                                 END { printf("%0.0f", sum) }')
12415
12416                 if ((sum != bs * count)); then
12417                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
12418                 fi
12419         done
12420
12421         rm -rf $DIR/${tdir}
12422 }
12423 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
12424
12425 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
12426
12427 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
12428 # not honor the -ignore_readdir_race option correctly. So we call
12429 # error_ignore() rather than error() in these cases. See LU-11152.
12430 error_133() {
12431         if (find --version; do_facet mds1 find --version) |
12432                 grep -q '\b4\.5\.1[1-4]\b'; then
12433                 error_ignore LU-11152 "$@"
12434         else
12435                 error "$@"
12436         fi
12437 }
12438
12439 test_133f() {
12440         # First without trusting modes.
12441         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
12442         echo "proc_dirs='$proc_dirs'"
12443         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
12444         find $proc_dirs -exec cat '{}' \; &> /dev/null
12445
12446         # Second verifying readability.
12447         $LCTL get_param -R '*' &> /dev/null
12448
12449         # Verifing writability with badarea_io.
12450         find $proc_dirs \
12451                 -ignore_readdir_race \
12452                 -type f \
12453                 -not -name force_lbug \
12454                 -not -name changelog_mask \
12455                 -exec badarea_io '{}' \; ||
12456                         error_133 "find $proc_dirs failed"
12457 }
12458 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
12459
12460 test_133g() {
12461         remote_mds_nodsh && skip "remote MDS with nodsh"
12462         remote_ost_nodsh && skip "remote OST with nodsh"
12463
12464         # eventually, this can also be replaced with "lctl get_param -R",
12465         # but not until that option is always available on the server
12466         local facet
12467         for facet in mds1 ost1; do
12468                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
12469                         skip_noexit "Too old lustre on $facet"
12470                 local facet_proc_dirs=$(do_facet $facet \
12471                                         \\\ls -d $proc_regexp 2>/dev/null)
12472                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12473                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12474                 do_facet $facet find $facet_proc_dirs \
12475                         ! -name req_history \
12476                         -exec cat '{}' \\\; &> /dev/null
12477
12478                 do_facet $facet find $facet_proc_dirs \
12479                         ! -name req_history \
12480                         -type f \
12481                         -exec cat '{}' \\\; &> /dev/null ||
12482                                 error "proc file read failed"
12483
12484                 do_facet $facet find $facet_proc_dirs \
12485                         -ignore_readdir_race \
12486                         -type f \
12487                         -not -name force_lbug \
12488                         -not -name changelog_mask \
12489                         -exec badarea_io '{}' \\\; ||
12490                                 error_133 "$facet find $facet_proc_dirs failed"
12491         done
12492
12493         # remount the FS in case writes/reads /proc break the FS
12494         cleanup || error "failed to unmount"
12495         setup || error "failed to setup"
12496         true
12497 }
12498 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
12499
12500 test_133h() {
12501         remote_mds_nodsh && skip "remote MDS with nodsh"
12502         remote_ost_nodsh && skip "remote OST with nodsh"
12503         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
12504                 skip "Need MDS version at least 2.9.54"
12505
12506         local facet
12507
12508         for facet in client mds1 ost1; do
12509                 local facet_proc_dirs=$(do_facet $facet \
12510                                         \\\ls -d $proc_regexp 2> /dev/null)
12511                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12512                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12513                 # Get the list of files that are missing the terminating newline
12514                 local missing=($(do_facet $facet \
12515                         find ${facet_proc_dirs} -type f \|              \
12516                                 while read F\; do                       \
12517                                         awk -v FS='\v' -v RS='\v\v'     \
12518                                         "'END { if(NR>0 &&              \
12519                                         \\\$NF !~ /.*\\\n\$/)           \
12520                                                 print FILENAME}'"       \
12521                                         '\$F'\;                         \
12522                                 done 2>/dev/null))
12523                 [ ${#missing[*]} -eq 0 ] ||
12524                         error "files do not end with newline: ${missing[*]}"
12525         done
12526 }
12527 run_test 133h "Proc files should end with newlines"
12528
12529 test_134a() {
12530         remote_mds_nodsh && skip "remote MDS with nodsh"
12531         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12532                 skip "Need MDS version at least 2.7.54"
12533
12534         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12535         cancel_lru_locks mdc
12536
12537         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12538         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12539         [ $unused -eq 0 ] || error "$unused locks are not cleared"
12540
12541         local nr=1000
12542         createmany -o $DIR/$tdir/f $nr ||
12543                 error "failed to create $nr files in $DIR/$tdir"
12544         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12545
12546         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
12547         do_facet mds1 $LCTL set_param fail_loc=0x327
12548         do_facet mds1 $LCTL set_param fail_val=500
12549         touch $DIR/$tdir/m
12550
12551         echo "sleep 10 seconds ..."
12552         sleep 10
12553         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
12554
12555         do_facet mds1 $LCTL set_param fail_loc=0
12556         do_facet mds1 $LCTL set_param fail_val=0
12557         [ $lck_cnt -lt $unused ] ||
12558                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
12559
12560         rm $DIR/$tdir/m
12561         unlinkmany $DIR/$tdir/f $nr
12562 }
12563 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
12564
12565 test_134b() {
12566         remote_mds_nodsh && skip "remote MDS with nodsh"
12567         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12568                 skip "Need MDS version at least 2.7.54"
12569
12570         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12571         cancel_lru_locks mdc
12572
12573         local low_wm=$(do_facet mds1 $LCTL get_param -n \
12574                         ldlm.lock_reclaim_threshold_mb)
12575         # disable reclaim temporarily
12576         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
12577
12578         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
12579         do_facet mds1 $LCTL set_param fail_loc=0x328
12580         do_facet mds1 $LCTL set_param fail_val=500
12581
12582         $LCTL set_param debug=+trace
12583
12584         local nr=600
12585         createmany -o $DIR/$tdir/f $nr &
12586         local create_pid=$!
12587
12588         echo "Sleep $TIMEOUT seconds ..."
12589         sleep $TIMEOUT
12590         if ! ps -p $create_pid  > /dev/null 2>&1; then
12591                 do_facet mds1 $LCTL set_param fail_loc=0
12592                 do_facet mds1 $LCTL set_param fail_val=0
12593                 do_facet mds1 $LCTL set_param \
12594                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
12595                 error "createmany finished incorrectly!"
12596         fi
12597         do_facet mds1 $LCTL set_param fail_loc=0
12598         do_facet mds1 $LCTL set_param fail_val=0
12599         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
12600         wait $create_pid || return 1
12601
12602         unlinkmany $DIR/$tdir/f $nr
12603 }
12604 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
12605
12606 test_140() { #bug-17379
12607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12608
12609         test_mkdir $DIR/$tdir
12610         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
12611         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
12612
12613         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
12614         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
12615         local i=0
12616         while i=$((i + 1)); do
12617                 test_mkdir $i
12618                 cd $i || error "Changing to $i"
12619                 ln -s ../stat stat || error "Creating stat symlink"
12620                 # Read the symlink until ELOOP present,
12621                 # not LBUGing the system is considered success,
12622                 # we didn't overrun the stack.
12623                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
12624                 if [ $ret -ne 0 ]; then
12625                         if [ $ret -eq 40 ]; then
12626                                 break  # -ELOOP
12627                         else
12628                                 error "Open stat symlink"
12629                                         return
12630                         fi
12631                 fi
12632         done
12633         i=$((i - 1))
12634         echo "The symlink depth = $i"
12635         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
12636                 error "Invalid symlink depth"
12637
12638         # Test recursive symlink
12639         ln -s symlink_self symlink_self
12640         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
12641         echo "open symlink_self returns $ret"
12642         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
12643 }
12644 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
12645
12646 test_150() {
12647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12648
12649         local TF="$TMP/$tfile"
12650
12651         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12652         cp $TF $DIR/$tfile
12653         cancel_lru_locks $OSC
12654         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
12655         remount_client $MOUNT
12656         df -P $MOUNT
12657         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
12658
12659         $TRUNCATE $TF 6000
12660         $TRUNCATE $DIR/$tfile 6000
12661         cancel_lru_locks $OSC
12662         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
12663
12664         echo "12345" >>$TF
12665         echo "12345" >>$DIR/$tfile
12666         cancel_lru_locks $OSC
12667         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
12668
12669         echo "12345" >>$TF
12670         echo "12345" >>$DIR/$tfile
12671         cancel_lru_locks $OSC
12672         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
12673
12674         rm -f $TF
12675         true
12676 }
12677 run_test 150 "truncate/append tests"
12678
12679 #LU-2902 roc_hit was not able to read all values from lproc
12680 function roc_hit_init() {
12681         local list=$(comma_list $(osts_nodes))
12682         local dir=$DIR/$tdir-check
12683         local file=$dir/$tfile
12684         local BEFORE
12685         local AFTER
12686         local idx
12687
12688         test_mkdir $dir
12689         #use setstripe to do a write to every ost
12690         for i in $(seq 0 $((OSTCOUNT-1))); do
12691                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
12692                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
12693                 idx=$(printf %04x $i)
12694                 BEFORE=$(get_osd_param $list *OST*$idx stats |
12695                         awk '$1 == "cache_access" {sum += $7}
12696                                 END { printf("%0.0f", sum) }')
12697
12698                 cancel_lru_locks osc
12699                 cat $file >/dev/null
12700
12701                 AFTER=$(get_osd_param $list *OST*$idx stats |
12702                         awk '$1 == "cache_access" {sum += $7}
12703                                 END { printf("%0.0f", sum) }')
12704
12705                 echo BEFORE:$BEFORE AFTER:$AFTER
12706                 if ! let "AFTER - BEFORE == 4"; then
12707                         rm -rf $dir
12708                         error "roc_hit is not safe to use"
12709                 fi
12710                 rm $file
12711         done
12712
12713         rm -rf $dir
12714 }
12715
12716 function roc_hit() {
12717         local list=$(comma_list $(osts_nodes))
12718         echo $(get_osd_param $list '' stats |
12719                 awk '$1 == "cache_hit" {sum += $7}
12720                         END { printf("%0.0f", sum) }')
12721 }
12722
12723 function set_cache() {
12724         local on=1
12725
12726         if [ "$2" == "off" ]; then
12727                 on=0;
12728         fi
12729         local list=$(comma_list $(osts_nodes))
12730         set_osd_param $list '' $1_cache_enable $on
12731
12732         cancel_lru_locks osc
12733 }
12734
12735 test_151() {
12736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12737         remote_ost_nodsh && skip "remote OST with nodsh"
12738
12739         local CPAGES=3
12740         local list=$(comma_list $(osts_nodes))
12741
12742         # check whether obdfilter is cache capable at all
12743         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
12744                 skip "not cache-capable obdfilter"
12745         fi
12746
12747         # check cache is enabled on all obdfilters
12748         if get_osd_param $list '' read_cache_enable | grep 0; then
12749                 skip "oss cache is disabled"
12750         fi
12751
12752         set_osd_param $list '' writethrough_cache_enable 1
12753
12754         # check write cache is enabled on all obdfilters
12755         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
12756                 skip "oss write cache is NOT enabled"
12757         fi
12758
12759         roc_hit_init
12760
12761         #define OBD_FAIL_OBD_NO_LRU  0x609
12762         do_nodes $list $LCTL set_param fail_loc=0x609
12763
12764         # pages should be in the case right after write
12765         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
12766                 error "dd failed"
12767
12768         local BEFORE=$(roc_hit)
12769         cancel_lru_locks osc
12770         cat $DIR/$tfile >/dev/null
12771         local AFTER=$(roc_hit)
12772
12773         do_nodes $list $LCTL set_param fail_loc=0
12774
12775         if ! let "AFTER - BEFORE == CPAGES"; then
12776                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12777         fi
12778
12779         cancel_lru_locks osc
12780         # invalidates OST cache
12781         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
12782         set_osd_param $list '' read_cache_enable 0
12783         cat $DIR/$tfile >/dev/null
12784
12785         # now data shouldn't be found in the cache
12786         BEFORE=$(roc_hit)
12787         cancel_lru_locks osc
12788         cat $DIR/$tfile >/dev/null
12789         AFTER=$(roc_hit)
12790         if let "AFTER - BEFORE != 0"; then
12791                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12792         fi
12793
12794         set_osd_param $list '' read_cache_enable 1
12795         rm -f $DIR/$tfile
12796 }
12797 run_test 151 "test cache on oss and controls ==============================="
12798
12799 test_152() {
12800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12801
12802         local TF="$TMP/$tfile"
12803
12804         # simulate ENOMEM during write
12805 #define OBD_FAIL_OST_NOMEM      0x226
12806         lctl set_param fail_loc=0x80000226
12807         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12808         cp $TF $DIR/$tfile
12809         sync || error "sync failed"
12810         lctl set_param fail_loc=0
12811
12812         # discard client's cache
12813         cancel_lru_locks osc
12814
12815         # simulate ENOMEM during read
12816         lctl set_param fail_loc=0x80000226
12817         cmp $TF $DIR/$tfile || error "cmp failed"
12818         lctl set_param fail_loc=0
12819
12820         rm -f $TF
12821 }
12822 run_test 152 "test read/write with enomem ============================"
12823
12824 test_153() {
12825         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
12826 }
12827 run_test 153 "test if fdatasync does not crash ======================="
12828
12829 dot_lustre_fid_permission_check() {
12830         local fid=$1
12831         local ffid=$MOUNT/.lustre/fid/$fid
12832         local test_dir=$2
12833
12834         echo "stat fid $fid"
12835         stat $ffid > /dev/null || error "stat $ffid failed."
12836         echo "touch fid $fid"
12837         touch $ffid || error "touch $ffid failed."
12838         echo "write to fid $fid"
12839         cat /etc/hosts > $ffid || error "write $ffid failed."
12840         echo "read fid $fid"
12841         diff /etc/hosts $ffid || error "read $ffid failed."
12842         echo "append write to fid $fid"
12843         cat /etc/hosts >> $ffid || error "append write $ffid failed."
12844         echo "rename fid $fid"
12845         mv $ffid $test_dir/$tfile.1 &&
12846                 error "rename $ffid to $tfile.1 should fail."
12847         touch $test_dir/$tfile.1
12848         mv $test_dir/$tfile.1 $ffid &&
12849                 error "rename $tfile.1 to $ffid should fail."
12850         rm -f $test_dir/$tfile.1
12851         echo "truncate fid $fid"
12852         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
12853         echo "link fid $fid"
12854         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
12855         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
12856                 echo "setfacl fid $fid"
12857                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
12858                 echo "getfacl fid $fid"
12859                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
12860         fi
12861         echo "unlink fid $fid"
12862         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
12863         echo "mknod fid $fid"
12864         mknod $ffid c 1 3 && error "mknod $ffid should fail."
12865
12866         fid=[0xf00000400:0x1:0x0]
12867         ffid=$MOUNT/.lustre/fid/$fid
12868
12869         echo "stat non-exist fid $fid"
12870         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
12871         echo "write to non-exist fid $fid"
12872         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
12873         echo "link new fid $fid"
12874         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
12875
12876         mkdir -p $test_dir/$tdir
12877         touch $test_dir/$tdir/$tfile
12878         fid=$($LFS path2fid $test_dir/$tdir)
12879         rc=$?
12880         [ $rc -ne 0 ] &&
12881                 error "error: could not get fid for $test_dir/$dir/$tfile."
12882
12883         ffid=$MOUNT/.lustre/fid/$fid
12884
12885         echo "ls $fid"
12886         ls $ffid > /dev/null || error "ls $ffid failed."
12887         echo "touch $fid/$tfile.1"
12888         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
12889
12890         echo "touch $MOUNT/.lustre/fid/$tfile"
12891         touch $MOUNT/.lustre/fid/$tfile && \
12892                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
12893
12894         echo "setxattr to $MOUNT/.lustre/fid"
12895         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
12896
12897         echo "listxattr for $MOUNT/.lustre/fid"
12898         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
12899
12900         echo "delxattr from $MOUNT/.lustre/fid"
12901         setfattr -x trusted.name1 $MOUNT/.lustre/fid
12902
12903         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
12904         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
12905                 error "touch invalid fid should fail."
12906
12907         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
12908         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
12909                 error "touch non-normal fid should fail."
12910
12911         echo "rename $tdir to $MOUNT/.lustre/fid"
12912         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
12913                 error "rename to $MOUNT/.lustre/fid should fail."
12914
12915         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
12916         then            # LU-3547
12917                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
12918                 local new_obf_mode=777
12919
12920                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
12921                 chmod $new_obf_mode $DIR/.lustre/fid ||
12922                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
12923
12924                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
12925                 [ $obf_mode -eq $new_obf_mode ] ||
12926                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
12927
12928                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
12929                 chmod $old_obf_mode $DIR/.lustre/fid ||
12930                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
12931         fi
12932
12933         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
12934         fid=$($LFS path2fid $test_dir/$tfile-2)
12935
12936         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
12937         then # LU-5424
12938                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
12939                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
12940                         error "create lov data thru .lustre failed"
12941         fi
12942         echo "cp /etc/passwd $test_dir/$tfile-2"
12943         cp /etc/passwd $test_dir/$tfile-2 ||
12944                 error "copy to $test_dir/$tfile-2 failed."
12945         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
12946         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
12947                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
12948
12949         rm -rf $test_dir/tfile.lnk
12950         rm -rf $test_dir/$tfile-2
12951 }
12952
12953 test_154A() {
12954         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12955                 skip "Need MDS version at least 2.4.1"
12956
12957         local tf=$DIR/$tfile
12958         touch $tf
12959
12960         local fid=$($LFS path2fid $tf)
12961         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
12962
12963         # check that we get the same pathname back
12964         local found=$($LFS fid2path $MOUNT "$fid")
12965         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
12966         [ "$found" == "$tf" ] ||
12967                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
12968 }
12969 run_test 154A "lfs path2fid and fid2path basic checks"
12970
12971 test_154B() {
12972         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12973                 skip "Need MDS version at least 2.4.1"
12974
12975         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
12976         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
12977         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
12978         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
12979
12980         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
12981         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
12982
12983         # check that we get the same pathname
12984         echo "PFID: $PFID, name: $name"
12985         local FOUND=$($LFS fid2path $MOUNT "$PFID")
12986         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
12987         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
12988                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
12989
12990         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
12991 }
12992 run_test 154B "verify the ll_decode_linkea tool"
12993
12994 test_154a() {
12995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12996         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12997         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12998                 skip "Need MDS version at least 2.2.51"
12999         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13000
13001         cp /etc/hosts $DIR/$tfile
13002
13003         fid=$($LFS path2fid $DIR/$tfile)
13004         rc=$?
13005         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13006
13007         dot_lustre_fid_permission_check "$fid" $DIR ||
13008                 error "dot lustre permission check $fid failed"
13009
13010         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13011
13012         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13013
13014         touch $MOUNT/.lustre/file &&
13015                 error "creation is not allowed under .lustre"
13016
13017         mkdir $MOUNT/.lustre/dir &&
13018                 error "mkdir is not allowed under .lustre"
13019
13020         rm -rf $DIR/$tfile
13021 }
13022 run_test 154a "Open-by-FID"
13023
13024 test_154b() {
13025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13026         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13027         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13028         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13029                 skip "Need MDS version at least 2.2.51"
13030
13031         local remote_dir=$DIR/$tdir/remote_dir
13032         local MDTIDX=1
13033         local rc=0
13034
13035         mkdir -p $DIR/$tdir
13036         $LFS mkdir -i $MDTIDX $remote_dir ||
13037                 error "create remote directory failed"
13038
13039         cp /etc/hosts $remote_dir/$tfile
13040
13041         fid=$($LFS path2fid $remote_dir/$tfile)
13042         rc=$?
13043         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13044
13045         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13046                 error "dot lustre permission check $fid failed"
13047         rm -rf $DIR/$tdir
13048 }
13049 run_test 154b "Open-by-FID for remote directory"
13050
13051 test_154c() {
13052         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13053                 skip "Need MDS version at least 2.4.1"
13054
13055         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13056         local FID1=$($LFS path2fid $DIR/$tfile.1)
13057         local FID2=$($LFS path2fid $DIR/$tfile.2)
13058         local FID3=$($LFS path2fid $DIR/$tfile.3)
13059
13060         local N=1
13061         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13062                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13063                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13064                 local want=FID$N
13065                 [ "$FID" = "${!want}" ] ||
13066                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13067                 N=$((N + 1))
13068         done
13069
13070         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13071         do
13072                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13073                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13074                 N=$((N + 1))
13075         done
13076 }
13077 run_test 154c "lfs path2fid and fid2path multiple arguments"
13078
13079 test_154d() {
13080         remote_mds_nodsh && skip "remote MDS with nodsh"
13081         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13082                 skip "Need MDS version at least 2.5.53"
13083
13084         if remote_mds; then
13085                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13086         else
13087                 nid="0@lo"
13088         fi
13089         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13090         local fd
13091         local cmd
13092
13093         rm -f $DIR/$tfile
13094         touch $DIR/$tfile
13095
13096         local fid=$($LFS path2fid $DIR/$tfile)
13097         # Open the file
13098         fd=$(free_fd)
13099         cmd="exec $fd<$DIR/$tfile"
13100         eval $cmd
13101         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13102         echo "$fid_list" | grep "$fid"
13103         rc=$?
13104
13105         cmd="exec $fd>/dev/null"
13106         eval $cmd
13107         if [ $rc -ne 0 ]; then
13108                 error "FID $fid not found in open files list $fid_list"
13109         fi
13110 }
13111 run_test 154d "Verify open file fid"
13112
13113 test_154e()
13114 {
13115         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13116                 skip "Need MDS version at least 2.6.50"
13117
13118         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13119                 error ".lustre returned by readdir"
13120         fi
13121 }
13122 run_test 154e ".lustre is not returned by readdir"
13123
13124 test_154f() {
13125         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13126
13127         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13128         test_mkdir -p -c1 $DIR/$tdir/d
13129         # test dirs inherit from its stripe
13130         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13131         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13132         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13133         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13134         touch $DIR/f
13135
13136         # get fid of parents
13137         local FID0=$($LFS path2fid $DIR/$tdir/d)
13138         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13139         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13140         local FID3=$($LFS path2fid $DIR)
13141
13142         # check that path2fid --parents returns expected <parent_fid>/name
13143         # 1) test for a directory (single parent)
13144         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13145         [ "$parent" == "$FID0/foo1" ] ||
13146                 error "expected parent: $FID0/foo1, got: $parent"
13147
13148         # 2) test for a file with nlink > 1 (multiple parents)
13149         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13150         echo "$parent" | grep -F "$FID1/$tfile" ||
13151                 error "$FID1/$tfile not returned in parent list"
13152         echo "$parent" | grep -F "$FID2/link" ||
13153                 error "$FID2/link not returned in parent list"
13154
13155         # 3) get parent by fid
13156         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13157         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13158         echo "$parent" | grep -F "$FID1/$tfile" ||
13159                 error "$FID1/$tfile not returned in parent list (by fid)"
13160         echo "$parent" | grep -F "$FID2/link" ||
13161                 error "$FID2/link not returned in parent list (by fid)"
13162
13163         # 4) test for entry in root directory
13164         parent=$($LFS path2fid --parents $DIR/f)
13165         echo "$parent" | grep -F "$FID3/f" ||
13166                 error "$FID3/f not returned in parent list"
13167
13168         # 5) test it on root directory
13169         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13170                 error "$MOUNT should not have parents"
13171
13172         # enable xattr caching and check that linkea is correctly updated
13173         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13174         save_lustre_params client "llite.*.xattr_cache" > $save
13175         lctl set_param llite.*.xattr_cache 1
13176
13177         # 6.1) linkea update on rename
13178         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13179
13180         # get parents by fid
13181         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13182         # foo1 should no longer be returned in parent list
13183         echo "$parent" | grep -F "$FID1" &&
13184                 error "$FID1 should no longer be in parent list"
13185         # the new path should appear
13186         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13187                 error "$FID2/$tfile.moved is not in parent list"
13188
13189         # 6.2) linkea update on unlink
13190         rm -f $DIR/$tdir/d/foo2/link
13191         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13192         # foo2/link should no longer be returned in parent list
13193         echo "$parent" | grep -F "$FID2/link" &&
13194                 error "$FID2/link should no longer be in parent list"
13195         true
13196
13197         rm -f $DIR/f
13198         restore_lustre_params < $save
13199         rm -f $save
13200 }
13201 run_test 154f "get parent fids by reading link ea"
13202
13203 test_154g()
13204 {
13205         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13206         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13207            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13208                 skip "Need MDS version at least 2.6.92"
13209
13210         mkdir -p $DIR/$tdir
13211         llapi_fid_test -d $DIR/$tdir
13212 }
13213 run_test 154g "various llapi FID tests"
13214
13215 test_155_small_load() {
13216     local temp=$TMP/$tfile
13217     local file=$DIR/$tfile
13218
13219     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13220         error "dd of=$temp bs=6096 count=1 failed"
13221     cp $temp $file
13222     cancel_lru_locks $OSC
13223     cmp $temp $file || error "$temp $file differ"
13224
13225     $TRUNCATE $temp 6000
13226     $TRUNCATE $file 6000
13227     cmp $temp $file || error "$temp $file differ (truncate1)"
13228
13229     echo "12345" >>$temp
13230     echo "12345" >>$file
13231     cmp $temp $file || error "$temp $file differ (append1)"
13232
13233     echo "12345" >>$temp
13234     echo "12345" >>$file
13235     cmp $temp $file || error "$temp $file differ (append2)"
13236
13237     rm -f $temp $file
13238     true
13239 }
13240
13241 test_155_big_load() {
13242         remote_ost_nodsh && skip "remote OST with nodsh"
13243
13244         local temp=$TMP/$tfile
13245         local file=$DIR/$tfile
13246
13247         free_min_max
13248         local cache_size=$(do_facet ost$((MAXI+1)) \
13249                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13250         local large_file_size=$((cache_size * 2))
13251
13252         echo "OSS cache size: $cache_size KB"
13253         echo "Large file size: $large_file_size KB"
13254
13255         [ $MAXV -le $large_file_size ] &&
13256                 skip_env "max available OST size needs > $large_file_size KB"
13257
13258         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13259
13260         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13261                 error "dd of=$temp bs=$large_file_size count=1k failed"
13262         cp $temp $file
13263         ls -lh $temp $file
13264         cancel_lru_locks osc
13265         cmp $temp $file || error "$temp $file differ"
13266
13267         rm -f $temp $file
13268         true
13269 }
13270
13271 save_writethrough() {
13272         local facets=$(get_facets OST)
13273
13274         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13275 }
13276
13277 test_155a() {
13278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13279
13280         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13281
13282         save_writethrough $p
13283
13284         set_cache read on
13285         set_cache writethrough on
13286         test_155_small_load
13287         restore_lustre_params < $p
13288         rm -f $p
13289 }
13290 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13291
13292 test_155b() {
13293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13294
13295         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13296
13297         save_writethrough $p
13298
13299         set_cache read on
13300         set_cache writethrough off
13301         test_155_small_load
13302         restore_lustre_params < $p
13303         rm -f $p
13304 }
13305 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
13306
13307 test_155c() {
13308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13309
13310         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13311
13312         save_writethrough $p
13313
13314         set_cache read off
13315         set_cache writethrough on
13316         test_155_small_load
13317         restore_lustre_params < $p
13318         rm -f $p
13319 }
13320 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
13321
13322 test_155d() {
13323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13324
13325         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13326
13327         save_writethrough $p
13328
13329         set_cache read off
13330         set_cache writethrough off
13331         test_155_small_load
13332         restore_lustre_params < $p
13333         rm -f $p
13334 }
13335 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
13336
13337 test_155e() {
13338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13339
13340         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13341
13342         save_writethrough $p
13343
13344         set_cache read on
13345         set_cache writethrough on
13346         test_155_big_load
13347         restore_lustre_params < $p
13348         rm -f $p
13349 }
13350 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
13351
13352 test_155f() {
13353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13354
13355         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13356
13357         save_writethrough $p
13358
13359         set_cache read on
13360         set_cache writethrough off
13361         test_155_big_load
13362         restore_lustre_params < $p
13363         rm -f $p
13364 }
13365 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
13366
13367 test_155g() {
13368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13369
13370         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13371
13372         save_writethrough $p
13373
13374         set_cache read off
13375         set_cache writethrough on
13376         test_155_big_load
13377         restore_lustre_params < $p
13378         rm -f $p
13379 }
13380 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
13381
13382 test_155h() {
13383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13384
13385         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13386
13387         save_writethrough $p
13388
13389         set_cache read off
13390         set_cache writethrough off
13391         test_155_big_load
13392         restore_lustre_params < $p
13393         rm -f $p
13394 }
13395 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
13396
13397 test_156() {
13398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13399         remote_ost_nodsh && skip "remote OST with nodsh"
13400         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
13401                 skip "stats not implemented on old servers"
13402         [ "$ost1_FSTYPE" = "zfs" ] &&
13403                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
13404
13405         local CPAGES=3
13406         local BEFORE
13407         local AFTER
13408         local file="$DIR/$tfile"
13409         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13410
13411         save_writethrough $p
13412         roc_hit_init
13413
13414         log "Turn on read and write cache"
13415         set_cache read on
13416         set_cache writethrough on
13417
13418         log "Write data and read it back."
13419         log "Read should be satisfied from the cache."
13420         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13421         BEFORE=$(roc_hit)
13422         cancel_lru_locks osc
13423         cat $file >/dev/null
13424         AFTER=$(roc_hit)
13425         if ! let "AFTER - BEFORE == CPAGES"; then
13426                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
13427         else
13428                 log "cache hits: before: $BEFORE, after: $AFTER"
13429         fi
13430
13431         log "Read again; it should be satisfied from the cache."
13432         BEFORE=$AFTER
13433         cancel_lru_locks osc
13434         cat $file >/dev/null
13435         AFTER=$(roc_hit)
13436         if ! let "AFTER - BEFORE == CPAGES"; then
13437                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
13438         else
13439                 log "cache hits:: before: $BEFORE, after: $AFTER"
13440         fi
13441
13442         log "Turn off the read cache and turn on the write cache"
13443         set_cache read off
13444         set_cache writethrough on
13445
13446         log "Read again; it should be satisfied from the cache."
13447         BEFORE=$(roc_hit)
13448         cancel_lru_locks osc
13449         cat $file >/dev/null
13450         AFTER=$(roc_hit)
13451         if ! let "AFTER - BEFORE == CPAGES"; then
13452                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
13453         else
13454                 log "cache hits:: before: $BEFORE, after: $AFTER"
13455         fi
13456
13457         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
13458                 # > 2.12.56 uses pagecache if cached
13459                 log "Read again; it should not be satisfied from the cache."
13460                 BEFORE=$AFTER
13461                 cancel_lru_locks osc
13462                 cat $file >/dev/null
13463                 AFTER=$(roc_hit)
13464                 if ! let "AFTER - BEFORE == 0"; then
13465                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
13466                 else
13467                         log "cache hits:: before: $BEFORE, after: $AFTER"
13468                 fi
13469         fi
13470
13471         log "Write data and read it back."
13472         log "Read should be satisfied from the cache."
13473         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13474         BEFORE=$(roc_hit)
13475         cancel_lru_locks osc
13476         cat $file >/dev/null
13477         AFTER=$(roc_hit)
13478         if ! let "AFTER - BEFORE == CPAGES"; then
13479                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
13480         else
13481                 log "cache hits:: before: $BEFORE, after: $AFTER"
13482         fi
13483
13484         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
13485                 # > 2.12.56 uses pagecache if cached
13486                 log "Read again; it should not be satisfied from the cache."
13487                 BEFORE=$AFTER
13488                 cancel_lru_locks osc
13489                 cat $file >/dev/null
13490                 AFTER=$(roc_hit)
13491                 if ! let "AFTER - BEFORE == 0"; then
13492                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
13493                 else
13494                         log "cache hits:: before: $BEFORE, after: $AFTER"
13495                 fi
13496         fi
13497
13498         log "Turn off read and write cache"
13499         set_cache read off
13500         set_cache writethrough off
13501
13502         log "Write data and read it back"
13503         log "It should not be satisfied from the cache."
13504         rm -f $file
13505         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13506         cancel_lru_locks osc
13507         BEFORE=$(roc_hit)
13508         cat $file >/dev/null
13509         AFTER=$(roc_hit)
13510         if ! let "AFTER - BEFORE == 0"; then
13511                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
13512         else
13513                 log "cache hits:: before: $BEFORE, after: $AFTER"
13514         fi
13515
13516         log "Turn on the read cache and turn off the write cache"
13517         set_cache read on
13518         set_cache writethrough off
13519
13520         log "Write data and read it back"
13521         log "It should not be satisfied from the cache."
13522         rm -f $file
13523         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13524         BEFORE=$(roc_hit)
13525         cancel_lru_locks osc
13526         cat $file >/dev/null
13527         AFTER=$(roc_hit)
13528         if ! let "AFTER - BEFORE == 0"; then
13529                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
13530         else
13531                 log "cache hits:: before: $BEFORE, after: $AFTER"
13532         fi
13533
13534         log "Read again; it should be satisfied from the cache."
13535         BEFORE=$(roc_hit)
13536         cancel_lru_locks osc
13537         cat $file >/dev/null
13538         AFTER=$(roc_hit)
13539         if ! let "AFTER - BEFORE == CPAGES"; then
13540                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
13541         else
13542                 log "cache hits:: before: $BEFORE, after: $AFTER"
13543         fi
13544
13545         restore_lustre_params < $p
13546         rm -f $p $file
13547 }
13548 run_test 156 "Verification of tunables"
13549
13550 test_160a() {
13551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13552         remote_mds_nodsh && skip "remote MDS with nodsh"
13553         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13554                 skip "Need MDS version at least 2.2.0"
13555
13556         changelog_register || error "changelog_register failed"
13557         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13558         changelog_users $SINGLEMDS | grep -q $cl_user ||
13559                 error "User $cl_user not found in changelog_users"
13560
13561         # change something
13562         test_mkdir -p $DIR/$tdir/pics/2008/zachy
13563         changelog_clear 0 || error "changelog_clear failed"
13564         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
13565         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
13566         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
13567         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
13568         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
13569         rm $DIR/$tdir/pics/desktop.jpg
13570
13571         changelog_dump | tail -10
13572
13573         echo "verifying changelog mask"
13574         changelog_chmask "-MKDIR"
13575         changelog_chmask "-CLOSE"
13576
13577         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
13578         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
13579
13580         changelog_chmask "+MKDIR"
13581         changelog_chmask "+CLOSE"
13582
13583         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
13584         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
13585
13586         changelog_dump | tail -10
13587         MKDIRS=$(changelog_dump | grep -c "MKDIR")
13588         CLOSES=$(changelog_dump | grep -c "CLOSE")
13589         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
13590         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
13591
13592         # verify contents
13593         echo "verifying target fid"
13594         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
13595         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
13596         [ "$fidc" == "$fidf" ] ||
13597                 error "changelog '$tfile' fid $fidc != file fid $fidf"
13598         echo "verifying parent fid"
13599         # The FID returned from the Changelog may be the directory shard on
13600         # a different MDT, and not the FID returned by path2fid on the parent.
13601         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
13602         # since this is what will matter when recreating this file in the tree.
13603         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
13604         local pathp=$($LFS fid2path $MOUNT "$fidp")
13605         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
13606                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
13607
13608         echo "getting records for $cl_user"
13609         changelog_users $SINGLEMDS
13610         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
13611         local nclr=3
13612         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
13613                 error "changelog_clear failed"
13614         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
13615         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
13616         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
13617                 error "user index expect $user_rec1 + $nclr != $user_rec2"
13618
13619         local min0_rec=$(changelog_users $SINGLEMDS |
13620                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
13621         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
13622                           awk '{ print $1; exit; }')
13623
13624         changelog_dump | tail -n 5
13625         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
13626         [ $first_rec == $((min0_rec + 1)) ] ||
13627                 error "first index should be $min0_rec + 1 not $first_rec"
13628
13629         # LU-3446 changelog index reset on MDT restart
13630         local cur_rec1=$(changelog_users $SINGLEMDS |
13631                          awk '/^current.index:/ { print $NF }')
13632         changelog_clear 0 ||
13633                 error "clear all changelog records for $cl_user failed"
13634         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
13635         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
13636                 error "Fail to start $SINGLEMDS"
13637         local cur_rec2=$(changelog_users $SINGLEMDS |
13638                          awk '/^current.index:/ { print $NF }')
13639         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
13640         [ $cur_rec1 == $cur_rec2 ] ||
13641                 error "current index should be $cur_rec1 not $cur_rec2"
13642
13643         echo "verifying users from this test are deregistered"
13644         changelog_deregister || error "changelog_deregister failed"
13645         changelog_users $SINGLEMDS | grep -q $cl_user &&
13646                 error "User '$cl_user' still in changelog_users"
13647
13648         # lctl get_param -n mdd.*.changelog_users
13649         # current index: 144
13650         # ID    index (idle seconds)
13651         # cl3   144 (2)
13652         if ! changelog_users $SINGLEMDS | grep "^cl"; then
13653                 # this is the normal case where all users were deregistered
13654                 # make sure no new records are added when no users are present
13655                 local last_rec1=$(changelog_users $SINGLEMDS |
13656                                   awk '/^current.index:/ { print $NF }')
13657                 touch $DIR/$tdir/chloe
13658                 local last_rec2=$(changelog_users $SINGLEMDS |
13659                                   awk '/^current.index:/ { print $NF }')
13660                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
13661                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
13662         else
13663                 # any changelog users must be leftovers from a previous test
13664                 changelog_users $SINGLEMDS
13665                 echo "other changelog users; can't verify off"
13666         fi
13667 }
13668 run_test 160a "changelog sanity"
13669
13670 test_160b() { # LU-3587
13671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13672         remote_mds_nodsh && skip "remote MDS with nodsh"
13673         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13674                 skip "Need MDS version at least 2.2.0"
13675
13676         changelog_register || error "changelog_register failed"
13677         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13678         changelog_users $SINGLEMDS | grep -q $cl_user ||
13679                 error "User '$cl_user' not found in changelog_users"
13680
13681         local longname1=$(str_repeat a 255)
13682         local longname2=$(str_repeat b 255)
13683
13684         cd $DIR
13685         echo "creating very long named file"
13686         touch $longname1 || error "create of '$longname1' failed"
13687         echo "renaming very long named file"
13688         mv $longname1 $longname2
13689
13690         changelog_dump | grep RENME | tail -n 5
13691         rm -f $longname2
13692 }
13693 run_test 160b "Verify that very long rename doesn't crash in changelog"
13694
13695 test_160c() {
13696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13697         remote_mds_nodsh && skip "remote MDS with nodsh"
13698
13699         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
13700                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
13701                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
13702                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
13703
13704         local rc=0
13705
13706         # Registration step
13707         changelog_register || error "changelog_register failed"
13708
13709         rm -rf $DIR/$tdir
13710         mkdir -p $DIR/$tdir
13711         $MCREATE $DIR/$tdir/foo_160c
13712         changelog_chmask "-TRUNC"
13713         $TRUNCATE $DIR/$tdir/foo_160c 200
13714         changelog_chmask "+TRUNC"
13715         $TRUNCATE $DIR/$tdir/foo_160c 199
13716         changelog_dump | tail -n 5
13717         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
13718         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
13719 }
13720 run_test 160c "verify that changelog log catch the truncate event"
13721
13722 test_160d() {
13723         remote_mds_nodsh && skip "remote MDS with nodsh"
13724         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13726         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
13727                 skip "Need MDS version at least 2.7.60"
13728
13729         # Registration step
13730         changelog_register || error "changelog_register failed"
13731
13732         mkdir -p $DIR/$tdir/migrate_dir
13733         changelog_clear 0 || error "changelog_clear failed"
13734
13735         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
13736         changelog_dump | tail -n 5
13737         local migrates=$(changelog_dump | grep -c "MIGRT")
13738         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
13739 }
13740 run_test 160d "verify that changelog log catch the migrate event"
13741
13742 test_160e() {
13743         remote_mds_nodsh && skip "remote MDS with nodsh"
13744
13745         # Create a user
13746         changelog_register || error "changelog_register failed"
13747
13748         # Delete a future user (expect fail)
13749         local MDT0=$(facet_svc $SINGLEMDS)
13750         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
13751         local rc=$?
13752
13753         if [ $rc -eq 0 ]; then
13754                 error "Deleted non-existant user cl77"
13755         elif [ $rc -ne 2 ]; then
13756                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
13757         fi
13758
13759         # Clear to a bad index (1 billion should be safe)
13760         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
13761         rc=$?
13762
13763         if [ $rc -eq 0 ]; then
13764                 error "Successfully cleared to invalid CL index"
13765         elif [ $rc -ne 22 ]; then
13766                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
13767         fi
13768 }
13769 run_test 160e "changelog negative testing (should return errors)"
13770
13771 test_160f() {
13772         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13773         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13774                 skip "Need MDS version at least 2.10.56"
13775
13776         local mdts=$(comma_list $(mdts_nodes))
13777
13778         # Create a user
13779         changelog_register || error "first changelog_register failed"
13780         changelog_register || error "second changelog_register failed"
13781         local cl_users
13782         declare -A cl_user1
13783         declare -A cl_user2
13784         local user_rec1
13785         local user_rec2
13786         local i
13787
13788         # generate some changelog records to accumulate on each MDT
13789         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13790         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13791                 error "create $DIR/$tdir/$tfile failed"
13792
13793         # check changelogs have been generated
13794         local nbcl=$(changelog_dump | wc -l)
13795         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13796
13797         for param in "changelog_max_idle_time=10" \
13798                      "changelog_gc=1" \
13799                      "changelog_min_gc_interval=2" \
13800                      "changelog_min_free_cat_entries=3"; do
13801                 local MDT0=$(facet_svc $SINGLEMDS)
13802                 local var="${param%=*}"
13803                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13804
13805                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13806                 do_nodes $mdts $LCTL set_param mdd.*.$param
13807         done
13808
13809         # force cl_user2 to be idle (1st part)
13810         sleep 9
13811
13812         # simulate changelog catalog almost full
13813         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13814         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13815
13816         for i in $(seq $MDSCOUNT); do
13817                 cl_users=(${CL_USERS[mds$i]})
13818                 cl_user1[mds$i]="${cl_users[0]}"
13819                 cl_user2[mds$i]="${cl_users[1]}"
13820
13821                 [ -n "${cl_user1[mds$i]}" ] ||
13822                         error "mds$i: no user registered"
13823                 [ -n "${cl_user2[mds$i]}" ] ||
13824                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13825
13826                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13827                 [ -n "$user_rec1" ] ||
13828                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13829                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13830                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13831                 [ -n "$user_rec2" ] ||
13832                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13833                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13834                      "$user_rec1 + 2 == $user_rec2"
13835                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13836                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13837                               "$user_rec1 + 2, but is $user_rec2"
13838                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13839                 [ -n "$user_rec2" ] ||
13840                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13841                 [ $user_rec1 == $user_rec2 ] ||
13842                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13843                               "$user_rec1, but is $user_rec2"
13844         done
13845
13846         # force cl_user2 to be idle (2nd part) and to reach
13847         # changelog_max_idle_time
13848         sleep 2
13849
13850         # generate one more changelog to trigger fail_loc
13851         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13852                 error "create $DIR/$tdir/${tfile}bis failed"
13853
13854         # ensure gc thread is done
13855         for i in $(mdts_nodes); do
13856                 wait_update $i \
13857                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13858                         error "$i: GC-thread not done"
13859         done
13860
13861         local first_rec
13862         for i in $(seq $MDSCOUNT); do
13863                 # check cl_user1 still registered
13864                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13865                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13866                 # check cl_user2 unregistered
13867                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13868                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13869
13870                 # check changelogs are present and starting at $user_rec1 + 1
13871                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13872                 [ -n "$user_rec1" ] ||
13873                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13874                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13875                             awk '{ print $1; exit; }')
13876
13877                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13878                 [ $((user_rec1 + 1)) == $first_rec ] ||
13879                         error "mds$i: first index should be $user_rec1 + 1, " \
13880                               "but is $first_rec"
13881         done
13882 }
13883 run_test 160f "changelog garbage collect (timestamped users)"
13884
13885 test_160g() {
13886         remote_mds_nodsh && skip "remote MDS with nodsh"
13887         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13888                 skip "Need MDS version at least 2.10.56"
13889
13890         local mdts=$(comma_list $(mdts_nodes))
13891
13892         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
13893         do_nodes $mdts $LCTL set_param fail_loc=0x1314
13894
13895         # Create a user
13896         changelog_register || error "first changelog_register failed"
13897         changelog_register || error "second changelog_register failed"
13898         local cl_users
13899         declare -A cl_user1
13900         declare -A cl_user2
13901         local user_rec1
13902         local user_rec2
13903         local i
13904
13905         # generate some changelog records to accumulate on each MDT
13906         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13907         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13908                 error "create $DIR/$tdir/$tfile failed"
13909
13910         # check changelogs have been generated
13911         local nbcl=$(changelog_dump | wc -l)
13912         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13913
13914         # reduce the max_idle_indexes value to make sure we exceed it
13915         max_ndx=$((nbcl / 2 - 1))
13916
13917         for param in "changelog_max_idle_indexes=$max_ndx" \
13918                      "changelog_gc=1" \
13919                      "changelog_min_gc_interval=2" \
13920                      "changelog_min_free_cat_entries=3"; do
13921                 local MDT0=$(facet_svc $SINGLEMDS)
13922                 local var="${param%=*}"
13923                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13924
13925                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13926                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
13927                         error "unable to set mdd.*.$param"
13928         done
13929
13930         # simulate changelog catalog almost full
13931         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13932         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13933
13934         for i in $(seq $MDSCOUNT); do
13935                 cl_users=(${CL_USERS[mds$i]})
13936                 cl_user1[mds$i]="${cl_users[0]}"
13937                 cl_user2[mds$i]="${cl_users[1]}"
13938
13939                 [ -n "${cl_user1[mds$i]}" ] ||
13940                         error "mds$i: no user registered"
13941                 [ -n "${cl_user2[mds$i]}" ] ||
13942                         error "mds$i: only ${cl_user1[mds$i]} is registered"
13943
13944                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13945                 [ -n "$user_rec1" ] ||
13946                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13947                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13948                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13949                 [ -n "$user_rec2" ] ||
13950                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13951                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13952                      "$user_rec1 + 2 == $user_rec2"
13953                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13954                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13955                               "$user_rec1 + 2, but is $user_rec2"
13956                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13957                 [ -n "$user_rec2" ] ||
13958                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13959                 [ $user_rec1 == $user_rec2 ] ||
13960                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13961                               "$user_rec1, but is $user_rec2"
13962         done
13963
13964         # ensure we are past the previous changelog_min_gc_interval set above
13965         sleep 2
13966
13967         # generate one more changelog to trigger fail_loc
13968         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13969                 error "create $DIR/$tdir/${tfile}bis failed"
13970
13971         # ensure gc thread is done
13972         for i in $(mdts_nodes); do
13973                 wait_update $i \
13974                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13975                         error "$i: GC-thread not done"
13976         done
13977
13978         local first_rec
13979         for i in $(seq $MDSCOUNT); do
13980                 # check cl_user1 still registered
13981                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13982                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13983                 # check cl_user2 unregistered
13984                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13985                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13986
13987                 # check changelogs are present and starting at $user_rec1 + 1
13988                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13989                 [ -n "$user_rec1" ] ||
13990                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13991                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13992                             awk '{ print $1; exit; }')
13993
13994                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13995                 [ $((user_rec1 + 1)) == $first_rec ] ||
13996                         error "mds$i: first index should be $user_rec1 + 1, " \
13997                               "but is $first_rec"
13998         done
13999 }
14000 run_test 160g "changelog garbage collect (old users)"
14001
14002 test_160h() {
14003         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14004         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14005                 skip "Need MDS version at least 2.10.56"
14006
14007         local mdts=$(comma_list $(mdts_nodes))
14008
14009         # Create a user
14010         changelog_register || error "first changelog_register failed"
14011         changelog_register || error "second changelog_register failed"
14012         local cl_users
14013         declare -A cl_user1
14014         declare -A cl_user2
14015         local user_rec1
14016         local user_rec2
14017         local i
14018
14019         # generate some changelog records to accumulate on each MDT
14020         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
14021         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14022                 error "create $DIR/$tdir/$tfile failed"
14023
14024         # check changelogs have been generated
14025         local nbcl=$(changelog_dump | wc -l)
14026         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14027
14028         for param in "changelog_max_idle_time=10" \
14029                      "changelog_gc=1" \
14030                      "changelog_min_gc_interval=2"; do
14031                 local MDT0=$(facet_svc $SINGLEMDS)
14032                 local var="${param%=*}"
14033                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14034
14035                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14036                 do_nodes $mdts $LCTL set_param mdd.*.$param
14037         done
14038
14039         # force cl_user2 to be idle (1st part)
14040         sleep 9
14041
14042         for i in $(seq $MDSCOUNT); do
14043                 cl_users=(${CL_USERS[mds$i]})
14044                 cl_user1[mds$i]="${cl_users[0]}"
14045                 cl_user2[mds$i]="${cl_users[1]}"
14046
14047                 [ -n "${cl_user1[mds$i]}" ] ||
14048                         error "mds$i: no user registered"
14049                 [ -n "${cl_user2[mds$i]}" ] ||
14050                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14051
14052                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14053                 [ -n "$user_rec1" ] ||
14054                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14055                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14056                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14057                 [ -n "$user_rec2" ] ||
14058                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14059                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14060                      "$user_rec1 + 2 == $user_rec2"
14061                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14062                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14063                               "$user_rec1 + 2, but is $user_rec2"
14064                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14065                 [ -n "$user_rec2" ] ||
14066                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14067                 [ $user_rec1 == $user_rec2 ] ||
14068                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14069                               "$user_rec1, but is $user_rec2"
14070         done
14071
14072         # force cl_user2 to be idle (2nd part) and to reach
14073         # changelog_max_idle_time
14074         sleep 2
14075
14076         # force each GC-thread start and block then
14077         # one per MDT/MDD, set fail_val accordingly
14078         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14079         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14080
14081         # generate more changelogs to trigger fail_loc
14082         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14083                 error "create $DIR/$tdir/${tfile}bis failed"
14084
14085         # stop MDT to stop GC-thread, should be done in back-ground as it will
14086         # block waiting for the thread to be released and exit
14087         declare -A stop_pids
14088         for i in $(seq $MDSCOUNT); do
14089                 stop mds$i &
14090                 stop_pids[mds$i]=$!
14091         done
14092
14093         for i in $(mdts_nodes); do
14094                 local facet
14095                 local nb=0
14096                 local facets=$(facets_up_on_host $i)
14097
14098                 for facet in ${facets//,/ }; do
14099                         if [[ $facet == mds* ]]; then
14100                                 nb=$((nb + 1))
14101                         fi
14102                 done
14103                 # ensure each MDS's gc threads are still present and all in "R"
14104                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14105                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14106                         error "$i: expected $nb GC-thread"
14107                 wait_update $i \
14108                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14109                         "R" 20 ||
14110                         error "$i: GC-thread not found in R-state"
14111                 # check umounts of each MDT on MDS have reached kthread_stop()
14112                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14113                         error "$i: expected $nb umount"
14114                 wait_update $i \
14115                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14116                         error "$i: umount not found in D-state"
14117         done
14118
14119         # release all GC-threads
14120         do_nodes $mdts $LCTL set_param fail_loc=0
14121
14122         # wait for MDT stop to complete
14123         for i in $(seq $MDSCOUNT); do
14124                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14125         done
14126
14127         # XXX
14128         # may try to check if any orphan changelog records are present
14129         # via ldiskfs/zfs and llog_reader...
14130
14131         # re-start/mount MDTs
14132         for i in $(seq $MDSCOUNT); do
14133                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14134                         error "Fail to start mds$i"
14135         done
14136
14137         local first_rec
14138         for i in $(seq $MDSCOUNT); do
14139                 # check cl_user1 still registered
14140                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14141                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14142                 # check cl_user2 unregistered
14143                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14144                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14145
14146                 # check changelogs are present and starting at $user_rec1 + 1
14147                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14148                 [ -n "$user_rec1" ] ||
14149                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14150                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14151                             awk '{ print $1; exit; }')
14152
14153                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14154                 [ $((user_rec1 + 1)) == $first_rec ] ||
14155                         error "mds$i: first index should be $user_rec1 + 1, " \
14156                               "but is $first_rec"
14157         done
14158 }
14159 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14160               "during mount"
14161
14162 test_160i() {
14163
14164         local mdts=$(comma_list $(mdts_nodes))
14165
14166         changelog_register || error "first changelog_register failed"
14167
14168         # generate some changelog records to accumulate on each MDT
14169         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
14170         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14171                 error "create $DIR/$tdir/$tfile failed"
14172
14173         # check changelogs have been generated
14174         local nbcl=$(changelog_dump | wc -l)
14175         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14176
14177         # simulate race between register and unregister
14178         # XXX as fail_loc is set per-MDS, with DNE configs the race
14179         # simulation will only occur for one MDT per MDS and for the
14180         # others the normal race scenario will take place
14181         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14182         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14183         do_nodes $mdts $LCTL set_param fail_val=1
14184
14185         # unregister 1st user
14186         changelog_deregister &
14187         local pid1=$!
14188         # wait some time for deregister work to reach race rdv
14189         sleep 2
14190         # register 2nd user
14191         changelog_register || error "2nd user register failed"
14192
14193         wait $pid1 || error "1st user deregister failed"
14194
14195         local i
14196         local last_rec
14197         declare -A LAST_REC
14198         for i in $(seq $MDSCOUNT); do
14199                 if changelog_users mds$i | grep "^cl"; then
14200                         # make sure new records are added with one user present
14201                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14202                                           awk '/^current.index:/ { print $NF }')
14203                 else
14204                         error "mds$i has no user registered"
14205                 fi
14206         done
14207
14208         # generate more changelog records to accumulate on each MDT
14209         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14210                 error "create $DIR/$tdir/${tfile}bis failed"
14211
14212         for i in $(seq $MDSCOUNT); do
14213                 last_rec=$(changelog_users $SINGLEMDS |
14214                            awk '/^current.index:/ { print $NF }')
14215                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14216                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14217                         error "changelogs are off on mds$i"
14218         done
14219 }
14220 run_test 160i "changelog user register/unregister race"
14221
14222 test_160j() {
14223         remote_mds_nodsh && skip "remote MDS with nodsh"
14224         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14225                 skip "Need MDS version at least 2.12.56"
14226
14227         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14228
14229         changelog_register || error "first changelog_register failed"
14230
14231         # generate some changelog
14232         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
14233         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14234                 error "create $DIR/$tdir/${tfile}bis failed"
14235
14236         # open the changelog device
14237         exec 3>/dev/changelog-$FSNAME-MDT0000
14238         exec 4</dev/changelog-$FSNAME-MDT0000
14239
14240         # umount the first lustre mount
14241         umount $MOUNT
14242
14243         # read changelog
14244         cat <&4 >/dev/null || error "read changelog failed"
14245
14246         # clear changelog
14247         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14248         changelog_users $SINGLEMDS | grep -q $cl_user ||
14249                 error "User $cl_user not found in changelog_users"
14250
14251         printf 'clear:'$cl_user':0' >&3
14252
14253         # close
14254         exec 3>&-
14255         exec 4<&-
14256
14257         # cleanup
14258         changelog_deregister || error "changelog_deregister failed"
14259
14260         umount $MOUNT2
14261         mount_client $MOUNT || error "mount_client on $MOUNT failed"
14262 }
14263 run_test 160j "client can be umounted  while its chanangelog is being used"
14264
14265 test_160k() {
14266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14267         remote_mds_nodsh && skip "remote MDS with nodsh"
14268
14269         mkdir -p $DIR/$tdir/1/1
14270
14271         changelog_register || error "changelog_register failed"
14272         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14273
14274         changelog_users $SINGLEMDS | grep -q $cl_user ||
14275                 error "User '$cl_user' not found in changelog_users"
14276 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14277         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
14278         rmdir $DIR/$tdir/1/1 & sleep 1
14279         mkdir $DIR/$tdir/2
14280         touch $DIR/$tdir/2/2
14281         rm -rf $DIR/$tdir/2
14282
14283         wait
14284         sleep 4
14285
14286         changelog_dump | grep rmdir || error "rmdir not recorded"
14287
14288         rm -rf $DIR/$tdir
14289         changelog_deregister
14290 }
14291 run_test 160k "Verify that changelog records are not lost"
14292
14293 test_161a() {
14294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14295
14296         test_mkdir -c1 $DIR/$tdir
14297         cp /etc/hosts $DIR/$tdir/$tfile
14298         test_mkdir -c1 $DIR/$tdir/foo1
14299         test_mkdir -c1 $DIR/$tdir/foo2
14300         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
14301         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
14302         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
14303         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
14304         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
14305         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14306                 $LFS fid2path $DIR $FID
14307                 error "bad link ea"
14308         fi
14309         # middle
14310         rm $DIR/$tdir/foo2/zachary
14311         # last
14312         rm $DIR/$tdir/foo2/thor
14313         # first
14314         rm $DIR/$tdir/$tfile
14315         # rename
14316         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
14317         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
14318                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
14319         rm $DIR/$tdir/foo2/maggie
14320
14321         # overflow the EA
14322         local longname=$tfile.avg_len_is_thirty_two_
14323         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
14324                 error_noexit 'failed to unlink many hardlinks'" EXIT
14325         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
14326                 error "failed to hardlink many files"
14327         links=$($LFS fid2path $DIR $FID | wc -l)
14328         echo -n "${links}/1000 links in link EA"
14329         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
14330 }
14331 run_test 161a "link ea sanity"
14332
14333 test_161b() {
14334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14335         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
14336
14337         local MDTIDX=1
14338         local remote_dir=$DIR/$tdir/remote_dir
14339
14340         mkdir -p $DIR/$tdir
14341         $LFS mkdir -i $MDTIDX $remote_dir ||
14342                 error "create remote directory failed"
14343
14344         cp /etc/hosts $remote_dir/$tfile
14345         mkdir -p $remote_dir/foo1
14346         mkdir -p $remote_dir/foo2
14347         ln $remote_dir/$tfile $remote_dir/foo1/sofia
14348         ln $remote_dir/$tfile $remote_dir/foo2/zachary
14349         ln $remote_dir/$tfile $remote_dir/foo1/luna
14350         ln $remote_dir/$tfile $remote_dir/foo2/thor
14351
14352         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
14353                      tr -d ']')
14354         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14355                 $LFS fid2path $DIR $FID
14356                 error "bad link ea"
14357         fi
14358         # middle
14359         rm $remote_dir/foo2/zachary
14360         # last
14361         rm $remote_dir/foo2/thor
14362         # first
14363         rm $remote_dir/$tfile
14364         # rename
14365         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
14366         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
14367         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
14368                 $LFS fid2path $DIR $FID
14369                 error "bad link rename"
14370         fi
14371         rm $remote_dir/foo2/maggie
14372
14373         # overflow the EA
14374         local longname=filename_avg_len_is_thirty_two_
14375         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
14376                 error "failed to hardlink many files"
14377         links=$($LFS fid2path $DIR $FID | wc -l)
14378         echo -n "${links}/1000 links in link EA"
14379         [[ ${links} -gt 60 ]] ||
14380                 error "expected at least 60 links in link EA"
14381         unlinkmany $remote_dir/foo2/$longname 1000 ||
14382         error "failed to unlink many hardlinks"
14383 }
14384 run_test 161b "link ea sanity under remote directory"
14385
14386 test_161c() {
14387         remote_mds_nodsh && skip "remote MDS with nodsh"
14388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14389         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
14390                 skip "Need MDS version at least 2.1.5"
14391
14392         # define CLF_RENAME_LAST 0x0001
14393         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
14394         changelog_register || error "changelog_register failed"
14395
14396         rm -rf $DIR/$tdir
14397         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
14398         touch $DIR/$tdir/foo_161c
14399         touch $DIR/$tdir/bar_161c
14400         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14401         changelog_dump | grep RENME | tail -n 5
14402         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14403         changelog_clear 0 || error "changelog_clear failed"
14404         if [ x$flags != "x0x1" ]; then
14405                 error "flag $flags is not 0x1"
14406         fi
14407
14408         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
14409         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
14410         touch $DIR/$tdir/foo_161c
14411         touch $DIR/$tdir/bar_161c
14412         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14413         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14414         changelog_dump | grep RENME | tail -n 5
14415         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14416         changelog_clear 0 || error "changelog_clear failed"
14417         if [ x$flags != "x0x0" ]; then
14418                 error "flag $flags is not 0x0"
14419         fi
14420         echo "rename overwrite a target having nlink > 1," \
14421                 "changelog record has flags of $flags"
14422
14423         # rename doesn't overwrite a target (changelog flag 0x0)
14424         touch $DIR/$tdir/foo_161c
14425         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
14426         changelog_dump | grep RENME | tail -n 5
14427         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
14428         changelog_clear 0 || error "changelog_clear failed"
14429         if [ x$flags != "x0x0" ]; then
14430                 error "flag $flags is not 0x0"
14431         fi
14432         echo "rename doesn't overwrite a target," \
14433                 "changelog record has flags of $flags"
14434
14435         # define CLF_UNLINK_LAST 0x0001
14436         # unlink a file having nlink = 1 (changelog flag 0x1)
14437         rm -f $DIR/$tdir/foo2_161c
14438         changelog_dump | grep UNLNK | tail -n 5
14439         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14440         changelog_clear 0 || error "changelog_clear failed"
14441         if [ x$flags != "x0x1" ]; then
14442                 error "flag $flags is not 0x1"
14443         fi
14444         echo "unlink a file having nlink = 1," \
14445                 "changelog record has flags of $flags"
14446
14447         # unlink a file having nlink > 1 (changelog flag 0x0)
14448         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14449         rm -f $DIR/$tdir/foobar_161c
14450         changelog_dump | grep UNLNK | tail -n 5
14451         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14452         changelog_clear 0 || error "changelog_clear failed"
14453         if [ x$flags != "x0x0" ]; then
14454                 error "flag $flags is not 0x0"
14455         fi
14456         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
14457 }
14458 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
14459
14460 test_161d() {
14461         remote_mds_nodsh && skip "remote MDS with nodsh"
14462         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
14463
14464         local pid
14465         local fid
14466
14467         changelog_register || error "changelog_register failed"
14468
14469         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
14470         # interfer with $MOUNT/.lustre/fid/ access
14471         mkdir $DIR/$tdir
14472         [[ $? -eq 0 ]] || error "mkdir failed"
14473
14474         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
14475         $LCTL set_param fail_loc=0x8000140c
14476         # 5s pause
14477         $LCTL set_param fail_val=5
14478
14479         # create file
14480         echo foofoo > $DIR/$tdir/$tfile &
14481         pid=$!
14482
14483         # wait for create to be delayed
14484         sleep 2
14485
14486         ps -p $pid
14487         [[ $? -eq 0 ]] || error "create should be blocked"
14488
14489         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
14490         stack_trap "rm -f $tempfile"
14491         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
14492         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
14493         # some delay may occur during ChangeLog publishing and file read just
14494         # above, that could allow file write to happen finally
14495         [[ -s $tempfile ]] && echo "file should be empty"
14496
14497         $LCTL set_param fail_loc=0
14498
14499         wait $pid
14500         [[ $? -eq 0 ]] || error "create failed"
14501 }
14502 run_test 161d "create with concurrent .lustre/fid access"
14503
14504 check_path() {
14505         local expected="$1"
14506         shift
14507         local fid="$2"
14508
14509         local path
14510         path=$($LFS fid2path "$@")
14511         local rc=$?
14512
14513         if [ $rc -ne 0 ]; then
14514                 error "path looked up of '$expected' failed: rc=$rc"
14515         elif [ "$path" != "$expected" ]; then
14516                 error "path looked up '$path' instead of '$expected'"
14517         else
14518                 echo "FID '$fid' resolves to path '$path' as expected"
14519         fi
14520 }
14521
14522 test_162a() { # was test_162
14523         test_mkdir -p -c1 $DIR/$tdir/d2
14524         touch $DIR/$tdir/d2/$tfile
14525         touch $DIR/$tdir/d2/x1
14526         touch $DIR/$tdir/d2/x2
14527         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
14528         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
14529         # regular file
14530         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
14531         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
14532
14533         # softlink
14534         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
14535         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
14536         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
14537
14538         # softlink to wrong file
14539         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
14540         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
14541         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
14542
14543         # hardlink
14544         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
14545         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
14546         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
14547         # fid2path dir/fsname should both work
14548         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
14549         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
14550
14551         # hardlink count: check that there are 2 links
14552         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
14553         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
14554
14555         # hardlink indexing: remove the first link
14556         rm $DIR/$tdir/d2/p/q/r/hlink
14557         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
14558 }
14559 run_test 162a "path lookup sanity"
14560
14561 test_162b() {
14562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14563         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14564
14565         mkdir $DIR/$tdir
14566         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
14567                                 error "create striped dir failed"
14568
14569         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
14570                                         tail -n 1 | awk '{print $2}')
14571         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
14572
14573         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
14574         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
14575
14576         # regular file
14577         for ((i=0;i<5;i++)); do
14578                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
14579                         error "get fid for f$i failed"
14580                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
14581
14582                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
14583                         error "get fid for d$i failed"
14584                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
14585         done
14586
14587         return 0
14588 }
14589 run_test 162b "striped directory path lookup sanity"
14590
14591 # LU-4239: Verify fid2path works with paths 100 or more directories deep
14592 test_162c() {
14593         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
14594                 skip "Need MDS version at least 2.7.51"
14595
14596         local lpath=$tdir.local
14597         local rpath=$tdir.remote
14598
14599         test_mkdir $DIR/$lpath
14600         test_mkdir $DIR/$rpath
14601
14602         for ((i = 0; i <= 101; i++)); do
14603                 lpath="$lpath/$i"
14604                 mkdir $DIR/$lpath
14605                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
14606                         error "get fid for local directory $DIR/$lpath failed"
14607                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
14608
14609                 rpath="$rpath/$i"
14610                 test_mkdir $DIR/$rpath
14611                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
14612                         error "get fid for remote directory $DIR/$rpath failed"
14613                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
14614         done
14615
14616         return 0
14617 }
14618 run_test 162c "fid2path works with paths 100 or more directories deep"
14619
14620 test_169() {
14621         # do directio so as not to populate the page cache
14622         log "creating a 10 Mb file"
14623         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14624         log "starting reads"
14625         dd if=$DIR/$tfile of=/dev/null bs=4096 &
14626         log "truncating the file"
14627         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14628         log "killing dd"
14629         kill %+ || true # reads might have finished
14630         echo "wait until dd is finished"
14631         wait
14632         log "removing the temporary file"
14633         rm -rf $DIR/$tfile || error "tmp file removal failed"
14634 }
14635 run_test 169 "parallel read and truncate should not deadlock"
14636
14637 test_170() {
14638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14639
14640         $LCTL clear     # bug 18514
14641         $LCTL debug_daemon start $TMP/${tfile}_log_good
14642         touch $DIR/$tfile
14643         $LCTL debug_daemon stop
14644         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
14645                 error "sed failed to read log_good"
14646
14647         $LCTL debug_daemon start $TMP/${tfile}_log_good
14648         rm -rf $DIR/$tfile
14649         $LCTL debug_daemon stop
14650
14651         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
14652                error "lctl df log_bad failed"
14653
14654         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14655         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14656
14657         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
14658         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
14659
14660         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
14661                 error "bad_line good_line1 good_line2 are empty"
14662
14663         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14664         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
14665         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14666
14667         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
14668         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14669         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14670
14671         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
14672                 error "bad_line_new good_line_new are empty"
14673
14674         local expected_good=$((good_line1 + good_line2*2))
14675
14676         rm -f $TMP/${tfile}*
14677         # LU-231, short malformed line may not be counted into bad lines
14678         if [ $bad_line -ne $bad_line_new ] &&
14679                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
14680                 error "expected $bad_line bad lines, but got $bad_line_new"
14681                 return 1
14682         fi
14683
14684         if [ $expected_good -ne $good_line_new ]; then
14685                 error "expected $expected_good good lines, but got $good_line_new"
14686                 return 2
14687         fi
14688         true
14689 }
14690 run_test 170 "test lctl df to handle corrupted log ====================="
14691
14692 test_171() { # bug20592
14693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14694
14695         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
14696         $LCTL set_param fail_loc=0x50e
14697         $LCTL set_param fail_val=3000
14698         multiop_bg_pause $DIR/$tfile O_s || true
14699         local MULTIPID=$!
14700         kill -USR1 $MULTIPID
14701         # cause log dump
14702         sleep 3
14703         wait $MULTIPID
14704         if dmesg | grep "recursive fault"; then
14705                 error "caught a recursive fault"
14706         fi
14707         $LCTL set_param fail_loc=0
14708         true
14709 }
14710 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
14711
14712 # it would be good to share it with obdfilter-survey/iokit-libecho code
14713 setup_obdecho_osc () {
14714         local rc=0
14715         local ost_nid=$1
14716         local obdfilter_name=$2
14717         echo "Creating new osc for $obdfilter_name on $ost_nid"
14718         # make sure we can find loopback nid
14719         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
14720
14721         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
14722                            ${obdfilter_name}_osc_UUID || rc=2; }
14723         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
14724                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
14725         return $rc
14726 }
14727
14728 cleanup_obdecho_osc () {
14729         local obdfilter_name=$1
14730         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
14731         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
14732         return 0
14733 }
14734
14735 obdecho_test() {
14736         local OBD=$1
14737         local node=$2
14738         local pages=${3:-64}
14739         local rc=0
14740         local id
14741
14742         local count=10
14743         local obd_size=$(get_obd_size $node $OBD)
14744         local page_size=$(get_page_size $node)
14745         if [[ -n "$obd_size" ]]; then
14746                 local new_count=$((obd_size / (pages * page_size / 1024)))
14747                 [[ $new_count -ge $count ]] || count=$new_count
14748         fi
14749
14750         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
14751         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
14752                            rc=2; }
14753         if [ $rc -eq 0 ]; then
14754             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
14755             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
14756         fi
14757         echo "New object id is $id"
14758         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
14759                            rc=4; }
14760         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
14761                            "test_brw $count w v $pages $id" || rc=4; }
14762         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
14763                            rc=4; }
14764         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
14765                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
14766         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
14767                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
14768         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
14769         return $rc
14770 }
14771
14772 test_180a() {
14773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14774
14775         if ! module_loaded obdecho; then
14776                 load_module obdecho/obdecho &&
14777                         stack_trap "rmmod obdecho" EXIT ||
14778                         error "unable to load obdecho on client"
14779         fi
14780
14781         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
14782         local host=$($LCTL get_param -n osc.$osc.import |
14783                      awk '/current_connection:/ { print $2 }' )
14784         local target=$($LCTL get_param -n osc.$osc.import |
14785                        awk '/target:/ { print $2 }' )
14786         target=${target%_UUID}
14787
14788         if [ -n "$target" ]; then
14789                 setup_obdecho_osc $host $target &&
14790                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
14791                         { error "obdecho setup failed with $?"; return; }
14792
14793                 obdecho_test ${target}_osc client ||
14794                         error "obdecho_test failed on ${target}_osc"
14795         else
14796                 $LCTL get_param osc.$osc.import
14797                 error "there is no osc.$osc.import target"
14798         fi
14799 }
14800 run_test 180a "test obdecho on osc"
14801
14802 test_180b() {
14803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14804         remote_ost_nodsh && skip "remote OST with nodsh"
14805
14806         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14807                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14808                 error "failed to load module obdecho"
14809
14810         local target=$(do_facet ost1 $LCTL dl |
14811                        awk '/obdfilter/ { print $4; exit; }')
14812
14813         if [ -n "$target" ]; then
14814                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
14815         else
14816                 do_facet ost1 $LCTL dl
14817                 error "there is no obdfilter target on ost1"
14818         fi
14819 }
14820 run_test 180b "test obdecho directly on obdfilter"
14821
14822 test_180c() { # LU-2598
14823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14824         remote_ost_nodsh && skip "remote OST with nodsh"
14825         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
14826                 skip "Need MDS version at least 2.4.0"
14827
14828         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14829                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14830                 error "failed to load module obdecho"
14831
14832         local target=$(do_facet ost1 $LCTL dl |
14833                        awk '/obdfilter/ { print $4; exit; }')
14834
14835         if [ -n "$target" ]; then
14836                 local pages=16384 # 64MB bulk I/O RPC size
14837
14838                 obdecho_test "$target" ost1 "$pages" ||
14839                         error "obdecho_test with pages=$pages failed with $?"
14840         else
14841                 do_facet ost1 $LCTL dl
14842                 error "there is no obdfilter target on ost1"
14843         fi
14844 }
14845 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
14846
14847 test_181() { # bug 22177
14848         test_mkdir $DIR/$tdir
14849         # create enough files to index the directory
14850         createmany -o $DIR/$tdir/foobar 4000
14851         # print attributes for debug purpose
14852         lsattr -d .
14853         # open dir
14854         multiop_bg_pause $DIR/$tdir D_Sc || return 1
14855         MULTIPID=$!
14856         # remove the files & current working dir
14857         unlinkmany $DIR/$tdir/foobar 4000
14858         rmdir $DIR/$tdir
14859         kill -USR1 $MULTIPID
14860         wait $MULTIPID
14861         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
14862         return 0
14863 }
14864 run_test 181 "Test open-unlinked dir ========================"
14865
14866 test_182() {
14867         local fcount=1000
14868         local tcount=10
14869
14870         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14871
14872         $LCTL set_param mdc.*.rpc_stats=clear
14873
14874         for (( i = 0; i < $tcount; i++ )) ; do
14875                 mkdir $DIR/$tdir/$i
14876         done
14877
14878         for (( i = 0; i < $tcount; i++ )) ; do
14879                 createmany -o $DIR/$tdir/$i/f- $fcount &
14880         done
14881         wait
14882
14883         for (( i = 0; i < $tcount; i++ )) ; do
14884                 unlinkmany $DIR/$tdir/$i/f- $fcount &
14885         done
14886         wait
14887
14888         $LCTL get_param mdc.*.rpc_stats
14889
14890         rm -rf $DIR/$tdir
14891 }
14892 run_test 182 "Test parallel modify metadata operations ================"
14893
14894 test_183() { # LU-2275
14895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14896         remote_mds_nodsh && skip "remote MDS with nodsh"
14897         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
14898                 skip "Need MDS version at least 2.3.56"
14899
14900         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14901         echo aaa > $DIR/$tdir/$tfile
14902
14903 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
14904         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
14905
14906         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
14907         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
14908
14909         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
14910
14911         # Flush negative dentry cache
14912         touch $DIR/$tdir/$tfile
14913
14914         # We are not checking for any leaked references here, they'll
14915         # become evident next time we do cleanup with module unload.
14916         rm -rf $DIR/$tdir
14917 }
14918 run_test 183 "No crash or request leak in case of strange dispositions ========"
14919
14920 # test suite 184 is for LU-2016, LU-2017
14921 test_184a() {
14922         check_swap_layouts_support
14923
14924         dir0=$DIR/$tdir/$testnum
14925         test_mkdir -p -c1 $dir0
14926         ref1=/etc/passwd
14927         ref2=/etc/group
14928         file1=$dir0/f1
14929         file2=$dir0/f2
14930         $LFS setstripe -c1 $file1
14931         cp $ref1 $file1
14932         $LFS setstripe -c2 $file2
14933         cp $ref2 $file2
14934         gen1=$($LFS getstripe -g $file1)
14935         gen2=$($LFS getstripe -g $file2)
14936
14937         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
14938         gen=$($LFS getstripe -g $file1)
14939         [[ $gen1 != $gen ]] ||
14940                 "Layout generation on $file1 does not change"
14941         gen=$($LFS getstripe -g $file2)
14942         [[ $gen2 != $gen ]] ||
14943                 "Layout generation on $file2 does not change"
14944
14945         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
14946         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
14947
14948         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
14949 }
14950 run_test 184a "Basic layout swap"
14951
14952 test_184b() {
14953         check_swap_layouts_support
14954
14955         dir0=$DIR/$tdir/$testnum
14956         mkdir -p $dir0 || error "creating dir $dir0"
14957         file1=$dir0/f1
14958         file2=$dir0/f2
14959         file3=$dir0/f3
14960         dir1=$dir0/d1
14961         dir2=$dir0/d2
14962         mkdir $dir1 $dir2
14963         $LFS setstripe -c1 $file1
14964         $LFS setstripe -c2 $file2
14965         $LFS setstripe -c1 $file3
14966         chown $RUNAS_ID $file3
14967         gen1=$($LFS getstripe -g $file1)
14968         gen2=$($LFS getstripe -g $file2)
14969
14970         $LFS swap_layouts $dir1 $dir2 &&
14971                 error "swap of directories layouts should fail"
14972         $LFS swap_layouts $dir1 $file1 &&
14973                 error "swap of directory and file layouts should fail"
14974         $RUNAS $LFS swap_layouts $file1 $file2 &&
14975                 error "swap of file we cannot write should fail"
14976         $LFS swap_layouts $file1 $file3 &&
14977                 error "swap of file with different owner should fail"
14978         /bin/true # to clear error code
14979 }
14980 run_test 184b "Forbidden layout swap (will generate errors)"
14981
14982 test_184c() {
14983         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
14984         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
14985         check_swap_layouts_support
14986
14987         local dir0=$DIR/$tdir/$testnum
14988         mkdir -p $dir0 || error "creating dir $dir0"
14989
14990         local ref1=$dir0/ref1
14991         local ref2=$dir0/ref2
14992         local file1=$dir0/file1
14993         local file2=$dir0/file2
14994         # create a file large enough for the concurrent test
14995         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
14996         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
14997         echo "ref file size: ref1($(stat -c %s $ref1))," \
14998              "ref2($(stat -c %s $ref2))"
14999
15000         cp $ref2 $file2
15001         dd if=$ref1 of=$file1 bs=16k &
15002         local DD_PID=$!
15003
15004         # Make sure dd starts to copy file
15005         while [ ! -f $file1 ]; do sleep 0.1; done
15006
15007         $LFS swap_layouts $file1 $file2
15008         local rc=$?
15009         wait $DD_PID
15010         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
15011         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
15012
15013         # how many bytes copied before swapping layout
15014         local copied=$(stat -c %s $file2)
15015         local remaining=$(stat -c %s $ref1)
15016         remaining=$((remaining - copied))
15017         echo "Copied $copied bytes before swapping layout..."
15018
15019         cmp -n $copied $file1 $ref2 | grep differ &&
15020                 error "Content mismatch [0, $copied) of ref2 and file1"
15021         cmp -n $copied $file2 $ref1 ||
15022                 error "Content mismatch [0, $copied) of ref1 and file2"
15023         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
15024                 error "Content mismatch [$copied, EOF) of ref1 and file1"
15025
15026         # clean up
15027         rm -f $ref1 $ref2 $file1 $file2
15028 }
15029 run_test 184c "Concurrent write and layout swap"
15030
15031 test_184d() {
15032         check_swap_layouts_support
15033         [ -z "$(which getfattr 2>/dev/null)" ] &&
15034                 skip_env "no getfattr command"
15035
15036         local file1=$DIR/$tdir/$tfile-1
15037         local file2=$DIR/$tdir/$tfile-2
15038         local file3=$DIR/$tdir/$tfile-3
15039         local lovea1
15040         local lovea2
15041
15042         mkdir -p $DIR/$tdir
15043         touch $file1 || error "create $file1 failed"
15044         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15045                 error "create $file2 failed"
15046         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15047                 error "create $file3 failed"
15048         lovea1=$(get_layout_param $file1)
15049
15050         $LFS swap_layouts $file2 $file3 ||
15051                 error "swap $file2 $file3 layouts failed"
15052         $LFS swap_layouts $file1 $file2 ||
15053                 error "swap $file1 $file2 layouts failed"
15054
15055         lovea2=$(get_layout_param $file2)
15056         echo "$lovea1"
15057         echo "$lovea2"
15058         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
15059
15060         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15061         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
15062 }
15063 run_test 184d "allow stripeless layouts swap"
15064
15065 test_184e() {
15066         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
15067                 skip "Need MDS version at least 2.6.94"
15068         check_swap_layouts_support
15069         [ -z "$(which getfattr 2>/dev/null)" ] &&
15070                 skip_env "no getfattr command"
15071
15072         local file1=$DIR/$tdir/$tfile-1
15073         local file2=$DIR/$tdir/$tfile-2
15074         local file3=$DIR/$tdir/$tfile-3
15075         local lovea
15076
15077         mkdir -p $DIR/$tdir
15078         touch $file1 || error "create $file1 failed"
15079         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15080                 error "create $file2 failed"
15081         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15082                 error "create $file3 failed"
15083
15084         $LFS swap_layouts $file1 $file2 ||
15085                 error "swap $file1 $file2 layouts failed"
15086
15087         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15088         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
15089
15090         echo 123 > $file1 || error "Should be able to write into $file1"
15091
15092         $LFS swap_layouts $file1 $file3 ||
15093                 error "swap $file1 $file3 layouts failed"
15094
15095         echo 123 > $file1 || error "Should be able to write into $file1"
15096
15097         rm -rf $file1 $file2 $file3
15098 }
15099 run_test 184e "Recreate layout after stripeless layout swaps"
15100
15101 test_184f() {
15102         # Create a file with name longer than sizeof(struct stat) ==
15103         # 144 to see if we can get chars from the file name to appear
15104         # in the returned striping. Note that 'f' == 0x66.
15105         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
15106
15107         mkdir -p $DIR/$tdir
15108         mcreate $DIR/$tdir/$file
15109         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
15110                 error "IOC_MDC_GETFILEINFO returned garbage striping"
15111         fi
15112 }
15113 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
15114
15115 test_185() { # LU-2441
15116         # LU-3553 - no volatile file support in old servers
15117         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
15118                 skip "Need MDS version at least 2.3.60"
15119
15120         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15121         touch $DIR/$tdir/spoo
15122         local mtime1=$(stat -c "%Y" $DIR/$tdir)
15123         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
15124                 error "cannot create/write a volatile file"
15125         [ "$FILESET" == "" ] &&
15126         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
15127                 error "FID is still valid after close"
15128
15129         multiop_bg_pause $DIR/$tdir vVw4096_c
15130         local multi_pid=$!
15131
15132         local OLD_IFS=$IFS
15133         IFS=":"
15134         local fidv=($fid)
15135         IFS=$OLD_IFS
15136         # assume that the next FID for this client is sequential, since stdout
15137         # is unfortunately eaten by multiop_bg_pause
15138         local n=$((${fidv[1]} + 1))
15139         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
15140         if [ "$FILESET" == "" ]; then
15141                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
15142                         error "FID is missing before close"
15143         fi
15144         kill -USR1 $multi_pid
15145         # 1 second delay, so if mtime change we will see it
15146         sleep 1
15147         local mtime2=$(stat -c "%Y" $DIR/$tdir)
15148         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
15149 }
15150 run_test 185 "Volatile file support"
15151
15152 function create_check_volatile() {
15153         local idx=$1
15154         local tgt
15155
15156         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
15157         local PID=$!
15158         sleep 1
15159         local FID=$(cat /tmp/${tfile}.fid)
15160         [ "$FID" == "" ] && error "can't get FID for volatile"
15161         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
15162         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
15163         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
15164         kill -USR1 $PID
15165         wait
15166         sleep 1
15167         cancel_lru_locks mdc # flush opencache
15168         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
15169         return 0
15170 }
15171
15172 test_185a(){
15173         # LU-12516 - volatile creation via .lustre
15174         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
15175                 skip "Need MDS version at least 2.3.55"
15176
15177         create_check_volatile 0
15178         [ $MDSCOUNT -lt 2 ] && return 0
15179
15180         # DNE case
15181         create_check_volatile 1
15182
15183         return 0
15184 }
15185 run_test 185a "Volatile file creation in .lustre/fid/"
15186
15187 test_187a() {
15188         remote_mds_nodsh && skip "remote MDS with nodsh"
15189         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15190                 skip "Need MDS version at least 2.3.0"
15191
15192         local dir0=$DIR/$tdir/$testnum
15193         mkdir -p $dir0 || error "creating dir $dir0"
15194
15195         local file=$dir0/file1
15196         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
15197         local dv1=$($LFS data_version $file)
15198         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
15199         local dv2=$($LFS data_version $file)
15200         [[ $dv1 != $dv2 ]] ||
15201                 error "data version did not change on write $dv1 == $dv2"
15202
15203         # clean up
15204         rm -f $file1
15205 }
15206 run_test 187a "Test data version change"
15207
15208 test_187b() {
15209         remote_mds_nodsh && skip "remote MDS with nodsh"
15210         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15211                 skip "Need MDS version at least 2.3.0"
15212
15213         local dir0=$DIR/$tdir/$testnum
15214         mkdir -p $dir0 || error "creating dir $dir0"
15215
15216         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
15217         [[ ${DV[0]} != ${DV[1]} ]] ||
15218                 error "data version did not change on write"\
15219                       " ${DV[0]} == ${DV[1]}"
15220
15221         # clean up
15222         rm -f $file1
15223 }
15224 run_test 187b "Test data version change on volatile file"
15225
15226 test_200() {
15227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15228         remote_mgs_nodsh && skip "remote MGS with nodsh"
15229         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15230
15231         local POOL=${POOL:-cea1}
15232         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
15233         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
15234         # Pool OST targets
15235         local first_ost=0
15236         local last_ost=$(($OSTCOUNT - 1))
15237         local ost_step=2
15238         local ost_list=$(seq $first_ost $ost_step $last_ost)
15239         local ost_range="$first_ost $last_ost $ost_step"
15240         local test_path=$POOL_ROOT/$POOL_DIR_NAME
15241         local file_dir=$POOL_ROOT/file_tst
15242         local subdir=$test_path/subdir
15243         local rc=0
15244
15245         while : ; do
15246                 # former test_200a test_200b
15247                 pool_add $POOL                          || { rc=$? ; break; }
15248                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
15249                 # former test_200c test_200d
15250                 mkdir -p $test_path
15251                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
15252                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
15253                 mkdir -p $subdir
15254                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
15255                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
15256                                                         || { rc=$? ; break; }
15257                 # former test_200e test_200f
15258                 local files=$((OSTCOUNT*3))
15259                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
15260                                                         || { rc=$? ; break; }
15261                 pool_create_files $POOL $file_dir $files "$ost_list" \
15262                                                         || { rc=$? ; break; }
15263                 # former test_200g test_200h
15264                 pool_lfs_df $POOL                       || { rc=$? ; break; }
15265                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
15266
15267                 # former test_201a test_201b test_201c
15268                 pool_remove_first_target $POOL          || { rc=$? ; break; }
15269
15270                 local f=$test_path/$tfile
15271                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
15272                 pool_remove $POOL $f                    || { rc=$? ; break; }
15273                 break
15274         done
15275
15276         destroy_test_pools
15277
15278         return $rc
15279 }
15280 run_test 200 "OST pools"
15281
15282 # usage: default_attr <count | size | offset>
15283 default_attr() {
15284         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
15285 }
15286
15287 # usage: check_default_stripe_attr
15288 check_default_stripe_attr() {
15289         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
15290         case $1 in
15291         --stripe-count|-c)
15292                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
15293         --stripe-size|-S)
15294                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
15295         --stripe-index|-i)
15296                 EXPECTED=-1;;
15297         *)
15298                 error "unknown getstripe attr '$1'"
15299         esac
15300
15301         [ $ACTUAL == $EXPECTED ] ||
15302                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
15303 }
15304
15305 test_204a() {
15306         test_mkdir $DIR/$tdir
15307         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
15308
15309         check_default_stripe_attr --stripe-count
15310         check_default_stripe_attr --stripe-size
15311         check_default_stripe_attr --stripe-index
15312 }
15313 run_test 204a "Print default stripe attributes"
15314
15315 test_204b() {
15316         test_mkdir $DIR/$tdir
15317         $LFS setstripe --stripe-count 1 $DIR/$tdir
15318
15319         check_default_stripe_attr --stripe-size
15320         check_default_stripe_attr --stripe-index
15321 }
15322 run_test 204b "Print default stripe size and offset"
15323
15324 test_204c() {
15325         test_mkdir $DIR/$tdir
15326         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15327
15328         check_default_stripe_attr --stripe-count
15329         check_default_stripe_attr --stripe-index
15330 }
15331 run_test 204c "Print default stripe count and offset"
15332
15333 test_204d() {
15334         test_mkdir $DIR/$tdir
15335         $LFS setstripe --stripe-index 0 $DIR/$tdir
15336
15337         check_default_stripe_attr --stripe-count
15338         check_default_stripe_attr --stripe-size
15339 }
15340 run_test 204d "Print default stripe count and size"
15341
15342 test_204e() {
15343         test_mkdir $DIR/$tdir
15344         $LFS setstripe -d $DIR/$tdir
15345
15346         check_default_stripe_attr --stripe-count --raw
15347         check_default_stripe_attr --stripe-size --raw
15348         check_default_stripe_attr --stripe-index --raw
15349 }
15350 run_test 204e "Print raw stripe attributes"
15351
15352 test_204f() {
15353         test_mkdir $DIR/$tdir
15354         $LFS setstripe --stripe-count 1 $DIR/$tdir
15355
15356         check_default_stripe_attr --stripe-size --raw
15357         check_default_stripe_attr --stripe-index --raw
15358 }
15359 run_test 204f "Print raw stripe size and offset"
15360
15361 test_204g() {
15362         test_mkdir $DIR/$tdir
15363         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15364
15365         check_default_stripe_attr --stripe-count --raw
15366         check_default_stripe_attr --stripe-index --raw
15367 }
15368 run_test 204g "Print raw stripe count and offset"
15369
15370 test_204h() {
15371         test_mkdir $DIR/$tdir
15372         $LFS setstripe --stripe-index 0 $DIR/$tdir
15373
15374         check_default_stripe_attr --stripe-count --raw
15375         check_default_stripe_attr --stripe-size --raw
15376 }
15377 run_test 204h "Print raw stripe count and size"
15378
15379 # Figure out which job scheduler is being used, if any,
15380 # or use a fake one
15381 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
15382         JOBENV=SLURM_JOB_ID
15383 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
15384         JOBENV=LSB_JOBID
15385 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
15386         JOBENV=PBS_JOBID
15387 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
15388         JOBENV=LOADL_STEP_ID
15389 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
15390         JOBENV=JOB_ID
15391 else
15392         $LCTL list_param jobid_name > /dev/null 2>&1
15393         if [ $? -eq 0 ]; then
15394                 JOBENV=nodelocal
15395         else
15396                 JOBENV=FAKE_JOBID
15397         fi
15398 fi
15399 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
15400
15401 verify_jobstats() {
15402         local cmd=($1)
15403         shift
15404         local facets="$@"
15405
15406 # we don't really need to clear the stats for this test to work, since each
15407 # command has a unique jobid, but it makes debugging easier if needed.
15408 #       for facet in $facets; do
15409 #               local dev=$(convert_facet2label $facet)
15410 #               # clear old jobstats
15411 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
15412 #       done
15413
15414         # use a new JobID for each test, or we might see an old one
15415         [ "$JOBENV" = "FAKE_JOBID" ] &&
15416                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
15417
15418         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
15419
15420         [ "$JOBENV" = "nodelocal" ] && {
15421                 FAKE_JOBID=id.$testnum.%e.$RANDOM
15422                 $LCTL set_param jobid_name=$FAKE_JOBID
15423                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
15424         }
15425
15426         log "Test: ${cmd[*]}"
15427         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
15428
15429         if [ $JOBENV = "FAKE_JOBID" ]; then
15430                 FAKE_JOBID=$JOBVAL ${cmd[*]}
15431         else
15432                 ${cmd[*]}
15433         fi
15434
15435         # all files are created on OST0000
15436         for facet in $facets; do
15437                 local stats="*.$(convert_facet2label $facet).job_stats"
15438
15439                 # strip out libtool wrappers for in-tree executables
15440                 if [ $(do_facet $facet lctl get_param $stats |
15441                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
15442                         do_facet $facet lctl get_param $stats
15443                         error "No jobstats for $JOBVAL found on $facet::$stats"
15444                 fi
15445         done
15446 }
15447
15448 jobstats_set() {
15449         local new_jobenv=$1
15450
15451         set_persistent_param_and_check client "jobid_var" \
15452                 "$FSNAME.sys.jobid_var" $new_jobenv
15453 }
15454
15455 test_205() { # Job stats
15456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15457         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
15458                 skip "Need MDS version with at least 2.7.1"
15459         remote_mgs_nodsh && skip "remote MGS with nodsh"
15460         remote_mds_nodsh && skip "remote MDS with nodsh"
15461         remote_ost_nodsh && skip "remote OST with nodsh"
15462         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
15463                 skip "Server doesn't support jobstats"
15464         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
15465
15466         local old_jobenv=$($LCTL get_param -n jobid_var)
15467         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
15468
15469         if [[ $PERM_CMD == *"set_param -P"* ]]; then
15470                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
15471         else
15472                 stack_trap "do_facet mgs $PERM_CMD \
15473                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
15474         fi
15475         changelog_register
15476
15477         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
15478                                 mdt.*.job_cleanup_interval | head -n 1)
15479         local new_interval=5
15480         do_facet $SINGLEMDS \
15481                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
15482         stack_trap "do_facet $SINGLEMDS \
15483                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
15484         local start=$SECONDS
15485
15486         local cmd
15487         # mkdir
15488         cmd="mkdir $DIR/$tdir"
15489         verify_jobstats "$cmd" "$SINGLEMDS"
15490         # rmdir
15491         cmd="rmdir $DIR/$tdir"
15492         verify_jobstats "$cmd" "$SINGLEMDS"
15493         # mkdir on secondary MDT
15494         if [ $MDSCOUNT -gt 1 ]; then
15495                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
15496                 verify_jobstats "$cmd" "mds2"
15497         fi
15498         # mknod
15499         cmd="mknod $DIR/$tfile c 1 3"
15500         verify_jobstats "$cmd" "$SINGLEMDS"
15501         # unlink
15502         cmd="rm -f $DIR/$tfile"
15503         verify_jobstats "$cmd" "$SINGLEMDS"
15504         # create all files on OST0000 so verify_jobstats can find OST stats
15505         # open & close
15506         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
15507         verify_jobstats "$cmd" "$SINGLEMDS"
15508         # setattr
15509         cmd="touch $DIR/$tfile"
15510         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15511         # write
15512         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
15513         verify_jobstats "$cmd" "ost1"
15514         # read
15515         cancel_lru_locks osc
15516         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
15517         verify_jobstats "$cmd" "ost1"
15518         # truncate
15519         cmd="$TRUNCATE $DIR/$tfile 0"
15520         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15521         # rename
15522         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
15523         verify_jobstats "$cmd" "$SINGLEMDS"
15524         # jobstats expiry - sleep until old stats should be expired
15525         local left=$((new_interval + 5 - (SECONDS - start)))
15526         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
15527                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
15528                         "0" $left
15529         cmd="mkdir $DIR/$tdir.expire"
15530         verify_jobstats "$cmd" "$SINGLEMDS"
15531         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
15532             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
15533
15534         # Ensure that jobid are present in changelog (if supported by MDS)
15535         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
15536                 changelog_dump | tail -10
15537                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
15538                 [ $jobids -eq 9 ] ||
15539                         error "Wrong changelog jobid count $jobids != 9"
15540
15541                 # LU-5862
15542                 JOBENV="disable"
15543                 jobstats_set $JOBENV
15544                 touch $DIR/$tfile
15545                 changelog_dump | grep $tfile
15546                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
15547                 [ $jobids -eq 0 ] ||
15548                         error "Unexpected jobids when jobid_var=$JOBENV"
15549         fi
15550
15551         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
15552         JOBENV="JOBCOMPLEX"
15553         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
15554
15555         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
15556 }
15557 run_test 205 "Verify job stats"
15558
15559 # LU-1480, LU-1773 and LU-1657
15560 test_206() {
15561         mkdir -p $DIR/$tdir
15562         $LFS setstripe -c -1 $DIR/$tdir
15563 #define OBD_FAIL_LOV_INIT 0x1403
15564         $LCTL set_param fail_loc=0xa0001403
15565         $LCTL set_param fail_val=1
15566         touch $DIR/$tdir/$tfile || true
15567 }
15568 run_test 206 "fail lov_init_raid0() doesn't lbug"
15569
15570 test_207a() {
15571         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15572         local fsz=`stat -c %s $DIR/$tfile`
15573         cancel_lru_locks mdc
15574
15575         # do not return layout in getattr intent
15576 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
15577         $LCTL set_param fail_loc=0x170
15578         local sz=`stat -c %s $DIR/$tfile`
15579
15580         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
15581
15582         rm -rf $DIR/$tfile
15583 }
15584 run_test 207a "can refresh layout at glimpse"
15585
15586 test_207b() {
15587         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15588         local cksum=`md5sum $DIR/$tfile`
15589         local fsz=`stat -c %s $DIR/$tfile`
15590         cancel_lru_locks mdc
15591         cancel_lru_locks osc
15592
15593         # do not return layout in getattr intent
15594 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
15595         $LCTL set_param fail_loc=0x171
15596
15597         # it will refresh layout after the file is opened but before read issues
15598         echo checksum is "$cksum"
15599         echo "$cksum" |md5sum -c --quiet || error "file differs"
15600
15601         rm -rf $DIR/$tfile
15602 }
15603 run_test 207b "can refresh layout at open"
15604
15605 test_208() {
15606         # FIXME: in this test suite, only RD lease is used. This is okay
15607         # for now as only exclusive open is supported. After generic lease
15608         # is done, this test suite should be revised. - Jinshan
15609
15610         remote_mds_nodsh && skip "remote MDS with nodsh"
15611         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
15612                 skip "Need MDS version at least 2.4.52"
15613
15614         echo "==== test 1: verify get lease work"
15615         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
15616
15617         echo "==== test 2: verify lease can be broken by upcoming open"
15618         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15619         local PID=$!
15620         sleep 1
15621
15622         $MULTIOP $DIR/$tfile oO_RDONLY:c
15623         kill -USR1 $PID && wait $PID || error "break lease error"
15624
15625         echo "==== test 3: verify lease can't be granted if an open already exists"
15626         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
15627         local PID=$!
15628         sleep 1
15629
15630         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
15631         kill -USR1 $PID && wait $PID || error "open file error"
15632
15633         echo "==== test 4: lease can sustain over recovery"
15634         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
15635         PID=$!
15636         sleep 1
15637
15638         fail mds1
15639
15640         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
15641
15642         echo "==== test 5: lease broken can't be regained by replay"
15643         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15644         PID=$!
15645         sleep 1
15646
15647         # open file to break lease and then recovery
15648         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
15649         fail mds1
15650
15651         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
15652
15653         rm -f $DIR/$tfile
15654 }
15655 run_test 208 "Exclusive open"
15656
15657 test_209() {
15658         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
15659                 skip_env "must have disp_stripe"
15660
15661         touch $DIR/$tfile
15662         sync; sleep 5; sync;
15663
15664         echo 3 > /proc/sys/vm/drop_caches
15665         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15666
15667         # open/close 500 times
15668         for i in $(seq 500); do
15669                 cat $DIR/$tfile
15670         done
15671
15672         echo 3 > /proc/sys/vm/drop_caches
15673         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15674
15675         echo "before: $req_before, after: $req_after"
15676         [ $((req_after - req_before)) -ge 300 ] &&
15677                 error "open/close requests are not freed"
15678         return 0
15679 }
15680 run_test 209 "read-only open/close requests should be freed promptly"
15681
15682 test_212() {
15683         size=`date +%s`
15684         size=$((size % 8192 + 1))
15685         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
15686         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
15687         rm -f $DIR/f212 $DIR/f212.xyz
15688 }
15689 run_test 212 "Sendfile test ============================================"
15690
15691 test_213() {
15692         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
15693         cancel_lru_locks osc
15694         lctl set_param fail_loc=0x8000040f
15695         # generate a read lock
15696         cat $DIR/$tfile > /dev/null
15697         # write to the file, it will try to cancel the above read lock.
15698         cat /etc/hosts >> $DIR/$tfile
15699 }
15700 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
15701
15702 test_214() { # for bug 20133
15703         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
15704         for (( i=0; i < 340; i++ )) ; do
15705                 touch $DIR/$tdir/d214c/a$i
15706         done
15707
15708         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
15709         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
15710         ls $DIR/d214c || error "ls $DIR/d214c failed"
15711         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
15712         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
15713 }
15714 run_test 214 "hash-indexed directory test - bug 20133"
15715
15716 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
15717 create_lnet_proc_files() {
15718         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
15719 }
15720
15721 # counterpart of create_lnet_proc_files
15722 remove_lnet_proc_files() {
15723         rm -f $TMP/lnet_$1.sys
15724 }
15725
15726 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15727 # 3rd arg as regexp for body
15728 check_lnet_proc_stats() {
15729         local l=$(cat "$TMP/lnet_$1" |wc -l)
15730         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
15731
15732         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
15733 }
15734
15735 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15736 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
15737 # optional and can be regexp for 2nd line (lnet.routes case)
15738 check_lnet_proc_entry() {
15739         local blp=2          # blp stands for 'position of 1st line of body'
15740         [ -z "$5" ] || blp=3 # lnet.routes case
15741
15742         local l=$(cat "$TMP/lnet_$1" |wc -l)
15743         # subtracting one from $blp because the body can be empty
15744         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
15745
15746         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
15747                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
15748
15749         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
15750                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
15751
15752         # bail out if any unexpected line happened
15753         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
15754         [ "$?" != 0 ] || error "$2 misformatted"
15755 }
15756
15757 test_215() { # for bugs 18102, 21079, 21517
15758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15759
15760         local N='(0|[1-9][0-9]*)'       # non-negative numeric
15761         local P='[1-9][0-9]*'           # positive numeric
15762         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
15763         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
15764         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
15765         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
15766
15767         local L1 # regexp for 1st line
15768         local L2 # regexp for 2nd line (optional)
15769         local BR # regexp for the rest (body)
15770
15771         # lnet.stats should look as 11 space-separated non-negative numerics
15772         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
15773         create_lnet_proc_files "stats"
15774         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
15775         remove_lnet_proc_files "stats"
15776
15777         # lnet.routes should look like this:
15778         # Routing disabled/enabled
15779         # net hops priority state router
15780         # where net is a string like tcp0, hops > 0, priority >= 0,
15781         # state is up/down,
15782         # router is a string like 192.168.1.1@tcp2
15783         L1="^Routing (disabled|enabled)$"
15784         L2="^net +hops +priority +state +router$"
15785         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
15786         create_lnet_proc_files "routes"
15787         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
15788         remove_lnet_proc_files "routes"
15789
15790         # lnet.routers should look like this:
15791         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
15792         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
15793         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
15794         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
15795         L1="^ref +rtr_ref +alive +router$"
15796         BR="^$P +$P +(up|down) +$NID$"
15797         create_lnet_proc_files "routers"
15798         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
15799         remove_lnet_proc_files "routers"
15800
15801         # lnet.peers should look like this:
15802         # nid refs state last max rtr min tx min queue
15803         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
15804         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
15805         # numeric (0 or >0 or <0), queue >= 0.
15806         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
15807         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
15808         create_lnet_proc_files "peers"
15809         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
15810         remove_lnet_proc_files "peers"
15811
15812         # lnet.buffers  should look like this:
15813         # pages count credits min
15814         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
15815         L1="^pages +count +credits +min$"
15816         BR="^ +$N +$N +$I +$I$"
15817         create_lnet_proc_files "buffers"
15818         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
15819         remove_lnet_proc_files "buffers"
15820
15821         # lnet.nis should look like this:
15822         # nid status alive refs peer rtr max tx min
15823         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
15824         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
15825         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
15826         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
15827         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
15828         create_lnet_proc_files "nis"
15829         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
15830         remove_lnet_proc_files "nis"
15831
15832         # can we successfully write to lnet.stats?
15833         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
15834 }
15835 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
15836
15837 test_216() { # bug 20317
15838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15839         remote_ost_nodsh && skip "remote OST with nodsh"
15840
15841         local node
15842         local facets=$(get_facets OST)
15843         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15844
15845         save_lustre_params client "osc.*.contention_seconds" > $p
15846         save_lustre_params $facets \
15847                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
15848         save_lustre_params $facets \
15849                 "ldlm.namespaces.filter-*.contended_locks" >> $p
15850         save_lustre_params $facets \
15851                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
15852         clear_stats osc.*.osc_stats
15853
15854         # agressive lockless i/o settings
15855         do_nodes $(comma_list $(osts_nodes)) \
15856                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
15857                         ldlm.namespaces.filter-*.contended_locks=0 \
15858                         ldlm.namespaces.filter-*.contention_seconds=60"
15859         lctl set_param -n osc.*.contention_seconds=60
15860
15861         $DIRECTIO write $DIR/$tfile 0 10 4096
15862         $CHECKSTAT -s 40960 $DIR/$tfile
15863
15864         # disable lockless i/o
15865         do_nodes $(comma_list $(osts_nodes)) \
15866                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
15867                         ldlm.namespaces.filter-*.contended_locks=32 \
15868                         ldlm.namespaces.filter-*.contention_seconds=0"
15869         lctl set_param -n osc.*.contention_seconds=0
15870         clear_stats osc.*.osc_stats
15871
15872         dd if=/dev/zero of=$DIR/$tfile count=0
15873         $CHECKSTAT -s 0 $DIR/$tfile
15874
15875         restore_lustre_params <$p
15876         rm -f $p
15877         rm $DIR/$tfile
15878 }
15879 run_test 216 "check lockless direct write updates file size and kms correctly"
15880
15881 test_217() { # bug 22430
15882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15883
15884         local node
15885         local nid
15886
15887         for node in $(nodes_list); do
15888                 nid=$(host_nids_address $node $NETTYPE)
15889                 if [[ $nid = *-* ]] ; then
15890                         echo "lctl ping $(h2nettype $nid)"
15891                         lctl ping $(h2nettype $nid)
15892                 else
15893                         echo "skipping $node (no hyphen detected)"
15894                 fi
15895         done
15896 }
15897 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
15898
15899 test_218() {
15900        # do directio so as not to populate the page cache
15901        log "creating a 10 Mb file"
15902        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15903        log "starting reads"
15904        dd if=$DIR/$tfile of=/dev/null bs=4096 &
15905        log "truncating the file"
15906        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15907        log "killing dd"
15908        kill %+ || true # reads might have finished
15909        echo "wait until dd is finished"
15910        wait
15911        log "removing the temporary file"
15912        rm -rf $DIR/$tfile || error "tmp file removal failed"
15913 }
15914 run_test 218 "parallel read and truncate should not deadlock"
15915
15916 test_219() {
15917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15918
15919         # write one partial page
15920         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
15921         # set no grant so vvp_io_commit_write will do sync write
15922         $LCTL set_param fail_loc=0x411
15923         # write a full page at the end of file
15924         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
15925
15926         $LCTL set_param fail_loc=0
15927         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
15928         $LCTL set_param fail_loc=0x411
15929         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
15930
15931         # LU-4201
15932         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
15933         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
15934 }
15935 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
15936
15937 test_220() { #LU-325
15938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15939         remote_ost_nodsh && skip "remote OST with nodsh"
15940         remote_mds_nodsh && skip "remote MDS with nodsh"
15941         remote_mgs_nodsh && skip "remote MGS with nodsh"
15942
15943         local OSTIDX=0
15944
15945         # create on MDT0000 so the last_id and next_id are correct
15946         mkdir $DIR/$tdir
15947         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
15948         OST=${OST%_UUID}
15949
15950         # on the mdt's osc
15951         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
15952         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
15953                         osp.$mdtosc_proc1.prealloc_last_id)
15954         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
15955                         osp.$mdtosc_proc1.prealloc_next_id)
15956
15957         $LFS df -i
15958
15959         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
15960         #define OBD_FAIL_OST_ENOINO              0x229
15961         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
15962         create_pool $FSNAME.$TESTNAME || return 1
15963         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
15964
15965         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
15966
15967         MDSOBJS=$((last_id - next_id))
15968         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
15969
15970         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
15971         echo "OST still has $count kbytes free"
15972
15973         echo "create $MDSOBJS files @next_id..."
15974         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
15975
15976         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15977                         osp.$mdtosc_proc1.prealloc_last_id)
15978         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15979                         osp.$mdtosc_proc1.prealloc_next_id)
15980
15981         echo "after creation, last_id=$last_id2, next_id=$next_id2"
15982         $LFS df -i
15983
15984         echo "cleanup..."
15985
15986         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
15987         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
15988
15989         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
15990                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
15991         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
15992                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
15993         echo "unlink $MDSOBJS files @$next_id..."
15994         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
15995 }
15996 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
15997
15998 test_221() {
15999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16000
16001         dd if=`which date` of=$MOUNT/date oflag=sync
16002         chmod +x $MOUNT/date
16003
16004         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
16005         $LCTL set_param fail_loc=0x80001401
16006
16007         $MOUNT/date > /dev/null
16008         rm -f $MOUNT/date
16009 }
16010 run_test 221 "make sure fault and truncate race to not cause OOM"
16011
16012 test_222a () {
16013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16014
16015         rm -rf $DIR/$tdir
16016         test_mkdir $DIR/$tdir
16017         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16018         createmany -o $DIR/$tdir/$tfile 10
16019         cancel_lru_locks mdc
16020         cancel_lru_locks osc
16021         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16022         $LCTL set_param fail_loc=0x31a
16023         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
16024         $LCTL set_param fail_loc=0
16025         rm -r $DIR/$tdir
16026 }
16027 run_test 222a "AGL for ls should not trigger CLIO lock failure"
16028
16029 test_222b () {
16030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16031
16032         rm -rf $DIR/$tdir
16033         test_mkdir $DIR/$tdir
16034         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16035         createmany -o $DIR/$tdir/$tfile 10
16036         cancel_lru_locks mdc
16037         cancel_lru_locks osc
16038         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16039         $LCTL set_param fail_loc=0x31a
16040         rm -r $DIR/$tdir || error "AGL for rmdir failed"
16041         $LCTL set_param fail_loc=0
16042 }
16043 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
16044
16045 test_223 () {
16046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16047
16048         rm -rf $DIR/$tdir
16049         test_mkdir $DIR/$tdir
16050         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16051         createmany -o $DIR/$tdir/$tfile 10
16052         cancel_lru_locks mdc
16053         cancel_lru_locks osc
16054         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
16055         $LCTL set_param fail_loc=0x31b
16056         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
16057         $LCTL set_param fail_loc=0
16058         rm -r $DIR/$tdir
16059 }
16060 run_test 223 "osc reenqueue if without AGL lock granted ======================="
16061
16062 test_224a() { # LU-1039, MRP-303
16063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16064
16065         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
16066         $LCTL set_param fail_loc=0x508
16067         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
16068         $LCTL set_param fail_loc=0
16069         df $DIR
16070 }
16071 run_test 224a "Don't panic on bulk IO failure"
16072
16073 test_224b() { # LU-1039, MRP-303
16074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16075
16076         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
16077         cancel_lru_locks osc
16078         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
16079         $LCTL set_param fail_loc=0x515
16080         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
16081         $LCTL set_param fail_loc=0
16082         df $DIR
16083 }
16084 run_test 224b "Don't panic on bulk IO failure"
16085
16086 test_224c() { # LU-6441
16087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16088         remote_mds_nodsh && skip "remote MDS with nodsh"
16089
16090         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16091         save_writethrough $p
16092         set_cache writethrough on
16093
16094         local pages_per_rpc=$($LCTL get_param \
16095                                 osc.*.max_pages_per_rpc)
16096         local at_max=$($LCTL get_param -n at_max)
16097         local timeout=$($LCTL get_param -n timeout)
16098         local test_at="at_max"
16099         local param_at="$FSNAME.sys.at_max"
16100         local test_timeout="timeout"
16101         local param_timeout="$FSNAME.sys.timeout"
16102
16103         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
16104
16105         set_persistent_param_and_check client "$test_at" "$param_at" 0
16106         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
16107
16108         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
16109         do_facet ost1 "$LCTL set_param fail_loc=0x520"
16110         $LFS setstripe -c 1 -i 0 $DIR/$tfile
16111         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
16112         sync
16113         do_facet ost1 "$LCTL set_param fail_loc=0"
16114
16115         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
16116         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
16117                 $timeout
16118
16119         $LCTL set_param -n $pages_per_rpc
16120         restore_lustre_params < $p
16121         rm -f $p
16122 }
16123 run_test 224c "Don't hang if one of md lost during large bulk RPC"
16124
16125 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
16126 test_225a () {
16127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16128         if [ -z ${MDSSURVEY} ]; then
16129                 skip_env "mds-survey not found"
16130         fi
16131         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16132                 skip "Need MDS version at least 2.2.51"
16133
16134         local mds=$(facet_host $SINGLEMDS)
16135         local target=$(do_nodes $mds 'lctl dl' |
16136                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16137
16138         local cmd1="file_count=1000 thrhi=4"
16139         local cmd2="dir_count=2 layer=mdd stripe_count=0"
16140         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16141         local cmd="$cmd1 $cmd2 $cmd3"
16142
16143         rm -f ${TMP}/mds_survey*
16144         echo + $cmd
16145         eval $cmd || error "mds-survey with zero-stripe failed"
16146         cat ${TMP}/mds_survey*
16147         rm -f ${TMP}/mds_survey*
16148 }
16149 run_test 225a "Metadata survey sanity with zero-stripe"
16150
16151 test_225b () {
16152         if [ -z ${MDSSURVEY} ]; then
16153                 skip_env "mds-survey not found"
16154         fi
16155         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16156                 skip "Need MDS version at least 2.2.51"
16157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16158         remote_mds_nodsh && skip "remote MDS with nodsh"
16159         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
16160                 skip_env "Need to mount OST to test"
16161         fi
16162
16163         local mds=$(facet_host $SINGLEMDS)
16164         local target=$(do_nodes $mds 'lctl dl' |
16165                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16166
16167         local cmd1="file_count=1000 thrhi=4"
16168         local cmd2="dir_count=2 layer=mdd stripe_count=1"
16169         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16170         local cmd="$cmd1 $cmd2 $cmd3"
16171
16172         rm -f ${TMP}/mds_survey*
16173         echo + $cmd
16174         eval $cmd || error "mds-survey with stripe_count failed"
16175         cat ${TMP}/mds_survey*
16176         rm -f ${TMP}/mds_survey*
16177 }
16178 run_test 225b "Metadata survey sanity with stripe_count = 1"
16179
16180 mcreate_path2fid () {
16181         local mode=$1
16182         local major=$2
16183         local minor=$3
16184         local name=$4
16185         local desc=$5
16186         local path=$DIR/$tdir/$name
16187         local fid
16188         local rc
16189         local fid_path
16190
16191         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
16192                 error "cannot create $desc"
16193
16194         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
16195         rc=$?
16196         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
16197
16198         fid_path=$($LFS fid2path $MOUNT $fid)
16199         rc=$?
16200         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
16201
16202         [ "$path" == "$fid_path" ] ||
16203                 error "fid2path returned $fid_path, expected $path"
16204
16205         echo "pass with $path and $fid"
16206 }
16207
16208 test_226a () {
16209         rm -rf $DIR/$tdir
16210         mkdir -p $DIR/$tdir
16211
16212         mcreate_path2fid 0010666 0 0 fifo "FIFO"
16213         mcreate_path2fid 0020666 1 3 null "character special file (null)"
16214         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
16215         mcreate_path2fid 0040666 0 0 dir "directory"
16216         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
16217         mcreate_path2fid 0100666 0 0 file "regular file"
16218         mcreate_path2fid 0120666 0 0 link "symbolic link"
16219         mcreate_path2fid 0140666 0 0 sock "socket"
16220 }
16221 run_test 226a "call path2fid and fid2path on files of all type"
16222
16223 test_226b () {
16224         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16225
16226         local MDTIDX=1
16227
16228         rm -rf $DIR/$tdir
16229         mkdir -p $DIR/$tdir
16230         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
16231                 error "create remote directory failed"
16232         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
16233         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
16234                                 "character special file (null)"
16235         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
16236                                 "character special file (no device)"
16237         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
16238         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
16239                                 "block special file (loop)"
16240         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
16241         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
16242         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
16243 }
16244 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
16245
16246 # LU-1299 Executing or running ldd on a truncated executable does not
16247 # cause an out-of-memory condition.
16248 test_227() {
16249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16250         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
16251
16252         dd if=$(which date) of=$MOUNT/date bs=1k count=1
16253         chmod +x $MOUNT/date
16254
16255         $MOUNT/date > /dev/null
16256         ldd $MOUNT/date > /dev/null
16257         rm -f $MOUNT/date
16258 }
16259 run_test 227 "running truncated executable does not cause OOM"
16260
16261 # LU-1512 try to reuse idle OI blocks
16262 test_228a() {
16263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16264         remote_mds_nodsh && skip "remote MDS with nodsh"
16265         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16266
16267         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16268         local myDIR=$DIR/$tdir
16269
16270         mkdir -p $myDIR
16271         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16272         $LCTL set_param fail_loc=0x80001002
16273         createmany -o $myDIR/t- 10000
16274         $LCTL set_param fail_loc=0
16275         # The guard is current the largest FID holder
16276         touch $myDIR/guard
16277         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16278                     tr -d '[')
16279         local IDX=$(($SEQ % 64))
16280
16281         do_facet $SINGLEMDS sync
16282         # Make sure journal flushed.
16283         sleep 6
16284         local blk1=$(do_facet $SINGLEMDS \
16285                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16286                      grep Blockcount | awk '{print $4}')
16287
16288         # Remove old files, some OI blocks will become idle.
16289         unlinkmany $myDIR/t- 10000
16290         # Create new files, idle OI blocks should be reused.
16291         createmany -o $myDIR/t- 2000
16292         do_facet $SINGLEMDS sync
16293         # Make sure journal flushed.
16294         sleep 6
16295         local blk2=$(do_facet $SINGLEMDS \
16296                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16297                      grep Blockcount | awk '{print $4}')
16298
16299         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16300 }
16301 run_test 228a "try to reuse idle OI blocks"
16302
16303 test_228b() {
16304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16305         remote_mds_nodsh && skip "remote MDS with nodsh"
16306         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16307
16308         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16309         local myDIR=$DIR/$tdir
16310
16311         mkdir -p $myDIR
16312         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16313         $LCTL set_param fail_loc=0x80001002
16314         createmany -o $myDIR/t- 10000
16315         $LCTL set_param fail_loc=0
16316         # The guard is current the largest FID holder
16317         touch $myDIR/guard
16318         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16319                     tr -d '[')
16320         local IDX=$(($SEQ % 64))
16321
16322         do_facet $SINGLEMDS sync
16323         # Make sure journal flushed.
16324         sleep 6
16325         local blk1=$(do_facet $SINGLEMDS \
16326                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16327                      grep Blockcount | awk '{print $4}')
16328
16329         # Remove old files, some OI blocks will become idle.
16330         unlinkmany $myDIR/t- 10000
16331
16332         # stop the MDT
16333         stop $SINGLEMDS || error "Fail to stop MDT."
16334         # remount the MDT
16335         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
16336
16337         df $MOUNT || error "Fail to df."
16338         # Create new files, idle OI blocks should be reused.
16339         createmany -o $myDIR/t- 2000
16340         do_facet $SINGLEMDS sync
16341         # Make sure journal flushed.
16342         sleep 6
16343         local blk2=$(do_facet $SINGLEMDS \
16344                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16345                      grep Blockcount | awk '{print $4}')
16346
16347         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16348 }
16349 run_test 228b "idle OI blocks can be reused after MDT restart"
16350
16351 #LU-1881
16352 test_228c() {
16353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16354         remote_mds_nodsh && skip "remote MDS with nodsh"
16355         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16356
16357         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16358         local myDIR=$DIR/$tdir
16359
16360         mkdir -p $myDIR
16361         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16362         $LCTL set_param fail_loc=0x80001002
16363         # 20000 files can guarantee there are index nodes in the OI file
16364         createmany -o $myDIR/t- 20000
16365         $LCTL set_param fail_loc=0
16366         # The guard is current the largest FID holder
16367         touch $myDIR/guard
16368         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16369                     tr -d '[')
16370         local IDX=$(($SEQ % 64))
16371
16372         do_facet $SINGLEMDS sync
16373         # Make sure journal flushed.
16374         sleep 6
16375         local blk1=$(do_facet $SINGLEMDS \
16376                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16377                      grep Blockcount | awk '{print $4}')
16378
16379         # Remove old files, some OI blocks will become idle.
16380         unlinkmany $myDIR/t- 20000
16381         rm -f $myDIR/guard
16382         # The OI file should become empty now
16383
16384         # Create new files, idle OI blocks should be reused.
16385         createmany -o $myDIR/t- 2000
16386         do_facet $SINGLEMDS sync
16387         # Make sure journal flushed.
16388         sleep 6
16389         local blk2=$(do_facet $SINGLEMDS \
16390                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16391                      grep Blockcount | awk '{print $4}')
16392
16393         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16394 }
16395 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
16396
16397 test_229() { # LU-2482, LU-3448
16398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16399         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
16400         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
16401                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
16402
16403         rm -f $DIR/$tfile
16404
16405         # Create a file with a released layout and stripe count 2.
16406         $MULTIOP $DIR/$tfile H2c ||
16407                 error "failed to create file with released layout"
16408
16409         $LFS getstripe -v $DIR/$tfile
16410
16411         local pattern=$($LFS getstripe -L $DIR/$tfile)
16412         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
16413
16414         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
16415                 error "getstripe"
16416         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
16417         stat $DIR/$tfile || error "failed to stat released file"
16418
16419         chown $RUNAS_ID $DIR/$tfile ||
16420                 error "chown $RUNAS_ID $DIR/$tfile failed"
16421
16422         chgrp $RUNAS_ID $DIR/$tfile ||
16423                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
16424
16425         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
16426         rm $DIR/$tfile || error "failed to remove released file"
16427 }
16428 run_test 229 "getstripe/stat/rm/attr changes work on released files"
16429
16430 test_230a() {
16431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16432         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16433         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16434                 skip "Need MDS version at least 2.11.52"
16435
16436         local MDTIDX=1
16437
16438         test_mkdir $DIR/$tdir
16439         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
16440         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
16441         [ $mdt_idx -ne 0 ] &&
16442                 error "create local directory on wrong MDT $mdt_idx"
16443
16444         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
16445                         error "create remote directory failed"
16446         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
16447         [ $mdt_idx -ne $MDTIDX ] &&
16448                 error "create remote directory on wrong MDT $mdt_idx"
16449
16450         createmany -o $DIR/$tdir/test_230/t- 10 ||
16451                 error "create files on remote directory failed"
16452         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
16453         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
16454         rm -r $DIR/$tdir || error "unlink remote directory failed"
16455 }
16456 run_test 230a "Create remote directory and files under the remote directory"
16457
16458 test_230b() {
16459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16460         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16461         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16462                 skip "Need MDS version at least 2.11.52"
16463
16464         local MDTIDX=1
16465         local mdt_index
16466         local i
16467         local file
16468         local pid
16469         local stripe_count
16470         local migrate_dir=$DIR/$tdir/migrate_dir
16471         local other_dir=$DIR/$tdir/other_dir
16472
16473         test_mkdir $DIR/$tdir
16474         test_mkdir -i0 -c1 $migrate_dir
16475         test_mkdir -i0 -c1 $other_dir
16476         for ((i=0; i<10; i++)); do
16477                 mkdir -p $migrate_dir/dir_${i}
16478                 createmany -o $migrate_dir/dir_${i}/f 10 ||
16479                         error "create files under remote dir failed $i"
16480         done
16481
16482         cp /etc/passwd $migrate_dir/$tfile
16483         cp /etc/passwd $other_dir/$tfile
16484         chattr +SAD $migrate_dir
16485         chattr +SAD $migrate_dir/$tfile
16486
16487         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16488         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16489         local old_dir_mode=$(stat -c%f $migrate_dir)
16490         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
16491
16492         mkdir -p $migrate_dir/dir_default_stripe2
16493         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
16494         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
16495
16496         mkdir -p $other_dir
16497         ln $migrate_dir/$tfile $other_dir/luna
16498         ln $migrate_dir/$tfile $migrate_dir/sofia
16499         ln $other_dir/$tfile $migrate_dir/david
16500         ln -s $migrate_dir/$tfile $other_dir/zachary
16501         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
16502         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
16503
16504         $LFS migrate -m $MDTIDX $migrate_dir ||
16505                 error "fails on migrating remote dir to MDT1"
16506
16507         echo "migratate to MDT1, then checking.."
16508         for ((i = 0; i < 10; i++)); do
16509                 for file in $(find $migrate_dir/dir_${i}); do
16510                         mdt_index=$($LFS getstripe -m $file)
16511                         [ $mdt_index == $MDTIDX ] ||
16512                                 error "$file is not on MDT${MDTIDX}"
16513                 done
16514         done
16515
16516         # the multiple link file should still in MDT0
16517         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
16518         [ $mdt_index == 0 ] ||
16519                 error "$file is not on MDT${MDTIDX}"
16520
16521         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16522         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16523                 error " expect $old_dir_flag get $new_dir_flag"
16524
16525         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16526         [ "$old_file_flag" = "$new_file_flag" ] ||
16527                 error " expect $old_file_flag get $new_file_flag"
16528
16529         local new_dir_mode=$(stat -c%f $migrate_dir)
16530         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16531                 error "expect mode $old_dir_mode get $new_dir_mode"
16532
16533         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16534         [ "$old_file_mode" = "$new_file_mode" ] ||
16535                 error "expect mode $old_file_mode get $new_file_mode"
16536
16537         diff /etc/passwd $migrate_dir/$tfile ||
16538                 error "$tfile different after migration"
16539
16540         diff /etc/passwd $other_dir/luna ||
16541                 error "luna different after migration"
16542
16543         diff /etc/passwd $migrate_dir/sofia ||
16544                 error "sofia different after migration"
16545
16546         diff /etc/passwd $migrate_dir/david ||
16547                 error "david different after migration"
16548
16549         diff /etc/passwd $other_dir/zachary ||
16550                 error "zachary different after migration"
16551
16552         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16553                 error "${tfile}_ln different after migration"
16554
16555         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16556                 error "${tfile}_ln_other different after migration"
16557
16558         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
16559         [ $stripe_count = 2 ] ||
16560                 error "dir strpe_count $d != 2 after migration."
16561
16562         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
16563         [ $stripe_count = 2 ] ||
16564                 error "file strpe_count $d != 2 after migration."
16565
16566         #migrate back to MDT0
16567         MDTIDX=0
16568
16569         $LFS migrate -m $MDTIDX $migrate_dir ||
16570                 error "fails on migrating remote dir to MDT0"
16571
16572         echo "migrate back to MDT0, checking.."
16573         for file in $(find $migrate_dir); do
16574                 mdt_index=$($LFS getstripe -m $file)
16575                 [ $mdt_index == $MDTIDX ] ||
16576                         error "$file is not on MDT${MDTIDX}"
16577         done
16578
16579         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16580         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16581                 error " expect $old_dir_flag get $new_dir_flag"
16582
16583         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16584         [ "$old_file_flag" = "$new_file_flag" ] ||
16585                 error " expect $old_file_flag get $new_file_flag"
16586
16587         local new_dir_mode=$(stat -c%f $migrate_dir)
16588         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16589                 error "expect mode $old_dir_mode get $new_dir_mode"
16590
16591         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16592         [ "$old_file_mode" = "$new_file_mode" ] ||
16593                 error "expect mode $old_file_mode get $new_file_mode"
16594
16595         diff /etc/passwd ${migrate_dir}/$tfile ||
16596                 error "$tfile different after migration"
16597
16598         diff /etc/passwd ${other_dir}/luna ||
16599                 error "luna different after migration"
16600
16601         diff /etc/passwd ${migrate_dir}/sofia ||
16602                 error "sofia different after migration"
16603
16604         diff /etc/passwd ${other_dir}/zachary ||
16605                 error "zachary different after migration"
16606
16607         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16608                 error "${tfile}_ln different after migration"
16609
16610         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16611                 error "${tfile}_ln_other different after migration"
16612
16613         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
16614         [ $stripe_count = 2 ] ||
16615                 error "dir strpe_count $d != 2 after migration."
16616
16617         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
16618         [ $stripe_count = 2 ] ||
16619                 error "file strpe_count $d != 2 after migration."
16620
16621         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16622 }
16623 run_test 230b "migrate directory"
16624
16625 test_230c() {
16626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16627         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16628         remote_mds_nodsh && skip "remote MDS with nodsh"
16629         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16630                 skip "Need MDS version at least 2.11.52"
16631
16632         local MDTIDX=1
16633         local total=3
16634         local mdt_index
16635         local file
16636         local migrate_dir=$DIR/$tdir/migrate_dir
16637
16638         #If migrating directory fails in the middle, all entries of
16639         #the directory is still accessiable.
16640         test_mkdir $DIR/$tdir
16641         test_mkdir -i0 -c1 $migrate_dir
16642         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
16643         stat $migrate_dir
16644         createmany -o $migrate_dir/f $total ||
16645                 error "create files under ${migrate_dir} failed"
16646
16647         # fail after migrating top dir, and this will fail only once, so the
16648         # first sub file migration will fail (currently f3), others succeed.
16649         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
16650         do_facet mds1 lctl set_param fail_loc=0x1801
16651         local t=$(ls $migrate_dir | wc -l)
16652         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
16653                 error "migrate should fail"
16654         local u=$(ls $migrate_dir | wc -l)
16655         [ "$u" == "$t" ] || error "$u != $t during migration"
16656
16657         # add new dir/file should succeed
16658         mkdir $migrate_dir/dir ||
16659                 error "mkdir failed under migrating directory"
16660         touch $migrate_dir/file ||
16661                 error "create file failed under migrating directory"
16662
16663         # add file with existing name should fail
16664         for file in $migrate_dir/f*; do
16665                 stat $file > /dev/null || error "stat $file failed"
16666                 $OPENFILE -f O_CREAT:O_EXCL $file &&
16667                         error "open(O_CREAT|O_EXCL) $file should fail"
16668                 $MULTIOP $file m && error "create $file should fail"
16669                 touch $DIR/$tdir/remote_dir/$tfile ||
16670                         error "touch $tfile failed"
16671                 ln $DIR/$tdir/remote_dir/$tfile $file &&
16672                         error "link $file should fail"
16673                 mdt_index=$($LFS getstripe -m $file)
16674                 if [ $mdt_index == 0 ]; then
16675                         # file failed to migrate is not allowed to rename to
16676                         mv $DIR/$tdir/remote_dir/$tfile $file &&
16677                                 error "rename to $file should fail"
16678                 else
16679                         mv $DIR/$tdir/remote_dir/$tfile $file ||
16680                                 error "rename to $file failed"
16681                 fi
16682                 echo hello >> $file || error "write $file failed"
16683         done
16684
16685         # resume migration with different options should fail
16686         $LFS migrate -m 0 $migrate_dir &&
16687                 error "migrate -m 0 $migrate_dir should fail"
16688
16689         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
16690                 error "migrate -c 2 $migrate_dir should fail"
16691
16692         # resume migration should succeed
16693         $LFS migrate -m $MDTIDX $migrate_dir ||
16694                 error "migrate $migrate_dir failed"
16695
16696         echo "Finish migration, then checking.."
16697         for file in $(find $migrate_dir); do
16698                 mdt_index=$($LFS getstripe -m $file)
16699                 [ $mdt_index == $MDTIDX ] ||
16700                         error "$file is not on MDT${MDTIDX}"
16701         done
16702
16703         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16704 }
16705 run_test 230c "check directory accessiblity if migration failed"
16706
16707 test_230d() {
16708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16709         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16710         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16711                 skip "Need MDS version at least 2.11.52"
16712         # LU-11235
16713         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
16714
16715         local migrate_dir=$DIR/$tdir/migrate_dir
16716         local old_index
16717         local new_index
16718         local old_count
16719         local new_count
16720         local new_hash
16721         local mdt_index
16722         local i
16723         local j
16724
16725         old_index=$((RANDOM % MDSCOUNT))
16726         old_count=$((MDSCOUNT - old_index))
16727         new_index=$((RANDOM % MDSCOUNT))
16728         new_count=$((MDSCOUNT - new_index))
16729         new_hash="all_char"
16730
16731         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
16732         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
16733
16734         test_mkdir $DIR/$tdir
16735         test_mkdir -i $old_index -c $old_count $migrate_dir
16736
16737         for ((i=0; i<100; i++)); do
16738                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
16739                 createmany -o $migrate_dir/dir_${i}/f 100 ||
16740                         error "create files under remote dir failed $i"
16741         done
16742
16743         echo -n "Migrate from MDT$old_index "
16744         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
16745         echo -n "to MDT$new_index"
16746         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
16747         echo
16748
16749         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
16750         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
16751                 error "migrate remote dir error"
16752
16753         echo "Finish migration, then checking.."
16754         for file in $(find $migrate_dir); do
16755                 mdt_index=$($LFS getstripe -m $file)
16756                 if [ $mdt_index -lt $new_index ] ||
16757                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
16758                         error "$file is on MDT$mdt_index"
16759                 fi
16760         done
16761
16762         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16763 }
16764 run_test 230d "check migrate big directory"
16765
16766 test_230e() {
16767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16768         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16769         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16770                 skip "Need MDS version at least 2.11.52"
16771
16772         local i
16773         local j
16774         local a_fid
16775         local b_fid
16776
16777         mkdir -p $DIR/$tdir
16778         mkdir $DIR/$tdir/migrate_dir
16779         mkdir $DIR/$tdir/other_dir
16780         touch $DIR/$tdir/migrate_dir/a
16781         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
16782         ls $DIR/$tdir/other_dir
16783
16784         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16785                 error "migrate dir fails"
16786
16787         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16788         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16789
16790         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16791         [ $mdt_index == 0 ] || error "a is not on MDT0"
16792
16793         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
16794                 error "migrate dir fails"
16795
16796         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
16797         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
16798
16799         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16800         [ $mdt_index == 1 ] || error "a is not on MDT1"
16801
16802         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
16803         [ $mdt_index == 1 ] || error "b is not on MDT1"
16804
16805         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16806         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
16807
16808         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
16809
16810         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16811 }
16812 run_test 230e "migrate mulitple local link files"
16813
16814 test_230f() {
16815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16816         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16817         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16818                 skip "Need MDS version at least 2.11.52"
16819
16820         local a_fid
16821         local ln_fid
16822
16823         mkdir -p $DIR/$tdir
16824         mkdir $DIR/$tdir/migrate_dir
16825         $LFS mkdir -i1 $DIR/$tdir/other_dir
16826         touch $DIR/$tdir/migrate_dir/a
16827         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
16828         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
16829         ls $DIR/$tdir/other_dir
16830
16831         # a should be migrated to MDT1, since no other links on MDT0
16832         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16833                 error "#1 migrate dir fails"
16834         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16835         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16836         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16837         [ $mdt_index == 1 ] || error "a is not on MDT1"
16838
16839         # a should stay on MDT1, because it is a mulitple link file
16840         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16841                 error "#2 migrate dir fails"
16842         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16843         [ $mdt_index == 1 ] || error "a is not on MDT1"
16844
16845         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16846                 error "#3 migrate dir fails"
16847
16848         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16849         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
16850         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
16851
16852         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
16853         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
16854
16855         # a should be migrated to MDT0, since no other links on MDT1
16856         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16857                 error "#4 migrate dir fails"
16858         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16859         [ $mdt_index == 0 ] || error "a is not on MDT0"
16860
16861         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16862 }
16863 run_test 230f "migrate mulitple remote link files"
16864
16865 test_230g() {
16866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16867         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16868         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16869                 skip "Need MDS version at least 2.11.52"
16870
16871         mkdir -p $DIR/$tdir/migrate_dir
16872
16873         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
16874                 error "migrating dir to non-exist MDT succeeds"
16875         true
16876 }
16877 run_test 230g "migrate dir to non-exist MDT"
16878
16879 test_230h() {
16880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16881         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16882         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16883                 skip "Need MDS version at least 2.11.52"
16884
16885         local mdt_index
16886
16887         mkdir -p $DIR/$tdir/migrate_dir
16888
16889         $LFS migrate -m1 $DIR &&
16890                 error "migrating mountpoint1 should fail"
16891
16892         $LFS migrate -m1 $DIR/$tdir/.. &&
16893                 error "migrating mountpoint2 should fail"
16894
16895         # same as mv
16896         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
16897                 error "migrating $tdir/migrate_dir/.. should fail"
16898
16899         true
16900 }
16901 run_test 230h "migrate .. and root"
16902
16903 test_230i() {
16904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16905         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16906         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16907                 skip "Need MDS version at least 2.11.52"
16908
16909         mkdir -p $DIR/$tdir/migrate_dir
16910
16911         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
16912                 error "migration fails with a tailing slash"
16913
16914         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
16915                 error "migration fails with two tailing slashes"
16916 }
16917 run_test 230i "lfs migrate -m tolerates trailing slashes"
16918
16919 test_230j() {
16920         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16921         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16922                 skip "Need MDS version at least 2.11.52"
16923
16924         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
16925         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
16926                 error "create $tfile failed"
16927         cat /etc/passwd > $DIR/$tdir/$tfile
16928
16929         $LFS migrate -m 1 $DIR/$tdir
16930
16931         cmp /etc/passwd $DIR/$tdir/$tfile ||
16932                 error "DoM file mismatch after migration"
16933 }
16934 run_test 230j "DoM file data not changed after dir migration"
16935
16936 test_230k() {
16937         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
16938         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16939                 skip "Need MDS version at least 2.11.56"
16940
16941         local total=20
16942         local files_on_starting_mdt=0
16943
16944         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
16945         $LFS getdirstripe $DIR/$tdir
16946         for i in $(seq $total); do
16947                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
16948                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16949                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16950         done
16951
16952         echo "$files_on_starting_mdt files on MDT0"
16953
16954         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
16955         $LFS getdirstripe $DIR/$tdir
16956
16957         files_on_starting_mdt=0
16958         for i in $(seq $total); do
16959                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16960                         error "file $tfile.$i mismatch after migration"
16961                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
16962                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16963         done
16964
16965         echo "$files_on_starting_mdt files on MDT1 after migration"
16966         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
16967
16968         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
16969         $LFS getdirstripe $DIR/$tdir
16970
16971         files_on_starting_mdt=0
16972         for i in $(seq $total); do
16973                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16974                         error "file $tfile.$i mismatch after 2nd migration"
16975                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16976                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16977         done
16978
16979         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
16980         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
16981
16982         true
16983 }
16984 run_test 230k "file data not changed after dir migration"
16985
16986 test_230l() {
16987         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16988         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16989                 skip "Need MDS version at least 2.11.56"
16990
16991         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
16992         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
16993                 error "create files under remote dir failed $i"
16994         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
16995 }
16996 run_test 230l "readdir between MDTs won't crash"
16997
16998 test_230m() {
16999         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17000         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17001                 skip "Need MDS version at least 2.11.56"
17002
17003         local MDTIDX=1
17004         local mig_dir=$DIR/$tdir/migrate_dir
17005         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
17006         local shortstr="b"
17007         local val
17008
17009         echo "Creating files and dirs with xattrs"
17010         test_mkdir $DIR/$tdir
17011         test_mkdir -i0 -c1 $mig_dir
17012         mkdir $mig_dir/dir
17013         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
17014                 error "cannot set xattr attr1 on dir"
17015         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
17016                 error "cannot set xattr attr2 on dir"
17017         touch $mig_dir/dir/f0
17018         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
17019                 error "cannot set xattr attr1 on file"
17020         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
17021                 error "cannot set xattr attr2 on file"
17022         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
17023         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
17024         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
17025         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
17026         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
17027         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
17028         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
17029         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
17030         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
17031
17032         echo "Migrating to MDT1"
17033         $LFS migrate -m $MDTIDX $mig_dir ||
17034                 error "fails on migrating dir to MDT1"
17035
17036         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
17037         echo "Checking xattrs"
17038         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
17039         [ "$val" = $longstr ] ||
17040                 error "expecting xattr1 $longstr on dir, found $val"
17041         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
17042         [ "$val" = $shortstr ] ||
17043                 error "expecting xattr2 $shortstr on dir, found $val"
17044         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
17045         [ "$val" = $longstr ] ||
17046                 error "expecting xattr1 $longstr on file, found $val"
17047         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
17048         [ "$val" = $shortstr ] ||
17049                 error "expecting xattr2 $shortstr on file, found $val"
17050 }
17051 run_test 230m "xattrs not changed after dir migration"
17052
17053 test_231a()
17054 {
17055         # For simplicity this test assumes that max_pages_per_rpc
17056         # is the same across all OSCs
17057         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
17058         local bulk_size=$((max_pages * PAGE_SIZE))
17059         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
17060                                        head -n 1)
17061
17062         mkdir -p $DIR/$tdir
17063         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
17064                 error "failed to set stripe with -S ${brw_size}M option"
17065
17066         # clear the OSC stats
17067         $LCTL set_param osc.*.stats=0 &>/dev/null
17068         stop_writeback
17069
17070         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
17071         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
17072                 oflag=direct &>/dev/null || error "dd failed"
17073
17074         sync; sleep 1; sync # just to be safe
17075         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
17076         if [ x$nrpcs != "x1" ]; then
17077                 $LCTL get_param osc.*.stats
17078                 error "found $nrpcs ost_write RPCs, not 1 as expected"
17079         fi
17080
17081         start_writeback
17082         # Drop the OSC cache, otherwise we will read from it
17083         cancel_lru_locks osc
17084
17085         # clear the OSC stats
17086         $LCTL set_param osc.*.stats=0 &>/dev/null
17087
17088         # Client reads $bulk_size.
17089         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
17090                 iflag=direct &>/dev/null || error "dd failed"
17091
17092         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
17093         if [ x$nrpcs != "x1" ]; then
17094                 $LCTL get_param osc.*.stats
17095                 error "found $nrpcs ost_read RPCs, not 1 as expected"
17096         fi
17097 }
17098 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
17099
17100 test_231b() {
17101         mkdir -p $DIR/$tdir
17102         local i
17103         for i in {0..1023}; do
17104                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
17105                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
17106                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
17107         done
17108         sync
17109 }
17110 run_test 231b "must not assert on fully utilized OST request buffer"
17111
17112 test_232a() {
17113         mkdir -p $DIR/$tdir
17114         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
17115
17116         #define OBD_FAIL_LDLM_OST_LVB            0x31c
17117         do_facet ost1 $LCTL set_param fail_loc=0x31c
17118
17119         # ignore dd failure
17120         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
17121
17122         do_facet ost1 $LCTL set_param fail_loc=0
17123         umount_client $MOUNT || error "umount failed"
17124         mount_client $MOUNT || error "mount failed"
17125         stop ost1 || error "cannot stop ost1"
17126         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17127 }
17128 run_test 232a "failed lock should not block umount"
17129
17130 test_232b() {
17131         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
17132                 skip "Need MDS version at least 2.10.58"
17133
17134         mkdir -p $DIR/$tdir
17135         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
17136         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
17137         sync
17138         cancel_lru_locks osc
17139
17140         #define OBD_FAIL_LDLM_OST_LVB            0x31c
17141         do_facet ost1 $LCTL set_param fail_loc=0x31c
17142
17143         # ignore failure
17144         $LFS data_version $DIR/$tdir/$tfile || true
17145
17146         do_facet ost1 $LCTL set_param fail_loc=0
17147         umount_client $MOUNT || error "umount failed"
17148         mount_client $MOUNT || error "mount failed"
17149         stop ost1 || error "cannot stop ost1"
17150         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17151 }
17152 run_test 232b "failed data version lock should not block umount"
17153
17154 test_233a() {
17155         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
17156                 skip "Need MDS version at least 2.3.64"
17157         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
17158
17159         local fid=$($LFS path2fid $MOUNT)
17160
17161         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17162                 error "cannot access $MOUNT using its FID '$fid'"
17163 }
17164 run_test 233a "checking that OBF of the FS root succeeds"
17165
17166 test_233b() {
17167         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
17168                 skip "Need MDS version at least 2.5.90"
17169         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
17170
17171         local fid=$($LFS path2fid $MOUNT/.lustre)
17172
17173         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17174                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
17175
17176         fid=$($LFS path2fid $MOUNT/.lustre/fid)
17177         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17178                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
17179 }
17180 run_test 233b "checking that OBF of the FS .lustre succeeds"
17181
17182 test_234() {
17183         local p="$TMP/sanityN-$TESTNAME.parameters"
17184         save_lustre_params client "llite.*.xattr_cache" > $p
17185         lctl set_param llite.*.xattr_cache 1 ||
17186                 skip_env "xattr cache is not supported"
17187
17188         mkdir -p $DIR/$tdir || error "mkdir failed"
17189         touch $DIR/$tdir/$tfile || error "touch failed"
17190         # OBD_FAIL_LLITE_XATTR_ENOMEM
17191         $LCTL set_param fail_loc=0x1405
17192         getfattr -n user.attr $DIR/$tdir/$tfile &&
17193                 error "getfattr should have failed with ENOMEM"
17194         $LCTL set_param fail_loc=0x0
17195         rm -rf $DIR/$tdir
17196
17197         restore_lustre_params < $p
17198         rm -f $p
17199 }
17200 run_test 234 "xattr cache should not crash on ENOMEM"
17201
17202 test_235() {
17203         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
17204                 skip "Need MDS version at least 2.4.52"
17205
17206         flock_deadlock $DIR/$tfile
17207         local RC=$?
17208         case $RC in
17209                 0)
17210                 ;;
17211                 124) error "process hangs on a deadlock"
17212                 ;;
17213                 *) error "error executing flock_deadlock $DIR/$tfile"
17214                 ;;
17215         esac
17216 }
17217 run_test 235 "LU-1715: flock deadlock detection does not work properly"
17218
17219 #LU-2935
17220 test_236() {
17221         check_swap_layouts_support
17222
17223         local ref1=/etc/passwd
17224         local ref2=/etc/group
17225         local file1=$DIR/$tdir/f1
17226         local file2=$DIR/$tdir/f2
17227
17228         test_mkdir -c1 $DIR/$tdir
17229         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
17230         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
17231         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
17232         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
17233         local fd=$(free_fd)
17234         local cmd="exec $fd<>$file2"
17235         eval $cmd
17236         rm $file2
17237         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
17238                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
17239         cmd="exec $fd>&-"
17240         eval $cmd
17241         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17242
17243         #cleanup
17244         rm -rf $DIR/$tdir
17245 }
17246 run_test 236 "Layout swap on open unlinked file"
17247
17248 # LU-4659 linkea consistency
17249 test_238() {
17250         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17251                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17252                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17253                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17254
17255         touch $DIR/$tfile
17256         ln $DIR/$tfile $DIR/$tfile.lnk
17257         touch $DIR/$tfile.new
17258         mv $DIR/$tfile.new $DIR/$tfile
17259         local fid1=$($LFS path2fid $DIR/$tfile)
17260         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
17261         local path1=$($LFS fid2path $FSNAME "$fid1")
17262         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
17263         local path2=$($LFS fid2path $FSNAME "$fid2")
17264         [ $tfile.lnk == $path2 ] ||
17265                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
17266         rm -f $DIR/$tfile*
17267 }
17268 run_test 238 "Verify linkea consistency"
17269
17270 test_239A() { # was test_239
17271         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
17272                 skip "Need MDS version at least 2.5.60"
17273
17274         local list=$(comma_list $(mdts_nodes))
17275
17276         mkdir -p $DIR/$tdir
17277         createmany -o $DIR/$tdir/f- 5000
17278         unlinkmany $DIR/$tdir/f- 5000
17279         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
17280                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
17281         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
17282                         osp.*MDT*.sync_in_flight" | calc_sum)
17283         [ "$changes" -eq 0 ] || error "$changes not synced"
17284 }
17285 run_test 239A "osp_sync test"
17286
17287 test_239a() { #LU-5297
17288         remote_mds_nodsh && skip "remote MDS with nodsh"
17289
17290         touch $DIR/$tfile
17291         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
17292         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
17293         chgrp $RUNAS_GID $DIR/$tfile
17294         wait_delete_completed
17295 }
17296 run_test 239a "process invalid osp sync record correctly"
17297
17298 test_239b() { #LU-5297
17299         remote_mds_nodsh && skip "remote MDS with nodsh"
17300
17301         touch $DIR/$tfile1
17302         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
17303         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
17304         chgrp $RUNAS_GID $DIR/$tfile1
17305         wait_delete_completed
17306         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17307         touch $DIR/$tfile2
17308         chgrp $RUNAS_GID $DIR/$tfile2
17309         wait_delete_completed
17310 }
17311 run_test 239b "process osp sync record with ENOMEM error correctly"
17312
17313 test_240() {
17314         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17315         remote_mds_nodsh && skip "remote MDS with nodsh"
17316
17317         mkdir -p $DIR/$tdir
17318
17319         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
17320                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
17321         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
17322                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
17323
17324         umount_client $MOUNT || error "umount failed"
17325         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
17326         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
17327         mount_client $MOUNT || error "failed to mount client"
17328
17329         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
17330         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
17331 }
17332 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
17333
17334 test_241_bio() {
17335         local count=$1
17336         local bsize=$2
17337
17338         for LOOP in $(seq $count); do
17339                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
17340                 cancel_lru_locks $OSC || true
17341         done
17342 }
17343
17344 test_241_dio() {
17345         local count=$1
17346         local bsize=$2
17347
17348         for LOOP in $(seq $1); do
17349                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
17350                         2>/dev/null
17351         done
17352 }
17353
17354 test_241a() { # was test_241
17355         local bsize=$PAGE_SIZE
17356
17357         (( bsize < 40960 )) && bsize=40960
17358         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17359         ls -la $DIR/$tfile
17360         cancel_lru_locks $OSC
17361         test_241_bio 1000 $bsize &
17362         PID=$!
17363         test_241_dio 1000 $bsize
17364         wait $PID
17365 }
17366 run_test 241a "bio vs dio"
17367
17368 test_241b() {
17369         local bsize=$PAGE_SIZE
17370
17371         (( bsize < 40960 )) && bsize=40960
17372         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17373         ls -la $DIR/$tfile
17374         test_241_dio 1000 $bsize &
17375         PID=$!
17376         test_241_dio 1000 $bsize
17377         wait $PID
17378 }
17379 run_test 241b "dio vs dio"
17380
17381 test_242() {
17382         remote_mds_nodsh && skip "remote MDS with nodsh"
17383
17384         mkdir -p $DIR/$tdir
17385         touch $DIR/$tdir/$tfile
17386
17387         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
17388         do_facet mds1 lctl set_param fail_loc=0x105
17389         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
17390
17391         do_facet mds1 lctl set_param fail_loc=0
17392         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
17393 }
17394 run_test 242 "mdt_readpage failure should not cause directory unreadable"
17395
17396 test_243()
17397 {
17398         test_mkdir $DIR/$tdir
17399         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
17400 }
17401 run_test 243 "various group lock tests"
17402
17403 test_244a()
17404 {
17405         test_mkdir $DIR/$tdir
17406         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
17407         sendfile_grouplock $DIR/$tdir/$tfile || \
17408                 error "sendfile+grouplock failed"
17409         rm -rf $DIR/$tdir
17410 }
17411 run_test 244a "sendfile with group lock tests"
17412
17413 test_244b()
17414 {
17415         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
17416
17417         local threads=50
17418         local size=$((1024*1024))
17419
17420         test_mkdir $DIR/$tdir
17421         for i in $(seq 1 $threads); do
17422                 local file=$DIR/$tdir/file_$((i / 10))
17423                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
17424                 local pids[$i]=$!
17425         done
17426         for i in $(seq 1 $threads); do
17427                 wait ${pids[$i]}
17428         done
17429 }
17430 run_test 244b "multi-threaded write with group lock"
17431
17432 test_245() {
17433         local flagname="multi_mod_rpcs"
17434         local connect_data_name="max_mod_rpcs"
17435         local out
17436
17437         # check if multiple modify RPCs flag is set
17438         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
17439                 grep "connect_flags:")
17440         echo "$out"
17441
17442         echo "$out" | grep -qw $flagname
17443         if [ $? -ne 0 ]; then
17444                 echo "connect flag $flagname is not set"
17445                 return
17446         fi
17447
17448         # check if multiple modify RPCs data is set
17449         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
17450         echo "$out"
17451
17452         echo "$out" | grep -qw $connect_data_name ||
17453                 error "import should have connect data $connect_data_name"
17454 }
17455 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
17456
17457 cleanup_247() {
17458         local submount=$1
17459
17460         trap 0
17461         umount_client $submount
17462         rmdir $submount
17463 }
17464
17465 test_247a() {
17466         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17467                 grep -q subtree ||
17468                 skip_env "Fileset feature is not supported"
17469
17470         local submount=${MOUNT}_$tdir
17471
17472         mkdir $MOUNT/$tdir
17473         mkdir -p $submount || error "mkdir $submount failed"
17474         FILESET="$FILESET/$tdir" mount_client $submount ||
17475                 error "mount $submount failed"
17476         trap "cleanup_247 $submount" EXIT
17477         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
17478         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
17479                 error "read $MOUNT/$tdir/$tfile failed"
17480         cleanup_247 $submount
17481 }
17482 run_test 247a "mount subdir as fileset"
17483
17484 test_247b() {
17485         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17486                 skip_env "Fileset feature is not supported"
17487
17488         local submount=${MOUNT}_$tdir
17489
17490         rm -rf $MOUNT/$tdir
17491         mkdir -p $submount || error "mkdir $submount failed"
17492         SKIP_FILESET=1
17493         FILESET="$FILESET/$tdir" mount_client $submount &&
17494                 error "mount $submount should fail"
17495         rmdir $submount
17496 }
17497 run_test 247b "mount subdir that dose not exist"
17498
17499 test_247c() {
17500         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17501                 skip_env "Fileset feature is not supported"
17502
17503         local submount=${MOUNT}_$tdir
17504
17505         mkdir -p $MOUNT/$tdir/dir1
17506         mkdir -p $submount || error "mkdir $submount failed"
17507         trap "cleanup_247 $submount" EXIT
17508         FILESET="$FILESET/$tdir" mount_client $submount ||
17509                 error "mount $submount failed"
17510         local fid=$($LFS path2fid $MOUNT/)
17511         $LFS fid2path $submount $fid && error "fid2path should fail"
17512         cleanup_247 $submount
17513 }
17514 run_test 247c "running fid2path outside root"
17515
17516 test_247d() {
17517         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17518                 skip "Fileset feature is not supported"
17519
17520         local submount=${MOUNT}_$tdir
17521
17522         mkdir -p $MOUNT/$tdir/dir1
17523         mkdir -p $submount || error "mkdir $submount failed"
17524         FILESET="$FILESET/$tdir" mount_client $submount ||
17525                 error "mount $submount failed"
17526         trap "cleanup_247 $submount" EXIT
17527         local fid=$($LFS path2fid $submount/dir1)
17528         $LFS fid2path $submount $fid || error "fid2path should succeed"
17529         cleanup_247 $submount
17530 }
17531 run_test 247d "running fid2path inside root"
17532
17533 # LU-8037
17534 test_247e() {
17535         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17536                 grep -q subtree ||
17537                 skip "Fileset feature is not supported"
17538
17539         local submount=${MOUNT}_$tdir
17540
17541         mkdir $MOUNT/$tdir
17542         mkdir -p $submount || error "mkdir $submount failed"
17543         FILESET="$FILESET/.." mount_client $submount &&
17544                 error "mount $submount should fail"
17545         rmdir $submount
17546 }
17547 run_test 247e "mount .. as fileset"
17548
17549 test_248a() {
17550         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
17551         [ -z "$fast_read_sav" ] && skip "no fast read support"
17552
17553         # create a large file for fast read verification
17554         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
17555
17556         # make sure the file is created correctly
17557         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
17558                 { rm -f $DIR/$tfile; skip "file creation error"; }
17559
17560         echo "Test 1: verify that fast read is 4 times faster on cache read"
17561
17562         # small read with fast read enabled
17563         $LCTL set_param -n llite.*.fast_read=1
17564         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17565                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17566                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17567         # small read with fast read disabled
17568         $LCTL set_param -n llite.*.fast_read=0
17569         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17570                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17571                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17572
17573         # verify that fast read is 4 times faster for cache read
17574         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
17575                 error_not_in_vm "fast read was not 4 times faster: " \
17576                            "$t_fast vs $t_slow"
17577
17578         echo "Test 2: verify the performance between big and small read"
17579         $LCTL set_param -n llite.*.fast_read=1
17580
17581         # 1k non-cache read
17582         cancel_lru_locks osc
17583         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17584                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17585                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17586
17587         # 1M non-cache read
17588         cancel_lru_locks osc
17589         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17590                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17591                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17592
17593         # verify that big IO is not 4 times faster than small IO
17594         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
17595                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
17596
17597         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
17598         rm -f $DIR/$tfile
17599 }
17600 run_test 248a "fast read verification"
17601
17602 test_248b() {
17603         # Default short_io_bytes=16384, try both smaller and larger sizes.
17604         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
17605         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
17606         echo "bs=53248 count=113 normal buffered write"
17607         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
17608                 error "dd of initial data file failed"
17609         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
17610
17611         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
17612         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
17613                 error "dd with sync normal writes failed"
17614         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
17615
17616         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
17617         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
17618                 error "dd with sync small writes failed"
17619         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
17620
17621         cancel_lru_locks osc
17622
17623         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
17624         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
17625         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
17626         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
17627                 iflag=direct || error "dd with O_DIRECT small read failed"
17628         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
17629         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
17630                 error "compare $TMP/$tfile.1 failed"
17631
17632         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
17633         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
17634
17635         # just to see what the maximum tunable value is, and test parsing
17636         echo "test invalid parameter 2MB"
17637         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
17638                 error "too-large short_io_bytes allowed"
17639         echo "test maximum parameter 512KB"
17640         # if we can set a larger short_io_bytes, run test regardless of version
17641         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
17642                 # older clients may not allow setting it this large, that's OK
17643                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
17644                         skip "Need at least client version 2.13.50"
17645                 error "medium short_io_bytes failed"
17646         fi
17647         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
17648         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
17649
17650         echo "test large parameter 64KB"
17651         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
17652         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
17653
17654         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
17655         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
17656                 error "dd with sync large writes failed"
17657         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
17658
17659         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
17660         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
17661         num=$((113 * 4096 / PAGE_SIZE))
17662         echo "bs=$size count=$num oflag=direct large write $tfile.3"
17663         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
17664                 error "dd with O_DIRECT large writes failed"
17665         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
17666                 error "compare $DIR/$tfile.3 failed"
17667
17668         cancel_lru_locks osc
17669
17670         echo "bs=$size count=$num iflag=direct large read $tfile.2"
17671         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
17672                 error "dd with O_DIRECT large read failed"
17673         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
17674                 error "compare $TMP/$tfile.2 failed"
17675
17676         echo "bs=$size count=$num iflag=direct large read $tfile.3"
17677         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
17678                 error "dd with O_DIRECT large read failed"
17679         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
17680                 error "compare $TMP/$tfile.3 failed"
17681 }
17682 run_test 248b "test short_io read and write for both small and large sizes"
17683
17684 test_249() { # LU-7890
17685         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
17686                 skip "Need at least version 2.8.54"
17687
17688         rm -f $DIR/$tfile
17689         $LFS setstripe -c 1 $DIR/$tfile
17690         # Offset 2T == 4k * 512M
17691         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
17692                 error "dd to 2T offset failed"
17693 }
17694 run_test 249 "Write above 2T file size"
17695
17696 test_250() {
17697         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
17698          && skip "no 16TB file size limit on ZFS"
17699
17700         $LFS setstripe -c 1 $DIR/$tfile
17701         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
17702         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
17703         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
17704         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
17705                 conv=notrunc,fsync && error "append succeeded"
17706         return 0
17707 }
17708 run_test 250 "Write above 16T limit"
17709
17710 test_251() {
17711         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
17712
17713         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
17714         #Skip once - writing the first stripe will succeed
17715         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17716         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
17717                 error "short write happened"
17718
17719         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17720         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
17721                 error "short read happened"
17722
17723         rm -f $DIR/$tfile
17724 }
17725 run_test 251 "Handling short read and write correctly"
17726
17727 test_252() {
17728         remote_mds_nodsh && skip "remote MDS with nodsh"
17729         remote_ost_nodsh && skip "remote OST with nodsh"
17730         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
17731                 skip_env "ldiskfs only test"
17732         fi
17733
17734         local tgt
17735         local dev
17736         local out
17737         local uuid
17738         local num
17739         local gen
17740
17741         # check lr_reader on OST0000
17742         tgt=ost1
17743         dev=$(facet_device $tgt)
17744         out=$(do_facet $tgt $LR_READER $dev)
17745         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17746         echo "$out"
17747         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
17748         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
17749                 error "Invalid uuid returned by $LR_READER on target $tgt"
17750         echo -e "uuid returned by $LR_READER is '$uuid'\n"
17751
17752         # check lr_reader -c on MDT0000
17753         tgt=mds1
17754         dev=$(facet_device $tgt)
17755         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
17756                 skip "$LR_READER does not support additional options"
17757         fi
17758         out=$(do_facet $tgt $LR_READER -c $dev)
17759         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17760         echo "$out"
17761         num=$(echo "$out" | grep -c "mdtlov")
17762         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
17763                 error "Invalid number of mdtlov clients returned by $LR_READER"
17764         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
17765
17766         # check lr_reader -cr on MDT0000
17767         out=$(do_facet $tgt $LR_READER -cr $dev)
17768         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17769         echo "$out"
17770         echo "$out" | grep -q "^reply_data:$" ||
17771                 error "$LR_READER should have returned 'reply_data' section"
17772         num=$(echo "$out" | grep -c "client_generation")
17773         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
17774 }
17775 run_test 252 "check lr_reader tool"
17776
17777 test_253() {
17778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17779         remote_mds_nodsh && skip "remote MDS with nodsh"
17780         remote_mgs_nodsh && skip "remote MGS with nodsh"
17781
17782         local ostidx=0
17783         local rc=0
17784         local ost_name=$(ostname_from_index $ostidx)
17785
17786         # on the mdt's osc
17787         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
17788         do_facet $SINGLEMDS $LCTL get_param -n \
17789                 osp.$mdtosc_proc1.reserved_mb_high ||
17790                 skip  "remote MDS does not support reserved_mb_high"
17791
17792         rm -rf $DIR/$tdir
17793         wait_mds_ost_sync
17794         wait_delete_completed
17795         mkdir $DIR/$tdir
17796
17797         pool_add $TESTNAME || error "Pool creation failed"
17798         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
17799
17800         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
17801                 error "Setstripe failed"
17802
17803         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
17804
17805         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
17806                     grep "watermarks")
17807         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
17808
17809         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17810                         osp.$mdtosc_proc1.prealloc_status)
17811         echo "prealloc_status $oa_status"
17812
17813         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
17814                 error "File creation should fail"
17815
17816         #object allocation was stopped, but we still able to append files
17817         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
17818                 oflag=append || error "Append failed"
17819
17820         rm -f $DIR/$tdir/$tfile.0
17821
17822         # For this test, we want to delete the files we created to go out of
17823         # space but leave the watermark, so we remain nearly out of space
17824         ost_watermarks_enospc_delete_files $tfile $ostidx
17825
17826         wait_delete_completed
17827
17828         sleep_maxage
17829
17830         for i in $(seq 10 12); do
17831                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
17832                         2>/dev/null || error "File creation failed after rm"
17833         done
17834
17835         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17836                         osp.$mdtosc_proc1.prealloc_status)
17837         echo "prealloc_status $oa_status"
17838
17839         if (( oa_status != 0 )); then
17840                 error "Object allocation still disable after rm"
17841         fi
17842 }
17843 run_test 253 "Check object allocation limit"
17844
17845 test_254() {
17846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17847         remote_mds_nodsh && skip "remote MDS with nodsh"
17848         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
17849                 skip "MDS does not support changelog_size"
17850
17851         local cl_user
17852         local MDT0=$(facet_svc $SINGLEMDS)
17853
17854         changelog_register || error "changelog_register failed"
17855
17856         changelog_clear 0 || error "changelog_clear failed"
17857
17858         local size1=$(do_facet $SINGLEMDS \
17859                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17860         echo "Changelog size $size1"
17861
17862         rm -rf $DIR/$tdir
17863         $LFS mkdir -i 0 $DIR/$tdir
17864         # change something
17865         mkdir -p $DIR/$tdir/pics/2008/zachy
17866         touch $DIR/$tdir/pics/2008/zachy/timestamp
17867         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
17868         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17869         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17870         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17871         rm $DIR/$tdir/pics/desktop.jpg
17872
17873         local size2=$(do_facet $SINGLEMDS \
17874                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17875         echo "Changelog size after work $size2"
17876
17877         (( $size2 > $size1 )) ||
17878                 error "new Changelog size=$size2 less than old size=$size1"
17879 }
17880 run_test 254 "Check changelog size"
17881
17882 ladvise_no_type()
17883 {
17884         local type=$1
17885         local file=$2
17886
17887         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
17888                 awk -F: '{print $2}' | grep $type > /dev/null
17889         if [ $? -ne 0 ]; then
17890                 return 0
17891         fi
17892         return 1
17893 }
17894
17895 ladvise_no_ioctl()
17896 {
17897         local file=$1
17898
17899         lfs ladvise -a willread $file > /dev/null 2>&1
17900         if [ $? -eq 0 ]; then
17901                 return 1
17902         fi
17903
17904         lfs ladvise -a willread $file 2>&1 |
17905                 grep "Inappropriate ioctl for device" > /dev/null
17906         if [ $? -eq 0 ]; then
17907                 return 0
17908         fi
17909         return 1
17910 }
17911
17912 percent() {
17913         bc <<<"scale=2; ($1 - $2) * 100 / $2"
17914 }
17915
17916 # run a random read IO workload
17917 # usage: random_read_iops <filename> <filesize> <iosize>
17918 random_read_iops() {
17919         local file=$1
17920         local fsize=$2
17921         local iosize=${3:-4096}
17922
17923         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
17924                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
17925 }
17926
17927 drop_file_oss_cache() {
17928         local file="$1"
17929         local nodes="$2"
17930
17931         $LFS ladvise -a dontneed $file 2>/dev/null ||
17932                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
17933 }
17934
17935 ladvise_willread_performance()
17936 {
17937         local repeat=10
17938         local average_origin=0
17939         local average_cache=0
17940         local average_ladvise=0
17941
17942         for ((i = 1; i <= $repeat; i++)); do
17943                 echo "Iter $i/$repeat: reading without willread hint"
17944                 cancel_lru_locks osc
17945                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17946                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
17947                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
17948                 average_origin=$(bc <<<"$average_origin + $speed_origin")
17949
17950                 cancel_lru_locks osc
17951                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
17952                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
17953                 average_cache=$(bc <<<"$average_cache + $speed_cache")
17954
17955                 cancel_lru_locks osc
17956                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17957                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
17958                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
17959                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
17960                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
17961         done
17962         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
17963         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
17964         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
17965
17966         speedup_cache=$(percent $average_cache $average_origin)
17967         speedup_ladvise=$(percent $average_ladvise $average_origin)
17968
17969         echo "Average uncached read: $average_origin"
17970         echo "Average speedup with OSS cached read: " \
17971                 "$average_cache = +$speedup_cache%"
17972         echo "Average speedup with ladvise willread: " \
17973                 "$average_ladvise = +$speedup_ladvise%"
17974
17975         local lowest_speedup=20
17976         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
17977                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
17978                         "got $average_cache%. Skipping ladvise willread check."
17979                 return 0
17980         fi
17981
17982         # the test won't work on ZFS until it supports 'ladvise dontneed', but
17983         # it is still good to run until then to exercise 'ladvise willread'
17984         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17985                 [ "$ost1_FSTYPE" = "zfs" ] &&
17986                 echo "osd-zfs does not support dontneed or drop_caches" &&
17987                 return 0
17988
17989         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
17990         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
17991                 error_not_in_vm "Speedup with willread is less than " \
17992                         "$lowest_speedup%, got $average_ladvise%"
17993 }
17994
17995 test_255a() {
17996         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17997                 skip "lustre < 2.8.54 does not support ladvise "
17998         remote_ost_nodsh && skip "remote OST with nodsh"
17999
18000         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
18001
18002         ladvise_no_type willread $DIR/$tfile &&
18003                 skip "willread ladvise is not supported"
18004
18005         ladvise_no_ioctl $DIR/$tfile &&
18006                 skip "ladvise ioctl is not supported"
18007
18008         local size_mb=100
18009         local size=$((size_mb * 1048576))
18010         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
18011                 error "dd to $DIR/$tfile failed"
18012
18013         lfs ladvise -a willread $DIR/$tfile ||
18014                 error "Ladvise failed with no range argument"
18015
18016         lfs ladvise -a willread -s 0 $DIR/$tfile ||
18017                 error "Ladvise failed with no -l or -e argument"
18018
18019         lfs ladvise -a willread -e 1 $DIR/$tfile ||
18020                 error "Ladvise failed with only -e argument"
18021
18022         lfs ladvise -a willread -l 1 $DIR/$tfile ||
18023                 error "Ladvise failed with only -l argument"
18024
18025         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
18026                 error "End offset should not be smaller than start offset"
18027
18028         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
18029                 error "End offset should not be equal to start offset"
18030
18031         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
18032                 error "Ladvise failed with overflowing -s argument"
18033
18034         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
18035                 error "Ladvise failed with overflowing -e argument"
18036
18037         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
18038                 error "Ladvise failed with overflowing -l argument"
18039
18040         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
18041                 error "Ladvise succeeded with conflicting -l and -e arguments"
18042
18043         echo "Synchronous ladvise should wait"
18044         local delay=4
18045 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
18046         do_nodes $(comma_list $(osts_nodes)) \
18047                 $LCTL set_param fail_val=$delay fail_loc=0x237
18048
18049         local start_ts=$SECONDS
18050         lfs ladvise -a willread $DIR/$tfile ||
18051                 error "Ladvise failed with no range argument"
18052         local end_ts=$SECONDS
18053         local inteval_ts=$((end_ts - start_ts))
18054
18055         if [ $inteval_ts -lt $(($delay - 1)) ]; then
18056                 error "Synchronous advice didn't wait reply"
18057         fi
18058
18059         echo "Asynchronous ladvise shouldn't wait"
18060         local start_ts=$SECONDS
18061         lfs ladvise -a willread -b $DIR/$tfile ||
18062                 error "Ladvise failed with no range argument"
18063         local end_ts=$SECONDS
18064         local inteval_ts=$((end_ts - start_ts))
18065
18066         if [ $inteval_ts -gt $(($delay / 2)) ]; then
18067                 error "Asynchronous advice blocked"
18068         fi
18069
18070         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
18071         ladvise_willread_performance
18072 }
18073 run_test 255a "check 'lfs ladvise -a willread'"
18074
18075 facet_meminfo() {
18076         local facet=$1
18077         local info=$2
18078
18079         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
18080 }
18081
18082 test_255b() {
18083         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
18084                 skip "lustre < 2.8.54 does not support ladvise "
18085         remote_ost_nodsh && skip "remote OST with nodsh"
18086
18087         lfs setstripe -c 1 -i 0 $DIR/$tfile
18088
18089         ladvise_no_type dontneed $DIR/$tfile &&
18090                 skip "dontneed ladvise is not supported"
18091
18092         ladvise_no_ioctl $DIR/$tfile &&
18093                 skip "ladvise ioctl is not supported"
18094
18095         ! $LFS ladvise -a dontneed $DIR/$tfile &&
18096                 [ "$ost1_FSTYPE" = "zfs" ] &&
18097                 skip "zfs-osd does not support 'ladvise dontneed'"
18098
18099         local size_mb=100
18100         local size=$((size_mb * 1048576))
18101         # In order to prevent disturbance of other processes, only check 3/4
18102         # of the memory usage
18103         local kibibytes=$((size_mb * 1024 * 3 / 4))
18104
18105         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
18106                 error "dd to $DIR/$tfile failed"
18107
18108         #force write to complete before dropping OST cache & checking memory
18109         sync
18110
18111         local total=$(facet_meminfo ost1 MemTotal)
18112         echo "Total memory: $total KiB"
18113
18114         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
18115         local before_read=$(facet_meminfo ost1 Cached)
18116         echo "Cache used before read: $before_read KiB"
18117
18118         lfs ladvise -a willread $DIR/$tfile ||
18119                 error "Ladvise willread failed"
18120         local after_read=$(facet_meminfo ost1 Cached)
18121         echo "Cache used after read: $after_read KiB"
18122
18123         lfs ladvise -a dontneed $DIR/$tfile ||
18124                 error "Ladvise dontneed again failed"
18125         local no_read=$(facet_meminfo ost1 Cached)
18126         echo "Cache used after dontneed ladvise: $no_read KiB"
18127
18128         if [ $total -lt $((before_read + kibibytes)) ]; then
18129                 echo "Memory is too small, abort checking"
18130                 return 0
18131         fi
18132
18133         if [ $((before_read + kibibytes)) -gt $after_read ]; then
18134                 error "Ladvise willread should use more memory" \
18135                         "than $kibibytes KiB"
18136         fi
18137
18138         if [ $((no_read + kibibytes)) -gt $after_read ]; then
18139                 error "Ladvise dontneed should release more memory" \
18140                         "than $kibibytes KiB"
18141         fi
18142 }
18143 run_test 255b "check 'lfs ladvise -a dontneed'"
18144
18145 test_255c() {
18146         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
18147                 skip "lustre < 2.10.50 does not support lockahead"
18148
18149         local count
18150         local new_count
18151         local difference
18152         local i
18153         local rc
18154
18155         test_mkdir -p $DIR/$tdir
18156         $LFS setstripe -i 0 -c 1 $DIR/$tdir
18157
18158         #test 10 returns only success/failure
18159         i=10
18160         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18161         rc=$?
18162         if [ $rc -eq 255 ]; then
18163                 error "Ladvise test${i} failed, ${rc}"
18164         fi
18165
18166         #test 11 counts lock enqueue requests, all others count new locks
18167         i=11
18168         count=$(do_facet ost1 \
18169                 $LCTL get_param -n ost.OSS.ost.stats)
18170         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
18171
18172         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18173         rc=$?
18174         if [ $rc -eq 255 ]; then
18175                 error "Ladvise test${i} failed, ${rc}"
18176         fi
18177
18178         new_count=$(do_facet ost1 \
18179                 $LCTL get_param -n ost.OSS.ost.stats)
18180         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
18181                    awk '{ print $2 }')
18182
18183         difference="$((new_count - count))"
18184         if [ $difference -ne $rc ]; then
18185                 error "Ladvise test${i}, bad enqueue count, returned " \
18186                       "${rc}, actual ${difference}"
18187         fi
18188
18189         for i in $(seq 12 21); do
18190                 # If we do not do this, we run the risk of having too many
18191                 # locks and starting lock cancellation while we are checking
18192                 # lock counts.
18193                 cancel_lru_locks osc
18194
18195                 count=$($LCTL get_param -n \
18196                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
18197
18198                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
18199                 rc=$?
18200                 if [ $rc -eq 255 ]; then
18201                         error "Ladvise test ${i} failed, ${rc}"
18202                 fi
18203
18204                 new_count=$($LCTL get_param -n \
18205                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
18206                 difference="$((new_count - count))"
18207
18208                 # Test 15 output is divided by 100 to map down to valid return
18209                 if [ $i -eq 15 ]; then
18210                         rc="$((rc * 100))"
18211                 fi
18212
18213                 if [ $difference -ne $rc ]; then
18214                         error "Ladvise test ${i}, bad lock count, returned " \
18215                               "${rc}, actual ${difference}"
18216                 fi
18217         done
18218
18219         #test 22 returns only success/failure
18220         i=22
18221         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18222         rc=$?
18223         if [ $rc -eq 255 ]; then
18224                 error "Ladvise test${i} failed, ${rc}"
18225         fi
18226 }
18227 run_test 255c "suite of ladvise lockahead tests"
18228
18229 test_256() {
18230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18231         remote_mds_nodsh && skip "remote MDS with nodsh"
18232         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18233         changelog_users $SINGLEMDS | grep "^cl" &&
18234                 skip "active changelog user"
18235
18236         local cl_user
18237         local cat_sl
18238         local mdt_dev
18239
18240         mdt_dev=$(mdsdevname 1)
18241         echo $mdt_dev
18242
18243         changelog_register || error "changelog_register failed"
18244
18245         rm -rf $DIR/$tdir
18246         mkdir -p $DIR/$tdir
18247
18248         changelog_clear 0 || error "changelog_clear failed"
18249
18250         # change something
18251         touch $DIR/$tdir/{1..10}
18252
18253         # stop the MDT
18254         stop $SINGLEMDS || error "Fail to stop MDT"
18255
18256         # remount the MDT
18257
18258         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
18259
18260         #after mount new plainllog is used
18261         touch $DIR/$tdir/{11..19}
18262         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
18263         stack_trap "rm -f $tmpfile"
18264         cat_sl=$(do_facet $SINGLEMDS "sync; \
18265                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18266                  llog_reader $tmpfile | grep -c type=1064553b")
18267         do_facet $SINGLEMDS llog_reader $tmpfile
18268
18269         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
18270
18271         changelog_clear 0 || error "changelog_clear failed"
18272
18273         cat_sl=$(do_facet $SINGLEMDS "sync; \
18274                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18275                  llog_reader $tmpfile | grep -c type=1064553b")
18276
18277         if (( cat_sl == 2 )); then
18278                 error "Empty plain llog was not deleted from changelog catalog"
18279         elif (( cat_sl != 1 )); then
18280                 error "Active plain llog shouldn't be deleted from catalog"
18281         fi
18282 }
18283 run_test 256 "Check llog delete for empty and not full state"
18284
18285 test_257() {
18286         remote_mds_nodsh && skip "remote MDS with nodsh"
18287         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
18288                 skip "Need MDS version at least 2.8.55"
18289
18290         test_mkdir $DIR/$tdir
18291
18292         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
18293                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
18294         stat $DIR/$tdir
18295
18296 #define OBD_FAIL_MDS_XATTR_REP                  0x161
18297         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18298         local facet=mds$((mdtidx + 1))
18299         set_nodes_failloc $(facet_active_host $facet) 0x80000161
18300         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
18301
18302         stop $facet || error "stop MDS failed"
18303         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
18304                 error "start MDS fail"
18305         wait_recovery_complete $facet
18306 }
18307 run_test 257 "xattr locks are not lost"
18308
18309 # Verify we take the i_mutex when security requires it
18310 test_258a() {
18311 #define OBD_FAIL_IMUTEX_SEC 0x141c
18312         $LCTL set_param fail_loc=0x141c
18313         touch $DIR/$tfile
18314         chmod u+s $DIR/$tfile
18315         chmod a+rwx $DIR/$tfile
18316         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18317         RC=$?
18318         if [ $RC -ne 0 ]; then
18319                 error "error, failed to take i_mutex, rc=$?"
18320         fi
18321         rm -f $DIR/$tfile
18322 }
18323 run_test 258a "verify i_mutex security behavior when suid attributes is set"
18324
18325 # Verify we do NOT take the i_mutex in the normal case
18326 test_258b() {
18327 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
18328         $LCTL set_param fail_loc=0x141d
18329         touch $DIR/$tfile
18330         chmod a+rwx $DIR
18331         chmod a+rw $DIR/$tfile
18332         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18333         RC=$?
18334         if [ $RC -ne 0 ]; then
18335                 error "error, took i_mutex unnecessarily, rc=$?"
18336         fi
18337         rm -f $DIR/$tfile
18338
18339 }
18340 run_test 258b "verify i_mutex security behavior"
18341
18342 test_259() {
18343         local file=$DIR/$tfile
18344         local before
18345         local after
18346
18347         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18348
18349         stack_trap "rm -f $file" EXIT
18350
18351         wait_delete_completed
18352         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18353         echo "before: $before"
18354
18355         $LFS setstripe -i 0 -c 1 $file
18356         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
18357         sync_all_data
18358         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18359         echo "after write: $after"
18360
18361 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
18362         do_facet ost1 $LCTL set_param fail_loc=0x2301
18363         $TRUNCATE $file 0
18364         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18365         echo "after truncate: $after"
18366
18367         stop ost1
18368         do_facet ost1 $LCTL set_param fail_loc=0
18369         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18370         sleep 2
18371         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18372         echo "after restart: $after"
18373         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
18374                 error "missing truncate?"
18375
18376         return 0
18377 }
18378 run_test 259 "crash at delayed truncate"
18379
18380 test_260() {
18381 #define OBD_FAIL_MDC_CLOSE               0x806
18382         $LCTL set_param fail_loc=0x80000806
18383         touch $DIR/$tfile
18384
18385 }
18386 run_test 260 "Check mdc_close fail"
18387
18388 ### Data-on-MDT sanity tests ###
18389 test_270a() {
18390         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18391                 skip "Need MDS version at least 2.10.55 for DoM"
18392
18393         # create DoM file
18394         local dom=$DIR/$tdir/dom_file
18395         local tmp=$DIR/$tdir/tmp_file
18396
18397         mkdir -p $DIR/$tdir
18398
18399         # basic checks for DoM component creation
18400         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
18401                 error "Can set MDT layout to non-first entry"
18402
18403         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
18404                 error "Can define multiple entries as MDT layout"
18405
18406         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
18407
18408         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
18409         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
18410         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
18411
18412         local mdtidx=$($LFS getstripe -m $dom)
18413         local mdtname=MDT$(printf %04x $mdtidx)
18414         local facet=mds$((mdtidx + 1))
18415         local space_check=1
18416
18417         # Skip free space checks with ZFS
18418         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
18419
18420         # write
18421         sync
18422         local size_tmp=$((65536 * 3))
18423         local mdtfree1=$(do_facet $facet \
18424                          lctl get_param -n osd*.*$mdtname.kbytesfree)
18425
18426         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18427         # check also direct IO along write
18428         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
18429         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18430         sync
18431         cmp $tmp $dom || error "file data is different"
18432         [ $(stat -c%s $dom) == $size_tmp ] ||
18433                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18434         if [ $space_check == 1 ]; then
18435                 local mdtfree2=$(do_facet $facet \
18436                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
18437
18438                 # increase in usage from by $size_tmp
18439                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18440                         error "MDT free space wrong after write: " \
18441                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18442         fi
18443
18444         # truncate
18445         local size_dom=10000
18446
18447         $TRUNCATE $dom $size_dom
18448         [ $(stat -c%s $dom) == $size_dom ] ||
18449                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
18450         if [ $space_check == 1 ]; then
18451                 mdtfree1=$(do_facet $facet \
18452                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18453                 # decrease in usage from $size_tmp to new $size_dom
18454                 [ $(($mdtfree1 - $mdtfree2)) -ge \
18455                   $(((size_tmp - size_dom) / 1024)) ] ||
18456                         error "MDT free space is wrong after truncate: " \
18457                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
18458         fi
18459
18460         # append
18461         cat $tmp >> $dom
18462         sync
18463         size_dom=$((size_dom + size_tmp))
18464         [ $(stat -c%s $dom) == $size_dom ] ||
18465                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
18466         if [ $space_check == 1 ]; then
18467                 mdtfree2=$(do_facet $facet \
18468                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18469                 # increase in usage by $size_tmp from previous
18470                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18471                         error "MDT free space is wrong after append: " \
18472                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18473         fi
18474
18475         # delete
18476         rm $dom
18477         if [ $space_check == 1 ]; then
18478                 mdtfree1=$(do_facet $facet \
18479                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18480                 # decrease in usage by $size_dom from previous
18481                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
18482                         error "MDT free space is wrong after removal: " \
18483                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
18484         fi
18485
18486         # combined striping
18487         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
18488                 error "Can't create DoM + OST striping"
18489
18490         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
18491         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18492         # check also direct IO along write
18493         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18494         sync
18495         cmp $tmp $dom || error "file data is different"
18496         [ $(stat -c%s $dom) == $size_tmp ] ||
18497                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18498         rm $dom $tmp
18499
18500         return 0
18501 }
18502 run_test 270a "DoM: basic functionality tests"
18503
18504 test_270b() {
18505         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18506                 skip "Need MDS version at least 2.10.55"
18507
18508         local dom=$DIR/$tdir/dom_file
18509         local max_size=1048576
18510
18511         mkdir -p $DIR/$tdir
18512         $LFS setstripe -E $max_size -L mdt $dom
18513
18514         # truncate over the limit
18515         $TRUNCATE $dom $(($max_size + 1)) &&
18516                 error "successful truncate over the maximum size"
18517         # write over the limit
18518         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
18519                 error "successful write over the maximum size"
18520         # append over the limit
18521         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
18522         echo "12345" >> $dom && error "successful append over the maximum size"
18523         rm $dom
18524
18525         return 0
18526 }
18527 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
18528
18529 test_270c() {
18530         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18531                 skip "Need MDS version at least 2.10.55"
18532
18533         mkdir -p $DIR/$tdir
18534         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18535
18536         # check files inherit DoM EA
18537         touch $DIR/$tdir/first
18538         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
18539                 error "bad pattern"
18540         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
18541                 error "bad stripe count"
18542         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
18543                 error "bad stripe size"
18544
18545         # check directory inherits DoM EA and uses it as default
18546         mkdir $DIR/$tdir/subdir
18547         touch $DIR/$tdir/subdir/second
18548         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
18549                 error "bad pattern in sub-directory"
18550         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
18551                 error "bad stripe count in sub-directory"
18552         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
18553                 error "bad stripe size in sub-directory"
18554         return 0
18555 }
18556 run_test 270c "DoM: DoM EA inheritance tests"
18557
18558 test_270d() {
18559         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18560                 skip "Need MDS version at least 2.10.55"
18561
18562         mkdir -p $DIR/$tdir
18563         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18564
18565         # inherit default DoM striping
18566         mkdir $DIR/$tdir/subdir
18567         touch $DIR/$tdir/subdir/f1
18568
18569         # change default directory striping
18570         $LFS setstripe -c 1 $DIR/$tdir/subdir
18571         touch $DIR/$tdir/subdir/f2
18572         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
18573                 error "wrong default striping in file 2"
18574         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
18575                 error "bad pattern in file 2"
18576         return 0
18577 }
18578 run_test 270d "DoM: change striping from DoM to RAID0"
18579
18580 test_270e() {
18581         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18582                 skip "Need MDS version at least 2.10.55"
18583
18584         mkdir -p $DIR/$tdir/dom
18585         mkdir -p $DIR/$tdir/norm
18586         DOMFILES=20
18587         NORMFILES=10
18588         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
18589         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
18590
18591         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
18592         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
18593
18594         # find DoM files by layout
18595         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
18596         [ $NUM -eq  $DOMFILES ] ||
18597                 error "lfs find -L: found $NUM, expected $DOMFILES"
18598         echo "Test 1: lfs find 20 DOM files by layout: OK"
18599
18600         # there should be 1 dir with default DOM striping
18601         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
18602         [ $NUM -eq  1 ] ||
18603                 error "lfs find -L: found $NUM, expected 1 dir"
18604         echo "Test 2: lfs find 1 DOM dir by layout: OK"
18605
18606         # find DoM files by stripe size
18607         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
18608         [ $NUM -eq  $DOMFILES ] ||
18609                 error "lfs find -S: found $NUM, expected $DOMFILES"
18610         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
18611
18612         # find files by stripe offset except DoM files
18613         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
18614         [ $NUM -eq  $NORMFILES ] ||
18615                 error "lfs find -i: found $NUM, expected $NORMFILES"
18616         echo "Test 5: lfs find no DOM files by stripe index: OK"
18617         return 0
18618 }
18619 run_test 270e "DoM: lfs find with DoM files test"
18620
18621 test_270f() {
18622         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18623                 skip "Need MDS version at least 2.10.55"
18624
18625         local mdtname=${FSNAME}-MDT0000-mdtlov
18626         local dom=$DIR/$tdir/dom_file
18627         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
18628                                                 lod.$mdtname.dom_stripesize)
18629         local dom_limit=131072
18630
18631         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
18632         local dom_current=$(do_facet mds1 $LCTL get_param -n \
18633                                                 lod.$mdtname.dom_stripesize)
18634         [ ${dom_limit} -eq ${dom_current} ] ||
18635                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
18636
18637         $LFS mkdir -i 0 -c 1 $DIR/$tdir
18638         $LFS setstripe -d $DIR/$tdir
18639         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
18640                 error "Can't set directory default striping"
18641
18642         # exceed maximum stripe size
18643         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18644                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
18645         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
18646                 error "Able to create DoM component size more than LOD limit"
18647
18648         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
18649         dom_current=$(do_facet mds1 $LCTL get_param -n \
18650                                                 lod.$mdtname.dom_stripesize)
18651         [ 0 -eq ${dom_current} ] ||
18652                 error "Can't set zero DoM stripe limit"
18653         rm $dom
18654
18655         # attempt to create DoM file on server with disabled DoM should
18656         # remove DoM entry from layout and be succeed
18657         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
18658                 error "Can't create DoM file (DoM is disabled)"
18659         [ $($LFS getstripe -L $dom) == "mdt" ] &&
18660                 error "File has DoM component while DoM is disabled"
18661         rm $dom
18662
18663         # attempt to create DoM file with only DoM stripe should return error
18664         $LFS setstripe -E $dom_limit -L mdt $dom &&
18665                 error "Able to create DoM-only file while DoM is disabled"
18666
18667         # too low values to be aligned with smallest stripe size 64K
18668         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
18669         dom_current=$(do_facet mds1 $LCTL get_param -n \
18670                                                 lod.$mdtname.dom_stripesize)
18671         [ 30000 -eq ${dom_current} ] &&
18672                 error "Can set too small DoM stripe limit"
18673
18674         # 64K is a minimal stripe size in Lustre, expect limit of that size
18675         [ 65536 -eq ${dom_current} ] ||
18676                 error "Limit is not set to 64K but ${dom_current}"
18677
18678         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
18679         dom_current=$(do_facet mds1 $LCTL get_param -n \
18680                                                 lod.$mdtname.dom_stripesize)
18681         echo $dom_current
18682         [ 2147483648 -eq ${dom_current} ] &&
18683                 error "Can set too large DoM stripe limit"
18684
18685         do_facet mds1 $LCTL set_param -n \
18686                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
18687         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18688                 error "Can't create DoM component size after limit change"
18689         do_facet mds1 $LCTL set_param -n \
18690                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
18691         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
18692                 error "Can't create DoM file after limit decrease"
18693         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
18694                 error "Can create big DoM component after limit decrease"
18695         touch ${dom}_def ||
18696                 error "Can't create file with old default layout"
18697
18698         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
18699         return 0
18700 }
18701 run_test 270f "DoM: maximum DoM stripe size checks"
18702
18703 test_271a() {
18704         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18705                 skip "Need MDS version at least 2.10.55"
18706
18707         local dom=$DIR/$tdir/dom
18708
18709         mkdir -p $DIR/$tdir
18710
18711         $LFS setstripe -E 1024K -L mdt $dom
18712
18713         lctl set_param -n mdc.*.stats=clear
18714         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18715         cat $dom > /dev/null
18716         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
18717         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
18718         ls $dom
18719         rm -f $dom
18720 }
18721 run_test 271a "DoM: data is cached for read after write"
18722
18723 test_271b() {
18724         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18725                 skip "Need MDS version at least 2.10.55"
18726
18727         local dom=$DIR/$tdir/dom
18728
18729         mkdir -p $DIR/$tdir
18730
18731         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18732
18733         lctl set_param -n mdc.*.stats=clear
18734         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18735         cancel_lru_locks mdc
18736         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
18737         # second stat to check size is cached on client
18738         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
18739         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18740         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
18741         rm -f $dom
18742 }
18743 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
18744
18745 test_271ba() {
18746         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18747                 skip "Need MDS version at least 2.10.55"
18748
18749         local dom=$DIR/$tdir/dom
18750
18751         mkdir -p $DIR/$tdir
18752
18753         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18754
18755         lctl set_param -n mdc.*.stats=clear
18756         lctl set_param -n osc.*.stats=clear
18757         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
18758         cancel_lru_locks mdc
18759         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18760         # second stat to check size is cached on client
18761         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18762         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18763         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
18764         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
18765         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
18766         rm -f $dom
18767 }
18768 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
18769
18770
18771 get_mdc_stats() {
18772         local mdtidx=$1
18773         local param=$2
18774         local mdt=MDT$(printf %04x $mdtidx)
18775
18776         if [ -z $param ]; then
18777                 lctl get_param -n mdc.*$mdt*.stats
18778         else
18779                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
18780         fi
18781 }
18782
18783 test_271c() {
18784         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18785                 skip "Need MDS version at least 2.10.55"
18786
18787         local dom=$DIR/$tdir/dom
18788
18789         mkdir -p $DIR/$tdir
18790
18791         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18792
18793         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18794         local facet=mds$((mdtidx + 1))
18795
18796         cancel_lru_locks mdc
18797         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
18798         createmany -o $dom 1000
18799         lctl set_param -n mdc.*.stats=clear
18800         smalliomany -w $dom 1000 200
18801         get_mdc_stats $mdtidx
18802         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18803         # Each file has 1 open, 1 IO enqueues, total 2000
18804         # but now we have also +1 getxattr for security.capability, total 3000
18805         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
18806         unlinkmany $dom 1000
18807
18808         cancel_lru_locks mdc
18809         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
18810         createmany -o $dom 1000
18811         lctl set_param -n mdc.*.stats=clear
18812         smalliomany -w $dom 1000 200
18813         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18814         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
18815         # for OPEN and IO lock.
18816         [ $((enq - enq_2)) -ge 1000 ] ||
18817                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
18818         unlinkmany $dom 1000
18819         return 0
18820 }
18821 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
18822
18823 cleanup_271def_tests() {
18824         trap 0
18825         rm -f $1
18826 }
18827
18828 test_271d() {
18829         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18830                 skip "Need MDS version at least 2.10.57"
18831
18832         local dom=$DIR/$tdir/dom
18833         local tmp=$TMP/$tfile
18834         trap "cleanup_271def_tests $tmp" EXIT
18835
18836         mkdir -p $DIR/$tdir
18837
18838         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18839
18840         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18841
18842         cancel_lru_locks mdc
18843         dd if=/dev/urandom of=$tmp bs=1000 count=1
18844         dd if=$tmp of=$dom bs=1000 count=1
18845         cancel_lru_locks mdc
18846
18847         cat /etc/hosts >> $tmp
18848         lctl set_param -n mdc.*.stats=clear
18849
18850         # append data to the same file it should update local page
18851         echo "Append to the same page"
18852         cat /etc/hosts >> $dom
18853         local num=$(get_mdc_stats $mdtidx ost_read)
18854         local ra=$(get_mdc_stats $mdtidx req_active)
18855         local rw=$(get_mdc_stats $mdtidx req_waittime)
18856
18857         [ -z $num ] || error "$num READ RPC occured"
18858         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18859         echo "... DONE"
18860
18861         # compare content
18862         cmp $tmp $dom || error "file miscompare"
18863
18864         cancel_lru_locks mdc
18865         lctl set_param -n mdc.*.stats=clear
18866
18867         echo "Open and read file"
18868         cat $dom > /dev/null
18869         local num=$(get_mdc_stats $mdtidx ost_read)
18870         local ra=$(get_mdc_stats $mdtidx req_active)
18871         local rw=$(get_mdc_stats $mdtidx req_waittime)
18872
18873         [ -z $num ] || error "$num READ RPC occured"
18874         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18875         echo "... DONE"
18876
18877         # compare content
18878         cmp $tmp $dom || error "file miscompare"
18879
18880         return 0
18881 }
18882 run_test 271d "DoM: read on open (1K file in reply buffer)"
18883
18884 test_271f() {
18885         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18886                 skip "Need MDS version at least 2.10.57"
18887
18888         local dom=$DIR/$tdir/dom
18889         local tmp=$TMP/$tfile
18890         trap "cleanup_271def_tests $tmp" EXIT
18891
18892         mkdir -p $DIR/$tdir
18893
18894         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18895
18896         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18897
18898         cancel_lru_locks mdc
18899         dd if=/dev/urandom of=$tmp bs=265000 count=1
18900         dd if=$tmp of=$dom bs=265000 count=1
18901         cancel_lru_locks mdc
18902         cat /etc/hosts >> $tmp
18903         lctl set_param -n mdc.*.stats=clear
18904
18905         echo "Append to the same page"
18906         cat /etc/hosts >> $dom
18907         local num=$(get_mdc_stats $mdtidx ost_read)
18908         local ra=$(get_mdc_stats $mdtidx req_active)
18909         local rw=$(get_mdc_stats $mdtidx req_waittime)
18910
18911         [ -z $num ] || error "$num READ RPC occured"
18912         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18913         echo "... DONE"
18914
18915         # compare content
18916         cmp $tmp $dom || error "file miscompare"
18917
18918         cancel_lru_locks mdc
18919         lctl set_param -n mdc.*.stats=clear
18920
18921         echo "Open and read file"
18922         cat $dom > /dev/null
18923         local num=$(get_mdc_stats $mdtidx ost_read)
18924         local ra=$(get_mdc_stats $mdtidx req_active)
18925         local rw=$(get_mdc_stats $mdtidx req_waittime)
18926
18927         [ -z $num ] && num=0
18928         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
18929         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18930         echo "... DONE"
18931
18932         # compare content
18933         cmp $tmp $dom || error "file miscompare"
18934
18935         return 0
18936 }
18937 run_test 271f "DoM: read on open (200K file and read tail)"
18938
18939 test_271g() {
18940         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
18941                 skip "Skipping due to old client or server version"
18942
18943         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
18944         # to get layout
18945         $CHECKSTAT -t file $DIR1/$tfile
18946
18947         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
18948         MULTIOP_PID=$!
18949         sleep 1
18950         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
18951         $LCTL set_param fail_loc=0x80000314
18952         rm $DIR1/$tfile || error "Unlink fails"
18953         RC=$?
18954         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
18955         [ $RC -eq 0 ] || error "Failed write to stale object"
18956 }
18957 run_test 271g "Discard DoM data vs client flush race"
18958
18959 test_272a() {
18960         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18961                 skip "Need MDS version at least 2.11.50"
18962
18963         local dom=$DIR/$tdir/dom
18964         mkdir -p $DIR/$tdir
18965
18966         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
18967         dd if=/dev/urandom of=$dom bs=512K count=1 ||
18968                 error "failed to write data into $dom"
18969         local old_md5=$(md5sum $dom)
18970
18971         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
18972                 error "failed to migrate to the same DoM component"
18973
18974         local new_md5=$(md5sum $dom)
18975
18976         [ "$old_md5" == "$new_md5" ] ||
18977                 error "md5sum differ: $old_md5, $new_md5"
18978
18979         [ $($LFS getstripe -c $dom) -eq 2 ] ||
18980                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
18981 }
18982 run_test 272a "DoM migration: new layout with the same DOM component"
18983
18984 test_272b() {
18985         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18986                 skip "Need MDS version at least 2.11.50"
18987
18988         local dom=$DIR/$tdir/dom
18989         mkdir -p $DIR/$tdir
18990         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18991
18992         local mdtidx=$($LFS getstripe -m $dom)
18993         local mdtname=MDT$(printf %04x $mdtidx)
18994         local facet=mds$((mdtidx + 1))
18995
18996         local mdtfree1=$(do_facet $facet \
18997                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18998         dd if=/dev/urandom of=$dom bs=2M count=1 ||
18999                 error "failed to write data into $dom"
19000         local old_md5=$(md5sum $dom)
19001         cancel_lru_locks mdc
19002         local mdtfree1=$(do_facet $facet \
19003                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19004
19005         $LFS migrate -c2 $dom ||
19006                 error "failed to migrate to the new composite layout"
19007         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19008                 error "MDT stripe was not removed"
19009
19010         cancel_lru_locks mdc
19011         local new_md5=$(md5sum $dom)
19012         [ "$old_md5" == "$new_md5" ] ||
19013                 error "$old_md5 != $new_md5"
19014
19015         # Skip free space checks with ZFS
19016         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19017                 local mdtfree2=$(do_facet $facet \
19018                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19019                 [ $mdtfree2 -gt $mdtfree1 ] ||
19020                         error "MDT space is not freed after migration"
19021         fi
19022         return 0
19023 }
19024 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
19025
19026 test_272c() {
19027         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19028                 skip "Need MDS version at least 2.11.50"
19029
19030         local dom=$DIR/$tdir/$tfile
19031         mkdir -p $DIR/$tdir
19032         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
19033
19034         local mdtidx=$($LFS getstripe -m $dom)
19035         local mdtname=MDT$(printf %04x $mdtidx)
19036         local facet=mds$((mdtidx + 1))
19037
19038         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
19039                 error "failed to write data into $dom"
19040         local old_md5=$(md5sum $dom)
19041         cancel_lru_locks mdc
19042         local mdtfree1=$(do_facet $facet \
19043                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19044
19045         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
19046                 error "failed to migrate to the new composite layout"
19047         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
19048                 error "MDT stripe was not removed"
19049
19050         cancel_lru_locks mdc
19051         local new_md5=$(md5sum $dom)
19052         [ "$old_md5" == "$new_md5" ] ||
19053                 error "$old_md5 != $new_md5"
19054
19055         # Skip free space checks with ZFS
19056         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19057                 local mdtfree2=$(do_facet $facet \
19058                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19059                 [ $mdtfree2 -gt $mdtfree1 ] ||
19060                         error "MDS space is not freed after migration"
19061         fi
19062         return 0
19063 }
19064 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
19065
19066 test_272d() {
19067         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19068                 skip "Need MDS version at least 2.12.55"
19069
19070         local dom=$DIR/$tdir/$tfile
19071         mkdir -p $DIR/$tdir
19072         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
19073
19074         local mdtidx=$($LFS getstripe -m $dom)
19075         local mdtname=MDT$(printf %04x $mdtidx)
19076         local facet=mds$((mdtidx + 1))
19077
19078         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
19079                 error "failed to write data into $dom"
19080         local old_md5=$(md5sum $dom)
19081         cancel_lru_locks mdc
19082         local mdtfree1=$(do_facet $facet \
19083                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19084
19085         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
19086                 error "failed mirroring to the new composite layout"
19087         $LFS mirror resync $dom ||
19088                 error "failed mirror resync"
19089         $LFS mirror split --mirror-id 1 -d $dom ||
19090                 error "failed mirror split"
19091
19092         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19093                 error "MDT stripe was not removed"
19094
19095         cancel_lru_locks mdc
19096         local new_md5=$(md5sum $dom)
19097         [ "$old_md5" == "$new_md5" ] ||
19098                 error "$old_md5 != $new_md5"
19099
19100         # Skip free space checks with ZFS
19101         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19102                 local mdtfree2=$(do_facet $facet \
19103                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19104                 [ $mdtfree2 -gt $mdtfree1 ] ||
19105                         error "MDS space is not freed after DOM mirror deletion"
19106         fi
19107         return 0
19108 }
19109 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
19110
19111 test_272e() {
19112         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19113                 skip "Need MDS version at least 2.12.55"
19114
19115         local dom=$DIR/$tdir/$tfile
19116         mkdir -p $DIR/$tdir
19117         $LFS setstripe -c 2 $dom
19118
19119         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
19120                 error "failed to write data into $dom"
19121         local old_md5=$(md5sum $dom)
19122         cancel_lru_locks mdc
19123
19124         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
19125                 error "failed mirroring to the DOM layout"
19126         $LFS mirror resync $dom ||
19127                 error "failed mirror resync"
19128         $LFS mirror split --mirror-id 1 -d $dom ||
19129                 error "failed mirror split"
19130
19131         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19132                 error "MDT stripe was not removed"
19133
19134         cancel_lru_locks mdc
19135         local new_md5=$(md5sum $dom)
19136         [ "$old_md5" == "$new_md5" ] ||
19137                 error "$old_md5 != $new_md5"
19138
19139         return 0
19140 }
19141 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
19142
19143 test_272f() {
19144         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19145                 skip "Need MDS version at least 2.12.55"
19146
19147         local dom=$DIR/$tdir/$tfile
19148         mkdir -p $DIR/$tdir
19149         $LFS setstripe -c 2 $dom
19150
19151         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
19152                 error "failed to write data into $dom"
19153         local old_md5=$(md5sum $dom)
19154         cancel_lru_locks mdc
19155
19156         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
19157                 error "failed migrating to the DOM file"
19158
19159         cancel_lru_locks mdc
19160         local new_md5=$(md5sum $dom)
19161         [ "$old_md5" != "$new_md5" ] &&
19162                 error "$old_md5 != $new_md5"
19163
19164         return 0
19165 }
19166 run_test 272f "DoM migration: OST-striped file to DOM file"
19167
19168 test_273a() {
19169         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19170                 skip "Need MDS version at least 2.11.50"
19171
19172         # Layout swap cannot be done if either file has DOM component,
19173         # this will never be supported, migration should be used instead
19174
19175         local dom=$DIR/$tdir/$tfile
19176         mkdir -p $DIR/$tdir
19177
19178         $LFS setstripe -c2 ${dom}_plain
19179         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
19180         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
19181                 error "can swap layout with DoM component"
19182         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
19183                 error "can swap layout with DoM component"
19184
19185         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
19186         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
19187                 error "can swap layout with DoM component"
19188         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
19189                 error "can swap layout with DoM component"
19190         return 0
19191 }
19192 run_test 273a "DoM: layout swapping should fail with DOM"
19193
19194 test_275() {
19195         remote_ost_nodsh && skip "remote OST with nodsh"
19196         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
19197                 skip "Need OST version >= 2.10.57"
19198
19199         local file=$DIR/$tfile
19200         local oss
19201
19202         oss=$(comma_list $(osts_nodes))
19203
19204         dd if=/dev/urandom of=$file bs=1M count=2 ||
19205                 error "failed to create a file"
19206         cancel_lru_locks osc
19207
19208         #lock 1
19209         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
19210                 error "failed to read a file"
19211
19212 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
19213         $LCTL set_param fail_loc=0x8000031f
19214
19215         cancel_lru_locks osc &
19216         sleep 1
19217
19218 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
19219         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
19220         #IO takes another lock, but matches the PENDING one
19221         #and places it to the IO RPC
19222         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
19223                 error "failed to read a file with PENDING lock"
19224 }
19225 run_test 275 "Read on a canceled duplicate lock"
19226
19227 test_276() {
19228         remote_ost_nodsh && skip "remote OST with nodsh"
19229         local pid
19230
19231         do_facet ost1 "(while true; do \
19232                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
19233                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
19234         pid=$!
19235
19236         for LOOP in $(seq 20); do
19237                 stop ost1
19238                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
19239         done
19240         kill -9 $pid
19241         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
19242                 rm $TMP/sanity_276_pid"
19243 }
19244 run_test 276 "Race between mount and obd_statfs"
19245
19246 test_277() {
19247         $LCTL set_param ldlm.namespaces.*.lru_size=0
19248         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
19249         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19250                         grep ^used_mb | awk '{print $2}')
19251         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
19252         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
19253                 oflag=direct conv=notrunc
19254         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19255                         grep ^used_mb | awk '{print $2}')
19256         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
19257 }
19258 run_test 277 "Direct IO shall drop page cache"
19259
19260 test_278() {
19261         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19262         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19263         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
19264                 skip "needs the same host for mdt1 mdt2" && return
19265
19266         local pid1
19267         local pid2
19268
19269 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
19270         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
19271         stop mds2 &
19272         pid2=$!
19273
19274         stop mds1
19275
19276         echo "Starting MDTs"
19277         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
19278         wait $pid2
19279 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
19280 #will return NULL
19281         do_facet mds2 $LCTL set_param fail_loc=0
19282
19283         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
19284         wait_recovery_complete mds2
19285 }
19286 run_test 278 "Race starting MDS between MDTs stop/start"
19287
19288 cleanup_test_300() {
19289         trap 0
19290         umask $SAVE_UMASK
19291 }
19292 test_striped_dir() {
19293         local mdt_index=$1
19294         local stripe_count
19295         local stripe_index
19296
19297         mkdir -p $DIR/$tdir
19298
19299         SAVE_UMASK=$(umask)
19300         trap cleanup_test_300 RETURN EXIT
19301
19302         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
19303                                                 $DIR/$tdir/striped_dir ||
19304                 error "set striped dir error"
19305
19306         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
19307         [ "$mode" = "755" ] || error "expect 755 got $mode"
19308
19309         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
19310                 error "getdirstripe failed"
19311         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
19312         if [ "$stripe_count" != "2" ]; then
19313                 error "1:stripe_count is $stripe_count, expect 2"
19314         fi
19315         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
19316         if [ "$stripe_count" != "2" ]; then
19317                 error "2:stripe_count is $stripe_count, expect 2"
19318         fi
19319
19320         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
19321         if [ "$stripe_index" != "$mdt_index" ]; then
19322                 error "stripe_index is $stripe_index, expect $mdt_index"
19323         fi
19324
19325         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19326                 error "nlink error after create striped dir"
19327
19328         mkdir $DIR/$tdir/striped_dir/a
19329         mkdir $DIR/$tdir/striped_dir/b
19330
19331         stat $DIR/$tdir/striped_dir/a ||
19332                 error "create dir under striped dir failed"
19333         stat $DIR/$tdir/striped_dir/b ||
19334                 error "create dir under striped dir failed"
19335
19336         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
19337                 error "nlink error after mkdir"
19338
19339         rmdir $DIR/$tdir/striped_dir/a
19340         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
19341                 error "nlink error after rmdir"
19342
19343         rmdir $DIR/$tdir/striped_dir/b
19344         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19345                 error "nlink error after rmdir"
19346
19347         chattr +i $DIR/$tdir/striped_dir
19348         createmany -o $DIR/$tdir/striped_dir/f 10 &&
19349                 error "immutable flags not working under striped dir!"
19350         chattr -i $DIR/$tdir/striped_dir
19351
19352         rmdir $DIR/$tdir/striped_dir ||
19353                 error "rmdir striped dir error"
19354
19355         cleanup_test_300
19356
19357         true
19358 }
19359
19360 test_300a() {
19361         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19362                 skip "skipped for lustre < 2.7.0"
19363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19364         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19365
19366         test_striped_dir 0 || error "failed on striped dir on MDT0"
19367         test_striped_dir 1 || error "failed on striped dir on MDT0"
19368 }
19369 run_test 300a "basic striped dir sanity test"
19370
19371 test_300b() {
19372         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19373                 skip "skipped for lustre < 2.7.0"
19374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19375         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19376
19377         local i
19378         local mtime1
19379         local mtime2
19380         local mtime3
19381
19382         test_mkdir $DIR/$tdir || error "mkdir fail"
19383         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19384                 error "set striped dir error"
19385         for i in {0..9}; do
19386                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
19387                 sleep 1
19388                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
19389                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
19390                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
19391                 sleep 1
19392                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
19393                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
19394                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
19395         done
19396         true
19397 }
19398 run_test 300b "check ctime/mtime for striped dir"
19399
19400 test_300c() {
19401         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19402                 skip "skipped for lustre < 2.7.0"
19403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19404         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19405
19406         local file_count
19407
19408         mkdir -p $DIR/$tdir
19409         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
19410                 error "set striped dir error"
19411
19412         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
19413                 error "chown striped dir failed"
19414
19415         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
19416                 error "create 5k files failed"
19417
19418         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
19419
19420         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
19421
19422         rm -rf $DIR/$tdir
19423 }
19424 run_test 300c "chown && check ls under striped directory"
19425
19426 test_300d() {
19427         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19428                 skip "skipped for lustre < 2.7.0"
19429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19430         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19431
19432         local stripe_count
19433         local file
19434
19435         mkdir -p $DIR/$tdir
19436         $LFS setstripe -c 2 $DIR/$tdir
19437
19438         #local striped directory
19439         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19440                 error "set striped dir error"
19441         createmany -o $DIR/$tdir/striped_dir/f 10 ||
19442                 error "create 10 files failed"
19443
19444         #remote striped directory
19445         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
19446                 error "set striped dir error"
19447         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
19448                 error "create 10 files failed"
19449
19450         for file in $(find $DIR/$tdir); do
19451                 stripe_count=$($LFS getstripe -c $file)
19452                 [ $stripe_count -eq 2 ] ||
19453                         error "wrong stripe $stripe_count for $file"
19454         done
19455
19456         rm -rf $DIR/$tdir
19457 }
19458 run_test 300d "check default stripe under striped directory"
19459
19460 test_300e() {
19461         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19462                 skip "Need MDS version at least 2.7.55"
19463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19464         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19465
19466         local stripe_count
19467         local file
19468
19469         mkdir -p $DIR/$tdir
19470
19471         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19472                 error "set striped dir error"
19473
19474         touch $DIR/$tdir/striped_dir/a
19475         touch $DIR/$tdir/striped_dir/b
19476         touch $DIR/$tdir/striped_dir/c
19477
19478         mkdir $DIR/$tdir/striped_dir/dir_a
19479         mkdir $DIR/$tdir/striped_dir/dir_b
19480         mkdir $DIR/$tdir/striped_dir/dir_c
19481
19482         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
19483                 error "set striped adir under striped dir error"
19484
19485         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
19486                 error "set striped bdir under striped dir error"
19487
19488         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
19489                 error "set striped cdir under striped dir error"
19490
19491         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
19492                 error "rename dir under striped dir fails"
19493
19494         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
19495                 error "rename dir under different stripes fails"
19496
19497         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
19498                 error "rename file under striped dir should succeed"
19499
19500         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
19501                 error "rename dir under striped dir should succeed"
19502
19503         rm -rf $DIR/$tdir
19504 }
19505 run_test 300e "check rename under striped directory"
19506
19507 test_300f() {
19508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19509         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19510         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19511                 skip "Need MDS version at least 2.7.55"
19512
19513         local stripe_count
19514         local file
19515
19516         rm -rf $DIR/$tdir
19517         mkdir -p $DIR/$tdir
19518
19519         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19520                 error "set striped dir error"
19521
19522         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
19523                 error "set striped dir error"
19524
19525         touch $DIR/$tdir/striped_dir/a
19526         mkdir $DIR/$tdir/striped_dir/dir_a
19527         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
19528                 error "create striped dir under striped dir fails"
19529
19530         touch $DIR/$tdir/striped_dir1/b
19531         mkdir $DIR/$tdir/striped_dir1/dir_b
19532         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
19533                 error "create striped dir under striped dir fails"
19534
19535         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
19536                 error "rename dir under different striped dir should fail"
19537
19538         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
19539                 error "rename striped dir under diff striped dir should fail"
19540
19541         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
19542                 error "rename file under diff striped dirs fails"
19543
19544         rm -rf $DIR/$tdir
19545 }
19546 run_test 300f "check rename cross striped directory"
19547
19548 test_300_check_default_striped_dir()
19549 {
19550         local dirname=$1
19551         local default_count=$2
19552         local default_index=$3
19553         local stripe_count
19554         local stripe_index
19555         local dir_stripe_index
19556         local dir
19557
19558         echo "checking $dirname $default_count $default_index"
19559         $LFS setdirstripe -D -c $default_count -i $default_index \
19560                                 -t all_char $DIR/$tdir/$dirname ||
19561                 error "set default stripe on striped dir error"
19562         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
19563         [ $stripe_count -eq $default_count ] ||
19564                 error "expect $default_count get $stripe_count for $dirname"
19565
19566         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
19567         [ $stripe_index -eq $default_index ] ||
19568                 error "expect $default_index get $stripe_index for $dirname"
19569
19570         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
19571                                                 error "create dirs failed"
19572
19573         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
19574         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
19575         for dir in $(find $DIR/$tdir/$dirname/*); do
19576                 stripe_count=$($LFS getdirstripe -c $dir)
19577                 [ $stripe_count -eq $default_count ] ||
19578                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
19579                 error "stripe count $default_count != $stripe_count for $dir"
19580
19581                 stripe_index=$($LFS getdirstripe -i $dir)
19582                 [ $default_index -eq -1 ] ||
19583                         [ $stripe_index -eq $default_index ] ||
19584                         error "$stripe_index != $default_index for $dir"
19585
19586                 #check default stripe
19587                 stripe_count=$($LFS getdirstripe -D -c $dir)
19588                 [ $stripe_count -eq $default_count ] ||
19589                 error "default count $default_count != $stripe_count for $dir"
19590
19591                 stripe_index=$($LFS getdirstripe -D -i $dir)
19592                 [ $stripe_index -eq $default_index ] ||
19593                 error "default index $default_index != $stripe_index for $dir"
19594         done
19595         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
19596 }
19597
19598 test_300g() {
19599         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19600         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19601                 skip "Need MDS version at least 2.7.55"
19602
19603         local dir
19604         local stripe_count
19605         local stripe_index
19606
19607         mkdir $DIR/$tdir
19608         mkdir $DIR/$tdir/normal_dir
19609
19610         #Checking when client cache stripe index
19611         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
19612         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
19613                 error "create striped_dir failed"
19614
19615         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
19616                 error "create dir0 fails"
19617         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
19618         [ $stripe_index -eq 0 ] ||
19619                 error "dir0 expect index 0 got $stripe_index"
19620
19621         mkdir $DIR/$tdir/striped_dir/dir1 ||
19622                 error "create dir1 fails"
19623         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
19624         [ $stripe_index -eq 1 ] ||
19625                 error "dir1 expect index 1 got $stripe_index"
19626
19627         #check default stripe count/stripe index
19628         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
19629         test_300_check_default_striped_dir normal_dir 1 0
19630         test_300_check_default_striped_dir normal_dir 2 1
19631         test_300_check_default_striped_dir normal_dir 2 -1
19632
19633         #delete default stripe information
19634         echo "delete default stripeEA"
19635         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
19636                 error "set default stripe on striped dir error"
19637
19638         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
19639         for dir in $(find $DIR/$tdir/normal_dir/*); do
19640                 stripe_count=$($LFS getdirstripe -c $dir)
19641                 [ $stripe_count -eq 0 ] ||
19642                         error "expect 1 get $stripe_count for $dir"
19643                 stripe_index=$($LFS getdirstripe -i $dir)
19644                 [ $stripe_index -eq 0 ] ||
19645                         error "expect 0 get $stripe_index for $dir"
19646         done
19647 }
19648 run_test 300g "check default striped directory for normal directory"
19649
19650 test_300h() {
19651         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19652         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19653                 skip "Need MDS version at least 2.7.55"
19654
19655         local dir
19656         local stripe_count
19657
19658         mkdir $DIR/$tdir
19659         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19660                 error "set striped dir error"
19661
19662         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
19663         test_300_check_default_striped_dir striped_dir 1 0
19664         test_300_check_default_striped_dir striped_dir 2 1
19665         test_300_check_default_striped_dir striped_dir 2 -1
19666
19667         #delete default stripe information
19668         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
19669                 error "set default stripe on striped dir error"
19670
19671         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
19672         for dir in $(find $DIR/$tdir/striped_dir/*); do
19673                 stripe_count=$($LFS getdirstripe -c $dir)
19674                 [ $stripe_count -eq 0 ] ||
19675                         error "expect 1 get $stripe_count for $dir"
19676         done
19677 }
19678 run_test 300h "check default striped directory for striped directory"
19679
19680 test_300i() {
19681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19682         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19683         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19684                 skip "Need MDS version at least 2.7.55"
19685
19686         local stripe_count
19687         local file
19688
19689         mkdir $DIR/$tdir
19690
19691         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19692                 error "set striped dir error"
19693
19694         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
19695                 error "create files under striped dir failed"
19696
19697         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
19698                 error "set striped hashdir error"
19699
19700         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
19701                 error "create dir0 under hash dir failed"
19702         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
19703                 error "create dir1 under hash dir failed"
19704
19705         # unfortunately, we need to umount to clear dir layout cache for now
19706         # once we fully implement dir layout, we can drop this
19707         umount_client $MOUNT || error "umount failed"
19708         mount_client $MOUNT || error "mount failed"
19709
19710         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
19711         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
19712         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
19713
19714         #set the stripe to be unknown hash type
19715         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
19716         $LCTL set_param fail_loc=0x1901
19717         for ((i = 0; i < 10; i++)); do
19718                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
19719                         error "stat f-$i failed"
19720                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
19721         done
19722
19723         touch $DIR/$tdir/striped_dir/f0 &&
19724                 error "create under striped dir with unknown hash should fail"
19725
19726         $LCTL set_param fail_loc=0
19727
19728         umount_client $MOUNT || error "umount failed"
19729         mount_client $MOUNT || error "mount failed"
19730
19731         return 0
19732 }
19733 run_test 300i "client handle unknown hash type striped directory"
19734
19735 test_300j() {
19736         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19738         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19739                 skip "Need MDS version at least 2.7.55"
19740
19741         local stripe_count
19742         local file
19743
19744         mkdir $DIR/$tdir
19745
19746         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
19747         $LCTL set_param fail_loc=0x1702
19748         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19749                 error "set striped dir error"
19750
19751         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
19752                 error "create files under striped dir failed"
19753
19754         $LCTL set_param fail_loc=0
19755
19756         rm -rf $DIR/$tdir || error "unlink striped dir fails"
19757
19758         return 0
19759 }
19760 run_test 300j "test large update record"
19761
19762 test_300k() {
19763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19764         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19765         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19766                 skip "Need MDS version at least 2.7.55"
19767
19768         # this test needs a huge transaction
19769         local kb
19770         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19771              osd*.$FSNAME-MDT0000.kbytestotal")
19772         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
19773
19774         local stripe_count
19775         local file
19776
19777         mkdir $DIR/$tdir
19778
19779         #define OBD_FAIL_LARGE_STRIPE   0x1703
19780         $LCTL set_param fail_loc=0x1703
19781         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
19782                 error "set striped dir error"
19783         $LCTL set_param fail_loc=0
19784
19785         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19786                 error "getstripeddir fails"
19787         rm -rf $DIR/$tdir/striped_dir ||
19788                 error "unlink striped dir fails"
19789
19790         return 0
19791 }
19792 run_test 300k "test large striped directory"
19793
19794 test_300l() {
19795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19796         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19797         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19798                 skip "Need MDS version at least 2.7.55"
19799
19800         local stripe_index
19801
19802         test_mkdir -p $DIR/$tdir/striped_dir
19803         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
19804                         error "chown $RUNAS_ID failed"
19805         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
19806                 error "set default striped dir failed"
19807
19808         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
19809         $LCTL set_param fail_loc=0x80000158
19810         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
19811
19812         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
19813         [ $stripe_index -eq 1 ] ||
19814                 error "expect 1 get $stripe_index for $dir"
19815 }
19816 run_test 300l "non-root user to create dir under striped dir with stale layout"
19817
19818 test_300m() {
19819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19820         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
19821         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19822                 skip "Need MDS version at least 2.7.55"
19823
19824         mkdir -p $DIR/$tdir/striped_dir
19825         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
19826                 error "set default stripes dir error"
19827
19828         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
19829
19830         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
19831         [ $stripe_count -eq 0 ] ||
19832                         error "expect 0 get $stripe_count for a"
19833
19834         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
19835                 error "set default stripes dir error"
19836
19837         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
19838
19839         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
19840         [ $stripe_count -eq 0 ] ||
19841                         error "expect 0 get $stripe_count for b"
19842
19843         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
19844                 error "set default stripes dir error"
19845
19846         mkdir $DIR/$tdir/striped_dir/c &&
19847                 error "default stripe_index is invalid, mkdir c should fails"
19848
19849         rm -rf $DIR/$tdir || error "rmdir fails"
19850 }
19851 run_test 300m "setstriped directory on single MDT FS"
19852
19853 cleanup_300n() {
19854         local list=$(comma_list $(mdts_nodes))
19855
19856         trap 0
19857         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19858 }
19859
19860 test_300n() {
19861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19862         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19863         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19864                 skip "Need MDS version at least 2.7.55"
19865         remote_mds_nodsh && skip "remote MDS with nodsh"
19866
19867         local stripe_index
19868         local list=$(comma_list $(mdts_nodes))
19869
19870         trap cleanup_300n RETURN EXIT
19871         mkdir -p $DIR/$tdir
19872         chmod 777 $DIR/$tdir
19873         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
19874                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19875                 error "create striped dir succeeds with gid=0"
19876
19877         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19878         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
19879                 error "create striped dir fails with gid=-1"
19880
19881         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19882         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
19883                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19884                 error "set default striped dir succeeds with gid=0"
19885
19886
19887         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19888         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
19889                 error "set default striped dir fails with gid=-1"
19890
19891
19892         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19893         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
19894                                         error "create test_dir fails"
19895         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
19896                                         error "create test_dir1 fails"
19897         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
19898                                         error "create test_dir2 fails"
19899         cleanup_300n
19900 }
19901 run_test 300n "non-root user to create dir under striped dir with default EA"
19902
19903 test_300o() {
19904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19905         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19906         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19907                 skip "Need MDS version at least 2.7.55"
19908
19909         local numfree1
19910         local numfree2
19911
19912         mkdir -p $DIR/$tdir
19913
19914         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
19915         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
19916         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
19917                 skip "not enough free inodes $numfree1 $numfree2"
19918         fi
19919
19920         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
19921         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
19922         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
19923                 skip "not enough free space $numfree1 $numfree2"
19924         fi
19925
19926         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
19927                 error "setdirstripe fails"
19928
19929         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
19930                 error "create dirs fails"
19931
19932         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
19933         ls $DIR/$tdir/striped_dir > /dev/null ||
19934                 error "ls striped dir fails"
19935         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
19936                 error "unlink big striped dir fails"
19937 }
19938 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
19939
19940 test_300p() {
19941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19942         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19943         remote_mds_nodsh && skip "remote MDS with nodsh"
19944
19945         mkdir -p $DIR/$tdir
19946
19947         #define OBD_FAIL_OUT_ENOSPC     0x1704
19948         do_facet mds2 lctl set_param fail_loc=0x80001704
19949         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
19950                  && error "create striped directory should fail"
19951
19952         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
19953
19954         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
19955         true
19956 }
19957 run_test 300p "create striped directory without space"
19958
19959 test_300q() {
19960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19961         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19962
19963         local fd=$(free_fd)
19964         local cmd="exec $fd<$tdir"
19965         cd $DIR
19966         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
19967         eval $cmd
19968         cmd="exec $fd<&-"
19969         trap "eval $cmd" EXIT
19970         cd $tdir || error "cd $tdir fails"
19971         rmdir  ../$tdir || error "rmdir $tdir fails"
19972         mkdir local_dir && error "create dir succeeds"
19973         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
19974         eval $cmd
19975         return 0
19976 }
19977 run_test 300q "create remote directory under orphan directory"
19978
19979 test_300r() {
19980         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
19981                 skip "Need MDS version at least 2.7.55" && return
19982         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19983
19984         mkdir $DIR/$tdir
19985
19986         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
19987                 error "set striped dir error"
19988
19989         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19990                 error "getstripeddir fails"
19991
19992         local stripe_count
19993         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19994                       awk '/lmv_stripe_count:/ { print $2 }')
19995
19996         [ $MDSCOUNT -ne $stripe_count ] &&
19997                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
19998
19999         rm -rf $DIR/$tdir/striped_dir ||
20000                 error "unlink striped dir fails"
20001 }
20002 run_test 300r "test -1 striped directory"
20003
20004 prepare_remote_file() {
20005         mkdir $DIR/$tdir/src_dir ||
20006                 error "create remote source failed"
20007
20008         cp /etc/hosts $DIR/$tdir/src_dir/a ||
20009                  error "cp to remote source failed"
20010         touch $DIR/$tdir/src_dir/a
20011
20012         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
20013                 error "create remote target dir failed"
20014
20015         touch $DIR/$tdir/tgt_dir/b
20016
20017         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
20018                 error "rename dir cross MDT failed!"
20019
20020         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
20021                 error "src_child still exists after rename"
20022
20023         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
20024                 error "missing file(a) after rename"
20025
20026         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
20027                 error "diff after rename"
20028 }
20029
20030 test_310a() {
20031         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
20032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20033
20034         local remote_file=$DIR/$tdir/tgt_dir/b
20035
20036         mkdir -p $DIR/$tdir
20037
20038         prepare_remote_file || error "prepare remote file failed"
20039
20040         #open-unlink file
20041         $OPENUNLINK $remote_file $remote_file ||
20042                 error "openunlink $remote_file failed"
20043         $CHECKSTAT -a $remote_file || error "$remote_file exists"
20044 }
20045 run_test 310a "open unlink remote file"
20046
20047 test_310b() {
20048         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
20049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20050
20051         local remote_file=$DIR/$tdir/tgt_dir/b
20052
20053         mkdir -p $DIR/$tdir
20054
20055         prepare_remote_file || error "prepare remote file failed"
20056
20057         ln $remote_file $DIR/$tfile || error "link failed for remote file"
20058         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
20059         $CHECKSTAT -t file $remote_file || error "check file failed"
20060 }
20061 run_test 310b "unlink remote file with multiple links while open"
20062
20063 test_310c() {
20064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20065         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
20066
20067         local remote_file=$DIR/$tdir/tgt_dir/b
20068
20069         mkdir -p $DIR/$tdir
20070
20071         prepare_remote_file || error "prepare remote file failed"
20072
20073         ln $remote_file $DIR/$tfile || error "link failed for remote file"
20074         multiop_bg_pause $remote_file O_uc ||
20075                         error "mulitop failed for remote file"
20076         MULTIPID=$!
20077         $MULTIOP $DIR/$tfile Ouc
20078         kill -USR1 $MULTIPID
20079         wait $MULTIPID
20080 }
20081 run_test 310c "open-unlink remote file with multiple links"
20082
20083 #LU-4825
20084 test_311() {
20085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20086         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
20087         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
20088                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
20089         remote_mds_nodsh && skip "remote MDS with nodsh"
20090
20091         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
20092         local mdts=$(comma_list $(mdts_nodes))
20093
20094         mkdir -p $DIR/$tdir
20095         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20096         createmany -o $DIR/$tdir/$tfile. 1000
20097
20098         # statfs data is not real time, let's just calculate it
20099         old_iused=$((old_iused + 1000))
20100
20101         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20102                         osp.*OST0000*MDT0000.create_count")
20103         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20104                                 osp.*OST0000*MDT0000.max_create_count")
20105         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
20106
20107         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
20108         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
20109         [ $index -ne 0 ] || error "$tfile stripe index is 0"
20110
20111         unlinkmany $DIR/$tdir/$tfile. 1000
20112
20113         do_nodes $mdts "$LCTL set_param -n \
20114                         osp.*OST0000*.max_create_count=$max_count"
20115         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
20116                 do_nodes $mdts "$LCTL set_param -n \
20117                                 osp.*OST0000*.create_count=$count"
20118         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
20119                         grep "=0" && error "create_count is zero"
20120
20121         local new_iused
20122         for i in $(seq 120); do
20123                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
20124                 # system may be too busy to destroy all objs in time, use
20125                 # a somewhat small value to not fail autotest
20126                 [ $((old_iused - new_iused)) -gt 400 ] && break
20127                 sleep 1
20128         done
20129
20130         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
20131         [ $((old_iused - new_iused)) -gt 400 ] ||
20132                 error "objs not destroyed after unlink"
20133 }
20134 run_test 311 "disable OSP precreate, and unlink should destroy objs"
20135
20136 zfs_oid_to_objid()
20137 {
20138         local ost=$1
20139         local objid=$2
20140
20141         local vdevdir=$(dirname $(facet_vdevice $ost))
20142         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
20143         local zfs_zapid=$(do_facet $ost $cmd |
20144                           grep -w "/O/0/d$((objid%32))" -C 5 |
20145                           awk '/Object/{getline; print $1}')
20146         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
20147                           awk "/$objid = /"'{printf $3}')
20148
20149         echo $zfs_objid
20150 }
20151
20152 zfs_object_blksz() {
20153         local ost=$1
20154         local objid=$2
20155
20156         local vdevdir=$(dirname $(facet_vdevice $ost))
20157         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
20158         local blksz=$(do_facet $ost $cmd $objid |
20159                       awk '/dblk/{getline; printf $4}')
20160
20161         case "${blksz: -1}" in
20162                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
20163                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
20164                 *) ;;
20165         esac
20166
20167         echo $blksz
20168 }
20169
20170 test_312() { # LU-4856
20171         remote_ost_nodsh && skip "remote OST with nodsh"
20172         [ "$ost1_FSTYPE" = "zfs" ] ||
20173                 skip_env "the test only applies to zfs"
20174
20175         local max_blksz=$(do_facet ost1 \
20176                           $ZFS get -p recordsize $(facet_device ost1) |
20177                           awk '!/VALUE/{print $3}')
20178
20179         # to make life a little bit easier
20180         $LFS mkdir -c 1 -i 0 $DIR/$tdir
20181         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20182
20183         local tf=$DIR/$tdir/$tfile
20184         touch $tf
20185         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20186
20187         # Get ZFS object id
20188         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20189         # block size change by sequential overwrite
20190         local bs
20191
20192         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
20193                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
20194
20195                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
20196                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
20197         done
20198         rm -f $tf
20199
20200         # block size change by sequential append write
20201         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
20202         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20203         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20204         local count
20205
20206         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
20207                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
20208                         oflag=sync conv=notrunc
20209
20210                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
20211                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
20212                         error "blksz error, actual $blksz, " \
20213                                 "expected: 2 * $count * $PAGE_SIZE"
20214         done
20215         rm -f $tf
20216
20217         # random write
20218         touch $tf
20219         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20220         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20221
20222         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
20223         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20224         [ $blksz -eq $PAGE_SIZE ] ||
20225                 error "blksz error: $blksz, expected: $PAGE_SIZE"
20226
20227         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
20228         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20229         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
20230
20231         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
20232         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20233         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
20234 }
20235 run_test 312 "make sure ZFS adjusts its block size by write pattern"
20236
20237 test_313() {
20238         remote_ost_nodsh && skip "remote OST with nodsh"
20239
20240         local file=$DIR/$tfile
20241
20242         rm -f $file
20243         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
20244
20245         # define OBD_FAIL_TGT_RCVD_EIO           0x720
20246         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20247         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
20248                 error "write should failed"
20249         do_facet ost1 "$LCTL set_param fail_loc=0"
20250         rm -f $file
20251 }
20252 run_test 313 "io should fail after last_rcvd update fail"
20253
20254 test_314() {
20255         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
20256
20257         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
20258         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20259         rm -f $DIR/$tfile
20260         wait_delete_completed
20261         do_facet ost1 "$LCTL set_param fail_loc=0"
20262 }
20263 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
20264
20265 test_315() { # LU-618
20266         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
20267
20268         local file=$DIR/$tfile
20269         rm -f $file
20270
20271         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
20272                 error "multiop file write failed"
20273         $MULTIOP $file oO_RDONLY:r4063232_c &
20274         PID=$!
20275
20276         sleep 2
20277
20278         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
20279         kill -USR1 $PID
20280
20281         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
20282         rm -f $file
20283 }
20284 run_test 315 "read should be accounted"
20285
20286 test_316() {
20287         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20288         large_xattr_enabled || skip_env "ea_inode feature disabled"
20289
20290         rm -rf $DIR/$tdir/d
20291         mkdir -p $DIR/$tdir/d
20292         chown nobody $DIR/$tdir/d
20293         touch $DIR/$tdir/d/file
20294
20295         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
20296 }
20297 run_test 316 "lfs mv"
20298
20299 test_317() {
20300         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
20301                 skip "Need MDS version at least 2.11.53"
20302         if [ "$ost1_FSTYPE" == "zfs" ]; then
20303                 skip "LU-10370: no implementation for ZFS"
20304         fi
20305
20306         local trunc_sz
20307         local grant_blk_size
20308
20309         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
20310                         awk '/grant_block_size:/ { print $2; exit; }')
20311         #
20312         # Create File of size 5M. Truncate it to below size's and verify
20313         # blocks count.
20314         #
20315         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
20316                 error "Create file $DIR/$tfile failed"
20317         stack_trap "rm -f $DIR/$tfile" EXIT
20318
20319         for trunc_sz in 2097152 4097 4000 509 0; do
20320                 $TRUNCATE $DIR/$tfile $trunc_sz ||
20321                         error "truncate $tfile to $trunc_sz failed"
20322                 local sz=$(stat --format=%s $DIR/$tfile)
20323                 local blk=$(stat --format=%b $DIR/$tfile)
20324                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
20325                                      grant_blk_size) * 8))
20326
20327                 if [[ $blk -ne $trunc_blk ]]; then
20328                         $(which stat) $DIR/$tfile
20329                         error "Expected Block $trunc_blk got $blk for $tfile"
20330                 fi
20331
20332                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20333                         error "Expected Size $trunc_sz got $sz for $tfile"
20334         done
20335
20336         #
20337         # sparse file test
20338         # Create file with a hole and write actual two blocks. Block count
20339         # must be 16.
20340         #
20341         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
20342                 conv=fsync || error "Create file : $DIR/$tfile"
20343
20344         # Calculate the final truncate size.
20345         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
20346
20347         #
20348         # truncate to size $trunc_sz bytes. Strip the last block
20349         # The block count must drop to 8
20350         #
20351         $TRUNCATE $DIR/$tfile $trunc_sz ||
20352                 error "truncate $tfile to $trunc_sz failed"
20353
20354         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
20355         sz=$(stat --format=%s $DIR/$tfile)
20356         blk=$(stat --format=%b $DIR/$tfile)
20357
20358         if [[ $blk -ne $trunc_bsz ]]; then
20359                 $(which stat) $DIR/$tfile
20360                 error "Expected Block $trunc_bsz got $blk for $tfile"
20361         fi
20362
20363         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20364                 error "Expected Size $trunc_sz got $sz for $tfile"
20365 }
20366 run_test 317 "Verify blocks get correctly update after truncate"
20367
20368 test_318() {
20369         local old_max_active=$($LCTL get_param -n \
20370                             llite.*.max_read_ahead_async_active 2>/dev/null)
20371
20372         $LCTL set_param llite.*.max_read_ahead_async_active=256
20373         local max_active=$($LCTL get_param -n \
20374                            llite.*.max_read_ahead_async_active 2>/dev/null)
20375         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
20376
20377         # currently reset to 0 is unsupported, leave it 512 for now.
20378         $LCTL set_param llite.*.max_read_ahead_async_active=0 &&
20379                 error "set max_read_ahead_async_active should fail"
20380
20381         $LCTL set_param llite.*.max_read_ahead_async_active=512
20382         max_active=$($LCTL get_param -n \
20383                      llite.*.max_read_ahead_async_active 2>/dev/null)
20384         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
20385
20386         # restore @max_active
20387         [ $old_max_active -ne 0 ] && $LCTL set_param \
20388                 llite.*.max_read_ahead_async_active=$old_max_active
20389
20390         local old_threshold=$($LCTL get_param -n \
20391                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20392         local max_per_file_mb=$($LCTL get_param -n \
20393                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
20394
20395         local invalid=$(($max_per_file_mb + 1))
20396         $LCTL set_param \
20397                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
20398                         && error "set $invalid should fail"
20399
20400         local valid=$(($invalid - 1))
20401         $LCTL set_param \
20402                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
20403                         error "set $valid should succeed"
20404         local threshold=$($LCTL get_param -n \
20405                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20406         [ $threshold -eq $valid ] || error \
20407                 "expect threshold $valid got $threshold"
20408         $LCTL set_param \
20409                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
20410 }
20411 run_test 318 "Verify async readahead tunables"
20412
20413 test_319() {
20414         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
20415
20416         local before=$(date +%s)
20417         local evict
20418         local mdir=$DIR/$tdir
20419         local file=$mdir/xxx
20420
20421         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
20422         touch $file
20423
20424 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
20425         $LCTL set_param fail_val=5 fail_loc=0x8000032c
20426         $LFS mv -m1 $file &
20427
20428         sleep 1
20429         dd if=$file of=/dev/null
20430         wait
20431         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
20432           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
20433
20434         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
20435 }
20436 run_test 319 "lost lease lock on migrate error"
20437
20438 test_fake_rw() {
20439         local read_write=$1
20440         if [ "$read_write" = "write" ]; then
20441                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
20442         elif [ "$read_write" = "read" ]; then
20443                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
20444         else
20445                 error "argument error"
20446         fi
20447
20448         # turn off debug for performance testing
20449         local saved_debug=$($LCTL get_param -n debug)
20450         $LCTL set_param debug=0
20451
20452         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20453
20454         # get ost1 size - $FSNAME-OST0000
20455         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
20456         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
20457         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
20458
20459         if [ "$read_write" = "read" ]; then
20460                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
20461         fi
20462
20463         local start_time=$(date +%s.%N)
20464         $dd_cmd bs=1M count=$blocks oflag=sync ||
20465                 error "real dd $read_write error"
20466         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
20467
20468         if [ "$read_write" = "write" ]; then
20469                 rm -f $DIR/$tfile
20470         fi
20471
20472         # define OBD_FAIL_OST_FAKE_RW           0x238
20473         do_facet ost1 $LCTL set_param fail_loc=0x238
20474
20475         local start_time=$(date +%s.%N)
20476         $dd_cmd bs=1M count=$blocks oflag=sync ||
20477                 error "fake dd $read_write error"
20478         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
20479
20480         if [ "$read_write" = "write" ]; then
20481                 # verify file size
20482                 cancel_lru_locks osc
20483                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
20484                         error "$tfile size not $blocks MB"
20485         fi
20486         do_facet ost1 $LCTL set_param fail_loc=0
20487
20488         echo "fake $read_write $duration_fake vs. normal $read_write" \
20489                 "$duration in seconds"
20490         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
20491                 error_not_in_vm "fake write is slower"
20492
20493         $LCTL set_param -n debug="$saved_debug"
20494         rm -f $DIR/$tfile
20495 }
20496 test_399a() { # LU-7655 for OST fake write
20497         remote_ost_nodsh && skip "remote OST with nodsh"
20498
20499         test_fake_rw write
20500 }
20501 run_test 399a "fake write should not be slower than normal write"
20502
20503 test_399b() { # LU-8726 for OST fake read
20504         remote_ost_nodsh && skip "remote OST with nodsh"
20505         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
20506                 skip_env "ldiskfs only test"
20507         fi
20508
20509         test_fake_rw read
20510 }
20511 run_test 399b "fake read should not be slower than normal read"
20512
20513 test_400a() { # LU-1606, was conf-sanity test_74
20514         if ! which $CC > /dev/null 2>&1; then
20515                 skip_env "$CC is not installed"
20516         fi
20517
20518         local extra_flags=''
20519         local out=$TMP/$tfile
20520         local prefix=/usr/include/lustre
20521         local prog
20522
20523         if ! [[ -d $prefix ]]; then
20524                 # Assume we're running in tree and fixup the include path.
20525                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
20526                 extra_flags+=" -L$LUSTRE/utils/.lib"
20527         fi
20528
20529         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
20530                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
20531                         error "client api broken"
20532         done
20533         rm -f $out
20534 }
20535 run_test 400a "Lustre client api program can compile and link"
20536
20537 test_400b() { # LU-1606, LU-5011
20538         local header
20539         local out=$TMP/$tfile
20540         local prefix=/usr/include/linux/lustre
20541
20542         # We use a hard coded prefix so that this test will not fail
20543         # when run in tree. There are headers in lustre/include/lustre/
20544         # that are not packaged (like lustre_idl.h) and have more
20545         # complicated include dependencies (like config.h and lnet/types.h).
20546         # Since this test about correct packaging we just skip them when
20547         # they don't exist (see below) rather than try to fixup cppflags.
20548
20549         if ! which $CC > /dev/null 2>&1; then
20550                 skip_env "$CC is not installed"
20551         fi
20552
20553         for header in $prefix/*.h; do
20554                 if ! [[ -f "$header" ]]; then
20555                         continue
20556                 fi
20557
20558                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
20559                         continue # lustre_ioctl.h is internal header
20560                 fi
20561
20562                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
20563                         error "cannot compile '$header'"
20564         done
20565         rm -f $out
20566 }
20567 run_test 400b "packaged headers can be compiled"
20568
20569 test_401a() { #LU-7437
20570         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
20571         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
20572
20573         #count the number of parameters by "list_param -R"
20574         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
20575         #count the number of parameters by listing proc files
20576         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
20577         echo "proc_dirs='$proc_dirs'"
20578         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
20579         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
20580                       sort -u | wc -l)
20581
20582         [ $params -eq $procs ] ||
20583                 error "found $params parameters vs. $procs proc files"
20584
20585         # test the list_param -D option only returns directories
20586         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
20587         #count the number of parameters by listing proc directories
20588         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
20589                 sort -u | wc -l)
20590
20591         [ $params -eq $procs ] ||
20592                 error "found $params parameters vs. $procs proc files"
20593 }
20594 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
20595
20596 test_401b() {
20597         local save=$($LCTL get_param -n jobid_var)
20598         local tmp=testing
20599
20600         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
20601                 error "no error returned when setting bad parameters"
20602
20603         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
20604         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
20605
20606         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
20607         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
20608         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
20609 }
20610 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
20611
20612 test_401c() {
20613         local jobid_var_old=$($LCTL get_param -n jobid_var)
20614         local jobid_var_new
20615
20616         $LCTL set_param jobid_var= &&
20617                 error "no error returned for 'set_param a='"
20618
20619         jobid_var_new=$($LCTL get_param -n jobid_var)
20620         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
20621                 error "jobid_var was changed by setting without value"
20622
20623         $LCTL set_param jobid_var &&
20624                 error "no error returned for 'set_param a'"
20625
20626         jobid_var_new=$($LCTL get_param -n jobid_var)
20627         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
20628                 error "jobid_var was changed by setting without value"
20629 }
20630 run_test 401c "Verify 'lctl set_param' without value fails in either format."
20631
20632 test_401d() {
20633         local jobid_var_old=$($LCTL get_param -n jobid_var)
20634         local jobid_var_new
20635         local new_value="foo=bar"
20636
20637         $LCTL set_param jobid_var=$new_value ||
20638                 error "'set_param a=b' did not accept a value containing '='"
20639
20640         jobid_var_new=$($LCTL get_param -n jobid_var)
20641         [[ "$jobid_var_new" == "$new_value" ]] ||
20642                 error "'set_param a=b' failed on a value containing '='"
20643
20644         # Reset the jobid_var to test the other format
20645         $LCTL set_param jobid_var=$jobid_var_old
20646         jobid_var_new=$($LCTL get_param -n jobid_var)
20647         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
20648                 error "failed to reset jobid_var"
20649
20650         $LCTL set_param jobid_var $new_value ||
20651                 error "'set_param a b' did not accept a value containing '='"
20652
20653         jobid_var_new=$($LCTL get_param -n jobid_var)
20654         [[ "$jobid_var_new" == "$new_value" ]] ||
20655                 error "'set_param a b' failed on a value containing '='"
20656
20657         $LCTL set_param jobid_var $jobid_var_old
20658         jobid_var_new=$($LCTL get_param -n jobid_var)
20659         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
20660                 error "failed to reset jobid_var"
20661 }
20662 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
20663
20664 test_402() {
20665         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
20666         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
20667                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
20668         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
20669                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
20670                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
20671         remote_mds_nodsh && skip "remote MDS with nodsh"
20672
20673         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
20674 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
20675         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
20676         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
20677                 echo "Touch failed - OK"
20678 }
20679 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
20680
20681 test_403() {
20682         local file1=$DIR/$tfile.1
20683         local file2=$DIR/$tfile.2
20684         local tfile=$TMP/$tfile
20685
20686         rm -f $file1 $file2 $tfile
20687
20688         touch $file1
20689         ln $file1 $file2
20690
20691         # 30 sec OBD_TIMEOUT in ll_getattr()
20692         # right before populating st_nlink
20693         $LCTL set_param fail_loc=0x80001409
20694         stat -c %h $file1 > $tfile &
20695
20696         # create an alias, drop all locks and reclaim the dentry
20697         < $file2
20698         cancel_lru_locks mdc
20699         cancel_lru_locks osc
20700         sysctl -w vm.drop_caches=2
20701
20702         wait
20703
20704         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
20705
20706         rm -f $tfile $file1 $file2
20707 }
20708 run_test 403 "i_nlink should not drop to zero due to aliasing"
20709
20710 test_404() { # LU-6601
20711         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
20712                 skip "Need server version newer than 2.8.52"
20713         remote_mds_nodsh && skip "remote MDS with nodsh"
20714
20715         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
20716                 awk '/osp .*-osc-MDT/ { print $4}')
20717
20718         local osp
20719         for osp in $mosps; do
20720                 echo "Deactivate: " $osp
20721                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
20722                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
20723                         awk -vp=$osp '$4 == p { print $2 }')
20724                 [ $stat = IN ] || {
20725                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
20726                         error "deactivate error"
20727                 }
20728                 echo "Activate: " $osp
20729                 do_facet $SINGLEMDS $LCTL --device %$osp activate
20730                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
20731                         awk -vp=$osp '$4 == p { print $2 }')
20732                 [ $stat = UP ] || {
20733                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
20734                         error "activate error"
20735                 }
20736         done
20737 }
20738 run_test 404 "validate manual {de}activated works properly for OSPs"
20739
20740 test_405() {
20741         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20742         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
20743                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
20744                         skip "Layout swap lock is not supported"
20745
20746         check_swap_layouts_support
20747
20748         test_mkdir $DIR/$tdir
20749         swap_lock_test -d $DIR/$tdir ||
20750                 error "One layout swap locked test failed"
20751 }
20752 run_test 405 "Various layout swap lock tests"
20753
20754 test_406() {
20755         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20756         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20757         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20759         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
20760                 skip "Need MDS version at least 2.8.50"
20761
20762         local def_stripe_size=$($LFS getstripe -S $MOUNT)
20763         local test_pool=$TESTNAME
20764
20765         pool_add $test_pool || error "pool_add failed"
20766         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
20767                 error "pool_add_targets failed"
20768
20769         save_layout_restore_at_exit $MOUNT
20770
20771         # parent set default stripe count only, child will stripe from both
20772         # parent and fs default
20773         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
20774                 error "setstripe $MOUNT failed"
20775         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
20776         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
20777         for i in $(seq 10); do
20778                 local f=$DIR/$tdir/$tfile.$i
20779                 touch $f || error "touch failed"
20780                 local count=$($LFS getstripe -c $f)
20781                 [ $count -eq $OSTCOUNT ] ||
20782                         error "$f stripe count $count != $OSTCOUNT"
20783                 local offset=$($LFS getstripe -i $f)
20784                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
20785                 local size=$($LFS getstripe -S $f)
20786                 [ $size -eq $((def_stripe_size * 2)) ] ||
20787                         error "$f stripe size $size != $((def_stripe_size * 2))"
20788                 local pool=$($LFS getstripe -p $f)
20789                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
20790         done
20791
20792         # change fs default striping, delete parent default striping, now child
20793         # will stripe from new fs default striping only
20794         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
20795                 error "change $MOUNT default stripe failed"
20796         $LFS setstripe -c 0 $DIR/$tdir ||
20797                 error "delete $tdir default stripe failed"
20798         for i in $(seq 11 20); do
20799                 local f=$DIR/$tdir/$tfile.$i
20800                 touch $f || error "touch $f failed"
20801                 local count=$($LFS getstripe -c $f)
20802                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
20803                 local offset=$($LFS getstripe -i $f)
20804                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
20805                 local size=$($LFS getstripe -S $f)
20806                 [ $size -eq $def_stripe_size ] ||
20807                         error "$f stripe size $size != $def_stripe_size"
20808                 local pool=$($LFS getstripe -p $f)
20809                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
20810         done
20811
20812         unlinkmany $DIR/$tdir/$tfile. 1 20
20813
20814         local f=$DIR/$tdir/$tfile
20815         pool_remove_all_targets $test_pool $f
20816         pool_remove $test_pool $f
20817 }
20818 run_test 406 "DNE support fs default striping"
20819
20820 test_407() {
20821         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20822         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20823                 skip "Need MDS version at least 2.8.55"
20824         remote_mds_nodsh && skip "remote MDS with nodsh"
20825
20826         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
20827                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
20828         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
20829                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
20830         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
20831
20832         #define OBD_FAIL_DT_TXN_STOP    0x2019
20833         for idx in $(seq $MDSCOUNT); do
20834                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
20835         done
20836         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
20837         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
20838                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
20839         true
20840 }
20841 run_test 407 "transaction fail should cause operation fail"
20842
20843 test_408() {
20844         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20845
20846         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
20847         lctl set_param fail_loc=0x8000040a
20848         # let ll_prepare_partial_page() fail
20849         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
20850
20851         rm -f $DIR/$tfile
20852
20853         # create at least 100 unused inodes so that
20854         # shrink_icache_memory(0) should not return 0
20855         touch $DIR/$tfile-{0..100}
20856         rm -f $DIR/$tfile-{0..100}
20857         sync
20858
20859         echo 2 > /proc/sys/vm/drop_caches
20860 }
20861 run_test 408 "drop_caches should not hang due to page leaks"
20862
20863 test_409()
20864 {
20865         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20866
20867         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
20868         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
20869         touch $DIR/$tdir/guard || error "(2) Fail to create"
20870
20871         local PREFIX=$(str_repeat 'A' 128)
20872         echo "Create 1K hard links start at $(date)"
20873         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20874                 error "(3) Fail to hard link"
20875
20876         echo "Links count should be right although linkEA overflow"
20877         stat $DIR/$tdir/guard || error "(4) Fail to stat"
20878         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
20879         [ $linkcount -eq 1001 ] ||
20880                 error "(5) Unexpected hard links count: $linkcount"
20881
20882         echo "List all links start at $(date)"
20883         ls -l $DIR/$tdir/foo > /dev/null ||
20884                 error "(6) Fail to list $DIR/$tdir/foo"
20885
20886         echo "Unlink hard links start at $(date)"
20887         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20888                 error "(7) Fail to unlink"
20889         echo "Unlink hard links finished at $(date)"
20890 }
20891 run_test 409 "Large amount of cross-MDTs hard links on the same file"
20892
20893 test_410()
20894 {
20895         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
20896                 skip "Need client version at least 2.9.59"
20897
20898         # Create a file, and stat it from the kernel
20899         local testfile=$DIR/$tfile
20900         touch $testfile
20901
20902         local run_id=$RANDOM
20903         local my_ino=$(stat --format "%i" $testfile)
20904
20905         # Try to insert the module. This will always fail as the
20906         # module is designed to not be inserted.
20907         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
20908             &> /dev/null
20909
20910         # Anything but success is a test failure
20911         dmesg | grep -q \
20912             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
20913             error "no inode match"
20914 }
20915 run_test 410 "Test inode number returned from kernel thread"
20916
20917 cleanup_test411_cgroup() {
20918         trap 0
20919         rmdir "$1"
20920 }
20921
20922 test_411() {
20923         local cg_basedir=/sys/fs/cgroup/memory
20924         # LU-9966
20925         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
20926                 skip "no setup for cgroup"
20927
20928         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
20929                 error "test file creation failed"
20930         cancel_lru_locks osc
20931
20932         # Create a very small memory cgroup to force a slab allocation error
20933         local cgdir=$cg_basedir/osc_slab_alloc
20934         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
20935         trap "cleanup_test411_cgroup $cgdir" EXIT
20936         echo 2M > $cgdir/memory.kmem.limit_in_bytes
20937         echo 1M > $cgdir/memory.limit_in_bytes
20938
20939         # Should not LBUG, just be killed by oom-killer
20940         # dd will return 0 even allocation failure in some environment.
20941         # So don't check return value
20942         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
20943         cleanup_test411_cgroup $cgdir
20944
20945         return 0
20946 }
20947 run_test 411 "Slab allocation error with cgroup does not LBUG"
20948
20949 test_412() {
20950         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20951         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20952                 skip "Need server version at least 2.10.55"
20953         fi
20954
20955         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
20956                 error "mkdir failed"
20957         $LFS getdirstripe $DIR/$tdir
20958         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20959         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
20960                 error "expect $((MDSCOUT - 1)) get $stripe_index"
20961         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
20962         [ $stripe_count -eq 2 ] ||
20963                 error "expect 2 get $stripe_count"
20964 }
20965 run_test 412 "mkdir on specific MDTs"
20966
20967 test_qos_mkdir() {
20968         local mkdir_cmd=$1
20969         local stripe_count=$2
20970         local mdts=$(comma_list $(mdts_nodes))
20971
20972         local testdir
20973         local lmv_qos_prio_free
20974         local lmv_qos_threshold_rr
20975         local lmv_qos_maxage
20976         local lod_qos_prio_free
20977         local lod_qos_threshold_rr
20978         local lod_qos_maxage
20979         local count
20980         local i
20981
20982         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
20983         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
20984         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
20985                 head -n1)
20986         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
20987         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
20988         stack_trap "$LCTL set_param \
20989                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
20990         stack_trap "$LCTL set_param \
20991                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
20992         stack_trap "$LCTL set_param \
20993                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
20994
20995         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
20996                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
20997         lod_qos_prio_free=${lod_qos_prio_free%%%}
20998         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
20999                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
21000         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
21001         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
21002                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
21003         stack_trap "do_nodes $mdts $LCTL set_param \
21004                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
21005         stack_trap "do_nodes $mdts $LCTL set_param \
21006                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
21007                 EXIT
21008         stack_trap "do_nodes $mdts $LCTL set_param \
21009                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
21010
21011         echo
21012         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
21013
21014         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
21015         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
21016
21017         testdir=$DIR/$tdir-s$stripe_count/rr
21018
21019         for i in $(seq $((100 * MDSCOUNT))); do
21020                 eval $mkdir_cmd $testdir/subdir$i ||
21021                         error "$mkdir_cmd subdir$i failed"
21022         done
21023
21024         for i in $(seq $MDSCOUNT); do
21025                 count=$($LFS getdirstripe -i $testdir/* |
21026                                 grep ^$((i - 1))$ | wc -l)
21027                 echo "$count directories created on MDT$((i - 1))"
21028                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
21029
21030                 if [ $stripe_count -gt 1 ]; then
21031                         count=$($LFS getdirstripe $testdir/* |
21032                                 grep -P "^\s+$((i - 1))\t" | wc -l)
21033                         echo "$count stripes created on MDT$((i - 1))"
21034                         # deviation should < 5% of average
21035                         [ $count -lt $((95 * stripe_count)) ] ||
21036                         [ $count -gt $((105 * stripe_count)) ] &&
21037                                 error "stripes are not evenly distributed"
21038                 fi
21039         done
21040
21041         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
21042         do_nodes $mdts $LCTL set_param \
21043                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
21044
21045         echo
21046         echo "Check for uneven MDTs: "
21047
21048         local ffree
21049         local bavail
21050         local max
21051         local min
21052         local max_index
21053         local min_index
21054         local tmp
21055
21056         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
21057         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
21058         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
21059
21060         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
21061         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
21062         max_index=0
21063         min_index=0
21064         for ((i = 1; i < ${#ffree[@]}; i++)); do
21065                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
21066                 if [ $tmp -gt $max ]; then
21067                         max=$tmp
21068                         max_index=$i
21069                 fi
21070                 if [ $tmp -lt $min ]; then
21071                         min=$tmp
21072                         min_index=$i
21073                 fi
21074         done
21075
21076         [ ${ffree[min_index]} -eq 0 ] &&
21077                 skip "no free files in MDT$min_index"
21078         [ ${ffree[min_index]} -gt 100000000 ] &&
21079                 skip "too much free files in MDT$min_index"
21080
21081         # Check if we need to generate uneven MDTs
21082         local threshold=50
21083         local diff=$(((max - min) * 100 / min))
21084         local value="$(generate_string 1024)"
21085
21086         while [ $diff -lt $threshold ]; do
21087                 # generate uneven MDTs, create till $threshold% diff
21088                 echo -n "weight diff=$diff% must be > $threshold% ..."
21089                 count=$((${ffree[min_index]} / 10))
21090                 # 50 sec per 10000 files in vm
21091                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
21092                         skip "$count files to create"
21093                 echo "Fill MDT$min_index with $count files"
21094                 [ -d $DIR/$tdir-MDT$min_index ] ||
21095                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
21096                         error "mkdir $tdir-MDT$min_index failed"
21097                 for i in $(seq $count); do
21098                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
21099                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
21100                                 error "create f$j_$i failed"
21101                         setfattr -n user.413b -v $value \
21102                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
21103                                 error "setfattr f$j_$i failed"
21104                 done
21105
21106                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
21107                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
21108                 max=$(((${ffree[max_index]} >> 8) * \
21109                         (${bavail[max_index]} * bsize >> 16)))
21110                 min=$(((${ffree[min_index]} >> 8) * \
21111                         (${bavail[min_index]} * bsize >> 16)))
21112                 diff=$(((max - min) * 100 / min))
21113         done
21114
21115         echo "MDT filesfree available: ${ffree[@]}"
21116         echo "MDT blocks available: ${bavail[@]}"
21117         echo "weight diff=$diff%"
21118
21119         echo
21120         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
21121
21122         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
21123         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
21124         # decrease statfs age, so that it can be updated in time
21125         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
21126         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
21127
21128         sleep 1
21129
21130         testdir=$DIR/$tdir-s$stripe_count/qos
21131
21132         for i in $(seq $((100 * MDSCOUNT))); do
21133                 eval $mkdir_cmd $testdir/subdir$i ||
21134                         error "$mkdir_cmd subdir$i failed"
21135         done
21136
21137         for i in $(seq $MDSCOUNT); do
21138                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
21139                         wc -l)
21140                 echo "$count directories created on MDT$((i - 1))"
21141
21142                 if [ $stripe_count -gt 1 ]; then
21143                         count=$($LFS getdirstripe $testdir/* |
21144                                 grep -P "^\s+$((i - 1))\t" | wc -l)
21145                         echo "$count stripes created on MDT$((i - 1))"
21146                 fi
21147         done
21148
21149         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
21150         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
21151
21152         # D-value should > 10% of averge
21153         [ $((max - min)) -lt 10 ] &&
21154                 error "subdirs shouldn't be evenly distributed"
21155
21156         # ditto
21157         if [ $stripe_count -gt 1 ]; then
21158                 max=$($LFS getdirstripe $testdir/* |
21159                         grep -P "^\s+$max_index\t" | wc -l)
21160                 min=$($LFS getdirstripe $testdir/* |
21161                         grep -P "^\s+$min_index\t" | wc -l)
21162                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
21163                         error "stripes shouldn't be evenly distributed"|| true
21164         fi
21165 }
21166
21167 test_413a() {
21168         [ $MDSCOUNT -lt 2 ] &&
21169                 skip "We need at least 2 MDTs for this test"
21170
21171         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
21172                 skip "Need server version at least 2.12.52"
21173
21174         local stripe_count
21175
21176         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
21177                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
21178                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
21179                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
21180                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
21181         done
21182 }
21183 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
21184
21185 test_413b() {
21186         [ $MDSCOUNT -lt 2 ] &&
21187                 skip "We need at least 2 MDTs for this test"
21188
21189         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
21190                 skip "Need server version at least 2.12.52"
21191
21192         local stripe_count
21193
21194         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
21195                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
21196                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
21197                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
21198                 $LFS setdirstripe -D -c $stripe_count \
21199                         $DIR/$tdir-s$stripe_count/rr ||
21200                         error "setdirstripe failed"
21201                 $LFS setdirstripe -D -c $stripe_count \
21202                         $DIR/$tdir-s$stripe_count/qos ||
21203                         error "setdirstripe failed"
21204                 test_qos_mkdir "mkdir" $stripe_count
21205         done
21206 }
21207 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
21208
21209 test_414() {
21210 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
21211         $LCTL set_param fail_loc=0x80000521
21212         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
21213         rm -f $DIR/$tfile
21214 }
21215 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
21216
21217 test_415() {
21218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21219         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
21220                 skip "Need server version at least 2.11.52"
21221
21222         # LU-11102
21223         local total
21224         local setattr_pid
21225         local start_time
21226         local end_time
21227         local duration
21228
21229         total=500
21230         # this test may be slow on ZFS
21231         [ "$mds1_FSTYPE" == "zfs" ] && total=100
21232
21233         # though this test is designed for striped directory, let's test normal
21234         # directory too since lock is always saved as CoS lock.
21235         test_mkdir $DIR/$tdir || error "mkdir $tdir"
21236         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
21237
21238         (
21239                 while true; do
21240                         touch $DIR/$tdir
21241                 done
21242         ) &
21243         setattr_pid=$!
21244
21245         start_time=$(date +%s)
21246         for i in $(seq $total); do
21247                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
21248                         > /dev/null
21249         done
21250         end_time=$(date +%s)
21251         duration=$((end_time - start_time))
21252
21253         kill -9 $setattr_pid
21254
21255         echo "rename $total files took $duration sec"
21256         [ $duration -lt 100 ] || error "rename took $duration sec"
21257 }
21258 run_test 415 "lock revoke is not missing"
21259
21260 test_416() {
21261         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
21262                 skip "Need server version at least 2.11.55"
21263
21264         # define OBD_FAIL_OSD_TXN_START    0x19a
21265         do_facet mds1 lctl set_param fail_loc=0x19a
21266
21267         lfs mkdir -c $MDSCOUNT $DIR/$tdir
21268
21269         true
21270 }
21271 run_test 416 "transaction start failure won't cause system hung"
21272
21273 cleanup_417() {
21274         trap 0
21275         do_nodes $(comma_list $(mdts_nodes)) \
21276                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
21277         do_nodes $(comma_list $(mdts_nodes)) \
21278                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
21279         do_nodes $(comma_list $(mdts_nodes)) \
21280                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
21281 }
21282
21283 test_417() {
21284         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21285         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
21286                 skip "Need MDS version at least 2.11.56"
21287
21288         trap cleanup_417 RETURN EXIT
21289
21290         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
21291         do_nodes $(comma_list $(mdts_nodes)) \
21292                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
21293         $LFS migrate -m 0 $DIR/$tdir.1 &&
21294                 error "migrate dir $tdir.1 should fail"
21295
21296         do_nodes $(comma_list $(mdts_nodes)) \
21297                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
21298         $LFS mkdir -i 1 $DIR/$tdir.2 &&
21299                 error "create remote dir $tdir.2 should fail"
21300
21301         do_nodes $(comma_list $(mdts_nodes)) \
21302                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
21303         $LFS mkdir -c 2 $DIR/$tdir.3 &&
21304                 error "create striped dir $tdir.3 should fail"
21305         true
21306 }
21307 run_test 417 "disable remote dir, striped dir and dir migration"
21308
21309 # Checks that the outputs of df [-i] and lfs df [-i] match
21310 #
21311 # usage: check_lfs_df <blocks | inodes> <mountpoint>
21312 check_lfs_df() {
21313         local dir=$2
21314         local inodes
21315         local df_out
21316         local lfs_df_out
21317         local count
21318         local passed=false
21319
21320         # blocks or inodes
21321         [ "$1" == "blocks" ] && inodes= || inodes="-i"
21322
21323         for count in {1..100}; do
21324                 cancel_lru_locks
21325                 sync; sleep 0.2
21326
21327                 # read the lines of interest
21328                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
21329                         error "df $inodes $dir | tail -n +2 failed"
21330                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
21331                         error "lfs df $inodes $dir | grep summary: failed"
21332
21333                 # skip first substrings of each output as they are different
21334                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
21335                 # compare the two outputs
21336                 passed=true
21337                 for i in {1..5}; do
21338                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
21339                 done
21340                 $passed && break
21341         done
21342
21343         if ! $passed; then
21344                 df -P $inodes $dir
21345                 echo
21346                 lfs df $inodes $dir
21347                 error "df and lfs df $1 output mismatch: "      \
21348                       "df ${inodes}: ${df_out[*]}, "            \
21349                       "lfs df ${inodes}: ${lfs_df_out[*]}"
21350         fi
21351 }
21352
21353 test_418() {
21354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21355
21356         local dir=$DIR/$tdir
21357         local numfiles=$((RANDOM % 4096 + 2))
21358         local numblocks=$((RANDOM % 256 + 1))
21359
21360         wait_delete_completed
21361         test_mkdir $dir
21362
21363         # check block output
21364         check_lfs_df blocks $dir
21365         # check inode output
21366         check_lfs_df inodes $dir
21367
21368         # create a single file and retest
21369         echo "Creating a single file and testing"
21370         createmany -o $dir/$tfile- 1 &>/dev/null ||
21371                 error "creating 1 file in $dir failed"
21372         check_lfs_df blocks $dir
21373         check_lfs_df inodes $dir
21374
21375         # create a random number of files
21376         echo "Creating $((numfiles - 1)) files and testing"
21377         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
21378                 error "creating $((numfiles - 1)) files in $dir failed"
21379
21380         # write a random number of blocks to the first test file
21381         echo "Writing $numblocks 4K blocks and testing"
21382         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
21383                 count=$numblocks &>/dev/null ||
21384                 error "dd to $dir/${tfile}-0 failed"
21385
21386         # retest
21387         check_lfs_df blocks $dir
21388         check_lfs_df inodes $dir
21389
21390         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
21391                 error "unlinking $numfiles files in $dir failed"
21392 }
21393 run_test 418 "df and lfs df outputs match"
21394
21395 test_419()
21396 {
21397         local dir=$DIR/$tdir
21398
21399         mkdir -p $dir
21400         touch $dir/file
21401
21402         cancel_lru_locks mdc
21403
21404         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
21405         $LCTL set_param fail_loc=0x1410
21406         cat $dir/file
21407         $LCTL set_param fail_loc=0
21408         rm -rf $dir
21409 }
21410 run_test 419 "Verify open file by name doesn't crash kernel"
21411
21412 test_420()
21413 {
21414         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
21415                 skip "Need MDS version at least 2.12.53"
21416
21417         local SAVE_UMASK=$(umask)
21418         local dir=$DIR/$tdir
21419         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
21420
21421         mkdir -p $dir
21422         umask 0000
21423         mkdir -m03777 $dir/testdir
21424         ls -dn $dir/testdir
21425         # Need to remove trailing '.' when SELinux is enabled
21426         local dirperms=$(ls -dn $dir/testdir |
21427                          awk '{ sub(/\.$/, "", $1); print $1}')
21428         [ $dirperms == "drwxrwsrwt" ] ||
21429                 error "incorrect perms on $dir/testdir"
21430
21431         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
21432                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
21433         ls -n $dir/testdir/testfile
21434         local fileperms=$(ls -n $dir/testdir/testfile |
21435                           awk '{ sub(/\.$/, "", $1); print $1}')
21436         [ $fileperms == "-rwxr-xr-x" ] ||
21437                 error "incorrect perms on $dir/testdir/testfile"
21438
21439         umask $SAVE_UMASK
21440 }
21441 run_test 420 "clear SGID bit on non-directories for non-members"
21442
21443 test_421a() {
21444         local cnt
21445         local fid1
21446         local fid2
21447
21448         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21449                 skip "Need MDS version at least 2.12.54"
21450
21451         test_mkdir $DIR/$tdir
21452         createmany -o $DIR/$tdir/f 3
21453         cnt=$(ls -1 $DIR/$tdir | wc -l)
21454         [ $cnt != 3 ] && error "unexpected #files: $cnt"
21455
21456         fid1=$(lfs path2fid $DIR/$tdir/f1)
21457         fid2=$(lfs path2fid $DIR/$tdir/f2)
21458         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
21459
21460         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
21461         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
21462
21463         cnt=$(ls -1 $DIR/$tdir | wc -l)
21464         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
21465
21466         rm -f $DIR/$tdir/f3 || error "can't remove f3"
21467         createmany -o $DIR/$tdir/f 3
21468         cnt=$(ls -1 $DIR/$tdir | wc -l)
21469         [ $cnt != 3 ] && error "unexpected #files: $cnt"
21470
21471         fid1=$(lfs path2fid $DIR/$tdir/f1)
21472         fid2=$(lfs path2fid $DIR/$tdir/f2)
21473         echo "remove using fsname $FSNAME"
21474         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
21475
21476         cnt=$(ls -1 $DIR/$tdir | wc -l)
21477         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
21478 }
21479 run_test 421a "simple rm by fid"
21480
21481 test_421b() {
21482         local cnt
21483         local FID1
21484         local FID2
21485
21486         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21487                 skip "Need MDS version at least 2.12.54"
21488
21489         test_mkdir $DIR/$tdir
21490         createmany -o $DIR/$tdir/f 3
21491         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
21492         MULTIPID=$!
21493
21494         FID1=$(lfs path2fid $DIR/$tdir/f1)
21495         FID2=$(lfs path2fid $DIR/$tdir/f2)
21496         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
21497
21498         kill -USR1 $MULTIPID
21499         wait
21500
21501         cnt=$(ls $DIR/$tdir | wc -l)
21502         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
21503 }
21504 run_test 421b "rm by fid on open file"
21505
21506 test_421c() {
21507         local cnt
21508         local FIDS
21509
21510         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21511                 skip "Need MDS version at least 2.12.54"
21512
21513         test_mkdir $DIR/$tdir
21514         createmany -o $DIR/$tdir/f 3
21515         touch $DIR/$tdir/$tfile
21516         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
21517         cnt=$(ls -1 $DIR/$tdir | wc -l)
21518         [ $cnt != 184 ] && error "unexpected #files: $cnt"
21519
21520         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
21521         $LFS rmfid $DIR $FID1 || error "rmfid failed"
21522
21523         cnt=$(ls $DIR/$tdir | wc -l)
21524         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
21525 }
21526 run_test 421c "rm by fid against hardlinked files"
21527
21528 test_421d() {
21529         local cnt
21530         local FIDS
21531
21532         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21533                 skip "Need MDS version at least 2.12.54"
21534
21535         test_mkdir $DIR/$tdir
21536         createmany -o $DIR/$tdir/f 4097
21537         cnt=$(ls -1 $DIR/$tdir | wc -l)
21538         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
21539
21540         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
21541         $LFS rmfid $DIR $FIDS || error "rmfid failed"
21542
21543         cnt=$(ls $DIR/$tdir | wc -l)
21544         rm -rf $DIR/$tdir
21545         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21546 }
21547 run_test 421d "rmfid en masse"
21548
21549 test_421e() {
21550         local cnt
21551         local FID
21552
21553         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21554         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21555                 skip "Need MDS version at least 2.12.54"
21556
21557         mkdir -p $DIR/$tdir
21558         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21559         createmany -o $DIR/$tdir/striped_dir/f 512
21560         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21561         [ $cnt != 512 ] && error "unexpected #files: $cnt"
21562
21563         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
21564                 sed "s/[/][^:]*://g")
21565         $LFS rmfid $DIR $FIDS || error "rmfid failed"
21566
21567         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
21568         rm -rf $DIR/$tdir
21569         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21570 }
21571 run_test 421e "rmfid in DNE"
21572
21573 test_421f() {
21574         local cnt
21575         local FID
21576
21577         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21578                 skip "Need MDS version at least 2.12.54"
21579
21580         test_mkdir $DIR/$tdir
21581         touch $DIR/$tdir/f
21582         cnt=$(ls -1 $DIR/$tdir | wc -l)
21583         [ $cnt != 1 ] && error "unexpected #files: $cnt"
21584
21585         FID=$(lfs path2fid $DIR/$tdir/f)
21586         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
21587         # rmfid should fail
21588         cnt=$(ls -1 $DIR/$tdir | wc -l)
21589         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
21590
21591         chmod a+rw $DIR/$tdir
21592         ls -la $DIR/$tdir
21593         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
21594         # rmfid should fail
21595         cnt=$(ls -1 $DIR/$tdir | wc -l)
21596         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
21597
21598         rm -f $DIR/$tdir/f
21599         $RUNAS touch $DIR/$tdir/f
21600         FID=$(lfs path2fid $DIR/$tdir/f)
21601         echo "rmfid as root"
21602         $LFS rmfid $DIR $FID || error "rmfid as root failed"
21603         cnt=$(ls -1 $DIR/$tdir | wc -l)
21604         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
21605
21606         rm -f $DIR/$tdir/f
21607         $RUNAS touch $DIR/$tdir/f
21608         cnt=$(ls -1 $DIR/$tdir | wc -l)
21609         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
21610         FID=$(lfs path2fid $DIR/$tdir/f)
21611         # rmfid w/o user_fid2path mount option should fail
21612         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
21613         cnt=$(ls -1 $DIR/$tdir | wc -l)
21614         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
21615
21616         umount_client $MOUNT || error "failed to umount client"
21617         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
21618                 error "failed to mount client'"
21619
21620         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
21621         # rmfid should succeed
21622         cnt=$(ls -1 $DIR/$tdir | wc -l)
21623         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
21624
21625         # rmfid shouldn't allow to remove files due to dir's permission
21626         chmod a+rwx $DIR/$tdir
21627         touch $DIR/$tdir/f
21628         ls -la $DIR/$tdir
21629         FID=$(lfs path2fid $DIR/$tdir/f)
21630         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
21631
21632         umount_client $MOUNT || error "failed to umount client"
21633         mount_client $MOUNT "$MOUNT_OPTS" ||
21634                 error "failed to mount client'"
21635
21636 }
21637 run_test 421f "rmfid checks permissions"
21638
21639 test_421g() {
21640         local cnt
21641         local FIDS
21642
21643         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21644         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21645                 skip "Need MDS version at least 2.12.54"
21646
21647         mkdir -p $DIR/$tdir
21648         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21649         createmany -o $DIR/$tdir/striped_dir/f 512
21650         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21651         [ $cnt != 512 ] && error "unexpected #files: $cnt"
21652
21653         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
21654                 sed "s/[/][^:]*://g")
21655
21656         rm -f $DIR/$tdir/striped_dir/f1*
21657         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21658         removed=$((512 - cnt))
21659
21660         # few files have been just removed, so we expect
21661         # rmfid to fail on their fids
21662         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
21663         [ $removed != $errors ] && error "$errors != $removed"
21664
21665         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
21666         rm -rf $DIR/$tdir
21667         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21668 }
21669 run_test 421g "rmfid to return errors properly"
21670
21671 test_422() {
21672         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
21673         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
21674         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
21675         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
21676         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
21677
21678         local amc=$(at_max_get client)
21679         local amo=$(at_max_get mds1)
21680         local timeout=`lctl get_param -n timeout`
21681
21682         at_max_set 0 client
21683         at_max_set 0 mds1
21684
21685 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
21686         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
21687                         fail_val=$(((2*timeout + 10)*1000))
21688         touch $DIR/$tdir/d3/file &
21689         sleep 2
21690 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
21691         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
21692                         fail_val=$((2*timeout + 5))
21693         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
21694         local pid=$!
21695         sleep 1
21696         kill -9 $pid
21697         sleep $((2 * timeout))
21698         echo kill $pid
21699         kill -9 $pid
21700         lctl mark touch
21701         touch $DIR/$tdir/d2/file3
21702         touch $DIR/$tdir/d2/file4
21703         touch $DIR/$tdir/d2/file5
21704
21705         wait
21706         at_max_set $amc client
21707         at_max_set $amo mds1
21708
21709         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
21710         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
21711                 error "Watchdog is always throttled"
21712 }
21713 run_test 422 "kill a process with RPC in progress"
21714
21715 prep_801() {
21716         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
21717         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
21718                 skip "Need server version at least 2.9.55"
21719
21720         start_full_debug_logging
21721 }
21722
21723 post_801() {
21724         stop_full_debug_logging
21725 }
21726
21727 barrier_stat() {
21728         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
21729                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
21730                            awk '/The barrier for/ { print $7 }')
21731                 echo $st
21732         else
21733                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
21734                 echo \'$st\'
21735         fi
21736 }
21737
21738 barrier_expired() {
21739         local expired
21740
21741         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
21742                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
21743                           awk '/will be expired/ { print $7 }')
21744         else
21745                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
21746         fi
21747
21748         echo $expired
21749 }
21750
21751 test_801a() {
21752         prep_801
21753
21754         echo "Start barrier_freeze at: $(date)"
21755         #define OBD_FAIL_BARRIER_DELAY          0x2202
21756         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
21757         # Do not reduce barrier time - See LU-11873
21758         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
21759
21760         sleep 2
21761         local b_status=$(barrier_stat)
21762         echo "Got barrier status at: $(date)"
21763         [ "$b_status" = "'freezing_p1'" ] ||
21764                 error "(1) unexpected barrier status $b_status"
21765
21766         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
21767         wait
21768         b_status=$(barrier_stat)
21769         [ "$b_status" = "'frozen'" ] ||
21770                 error "(2) unexpected barrier status $b_status"
21771
21772         local expired=$(barrier_expired)
21773         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
21774         sleep $((expired + 3))
21775
21776         b_status=$(barrier_stat)
21777         [ "$b_status" = "'expired'" ] ||
21778                 error "(3) unexpected barrier status $b_status"
21779
21780         # Do not reduce barrier time - See LU-11873
21781         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
21782                 error "(4) fail to freeze barrier"
21783
21784         b_status=$(barrier_stat)
21785         [ "$b_status" = "'frozen'" ] ||
21786                 error "(5) unexpected barrier status $b_status"
21787
21788         echo "Start barrier_thaw at: $(date)"
21789         #define OBD_FAIL_BARRIER_DELAY          0x2202
21790         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
21791         do_facet mgs $LCTL barrier_thaw $FSNAME &
21792
21793         sleep 2
21794         b_status=$(barrier_stat)
21795         echo "Got barrier status at: $(date)"
21796         [ "$b_status" = "'thawing'" ] ||
21797                 error "(6) unexpected barrier status $b_status"
21798
21799         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
21800         wait
21801         b_status=$(barrier_stat)
21802         [ "$b_status" = "'thawed'" ] ||
21803                 error "(7) unexpected barrier status $b_status"
21804
21805         #define OBD_FAIL_BARRIER_FAILURE        0x2203
21806         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
21807         do_facet mgs $LCTL barrier_freeze $FSNAME
21808
21809         b_status=$(barrier_stat)
21810         [ "$b_status" = "'failed'" ] ||
21811                 error "(8) unexpected barrier status $b_status"
21812
21813         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21814         do_facet mgs $LCTL barrier_thaw $FSNAME
21815
21816         post_801
21817 }
21818 run_test 801a "write barrier user interfaces and stat machine"
21819
21820 test_801b() {
21821         prep_801
21822
21823         mkdir $DIR/$tdir || error "(1) fail to mkdir"
21824         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
21825         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
21826         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
21827         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
21828
21829         cancel_lru_locks mdc
21830
21831         # 180 seconds should be long enough
21832         do_facet mgs $LCTL barrier_freeze $FSNAME 180
21833
21834         local b_status=$(barrier_stat)
21835         [ "$b_status" = "'frozen'" ] ||
21836                 error "(6) unexpected barrier status $b_status"
21837
21838         mkdir $DIR/$tdir/d0/d10 &
21839         mkdir_pid=$!
21840
21841         touch $DIR/$tdir/d1/f13 &
21842         touch_pid=$!
21843
21844         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
21845         ln_pid=$!
21846
21847         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
21848         mv_pid=$!
21849
21850         rm -f $DIR/$tdir/d4/f12 &
21851         rm_pid=$!
21852
21853         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
21854
21855         # To guarantee taht the 'stat' is not blocked
21856         b_status=$(barrier_stat)
21857         [ "$b_status" = "'frozen'" ] ||
21858                 error "(8) unexpected barrier status $b_status"
21859
21860         # let above commands to run at background
21861         sleep 5
21862
21863         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
21864         ps -p $touch_pid || error "(10) touch should be blocked"
21865         ps -p $ln_pid || error "(11) link should be blocked"
21866         ps -p $mv_pid || error "(12) rename should be blocked"
21867         ps -p $rm_pid || error "(13) unlink should be blocked"
21868
21869         b_status=$(barrier_stat)
21870         [ "$b_status" = "'frozen'" ] ||
21871                 error "(14) unexpected barrier status $b_status"
21872
21873         do_facet mgs $LCTL barrier_thaw $FSNAME
21874         b_status=$(barrier_stat)
21875         [ "$b_status" = "'thawed'" ] ||
21876                 error "(15) unexpected barrier status $b_status"
21877
21878         wait $mkdir_pid || error "(16) mkdir should succeed"
21879         wait $touch_pid || error "(17) touch should succeed"
21880         wait $ln_pid || error "(18) link should succeed"
21881         wait $mv_pid || error "(19) rename should succeed"
21882         wait $rm_pid || error "(20) unlink should succeed"
21883
21884         post_801
21885 }
21886 run_test 801b "modification will be blocked by write barrier"
21887
21888 test_801c() {
21889         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21890
21891         prep_801
21892
21893         stop mds2 || error "(1) Fail to stop mds2"
21894
21895         do_facet mgs $LCTL barrier_freeze $FSNAME 30
21896
21897         local b_status=$(barrier_stat)
21898         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
21899                 do_facet mgs $LCTL barrier_thaw $FSNAME
21900                 error "(2) unexpected barrier status $b_status"
21901         }
21902
21903         do_facet mgs $LCTL barrier_rescan $FSNAME ||
21904                 error "(3) Fail to rescan barrier bitmap"
21905
21906         # Do not reduce barrier time - See LU-11873
21907         do_facet mgs $LCTL barrier_freeze $FSNAME 20
21908
21909         b_status=$(barrier_stat)
21910         [ "$b_status" = "'frozen'" ] ||
21911                 error "(4) unexpected barrier status $b_status"
21912
21913         do_facet mgs $LCTL barrier_thaw $FSNAME
21914         b_status=$(barrier_stat)
21915         [ "$b_status" = "'thawed'" ] ||
21916                 error "(5) unexpected barrier status $b_status"
21917
21918         local devname=$(mdsdevname 2)
21919
21920         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
21921
21922         do_facet mgs $LCTL barrier_rescan $FSNAME ||
21923                 error "(7) Fail to rescan barrier bitmap"
21924
21925         post_801
21926 }
21927 run_test 801c "rescan barrier bitmap"
21928
21929 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
21930 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
21931 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
21932 saved_MOUNT_OPTS=$MOUNT_OPTS
21933
21934 cleanup_802a() {
21935         trap 0
21936
21937         stopall
21938         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
21939         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
21940         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
21941         MOUNT_OPTS=$saved_MOUNT_OPTS
21942         setupall
21943 }
21944
21945 test_802a() {
21946         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
21947         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
21948         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
21949                 skip "Need server version at least 2.9.55"
21950
21951         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
21952
21953         mkdir $DIR/$tdir || error "(1) fail to mkdir"
21954
21955         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
21956                 error "(2) Fail to copy"
21957
21958         trap cleanup_802a EXIT
21959
21960         # sync by force before remount as readonly
21961         sync; sync_all_data; sleep 3; sync_all_data
21962
21963         stopall
21964
21965         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
21966         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
21967         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
21968
21969         echo "Mount the server as read only"
21970         setupall server_only || error "(3) Fail to start servers"
21971
21972         echo "Mount client without ro should fail"
21973         mount_client $MOUNT &&
21974                 error "(4) Mount client without 'ro' should fail"
21975
21976         echo "Mount client with ro should succeed"
21977         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
21978         mount_client $MOUNT ||
21979                 error "(5) Mount client with 'ro' should succeed"
21980
21981         echo "Modify should be refused"
21982         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
21983
21984         echo "Read should be allowed"
21985         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
21986                 error "(7) Read should succeed under ro mode"
21987
21988         cleanup_802a
21989 }
21990 run_test 802a "simulate readonly device"
21991
21992 test_802b() {
21993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21994         remote_mds_nodsh && skip "remote MDS with nodsh"
21995
21996         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
21997                 skip "readonly option not available"
21998
21999         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
22000
22001         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
22002                 error "(2) Fail to copy"
22003
22004         # write back all cached data before setting MDT to readonly
22005         cancel_lru_locks
22006         sync_all_data
22007
22008         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
22009         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
22010
22011         echo "Modify should be refused"
22012         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
22013
22014         echo "Read should be allowed"
22015         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
22016                 error "(7) Read should succeed under ro mode"
22017
22018         # disable readonly
22019         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
22020 }
22021 run_test 802b "be able to set MDTs to readonly"
22022
22023 test_803() {
22024         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
22025         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
22026                 skip "MDS needs to be newer than 2.10.54"
22027
22028         mkdir -p $DIR/$tdir
22029         # Create some objects on all MDTs to trigger related logs objects
22030         for idx in $(seq $MDSCOUNT); do
22031                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
22032                         $DIR/$tdir/dir${idx} ||
22033                         error "Fail to create $DIR/$tdir/dir${idx}"
22034         done
22035
22036         sync; sleep 3
22037         wait_delete_completed # ensure old test cleanups are finished
22038         echo "before create:"
22039         $LFS df -i $MOUNT
22040         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22041
22042         for i in {1..10}; do
22043                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
22044                         error "Fail to create $DIR/$tdir/foo$i"
22045         done
22046
22047         sync; sleep 3
22048         echo "after create:"
22049         $LFS df -i $MOUNT
22050         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22051
22052         # allow for an llog to be cleaned up during the test
22053         [ $after_used -ge $((before_used + 10 - 1)) ] ||
22054                 error "before ($before_used) + 10 > after ($after_used)"
22055
22056         for i in {1..10}; do
22057                 rm -rf $DIR/$tdir/foo$i ||
22058                         error "Fail to remove $DIR/$tdir/foo$i"
22059         done
22060
22061         sleep 3 # avoid MDT return cached statfs
22062         wait_delete_completed
22063         echo "after unlink:"
22064         $LFS df -i $MOUNT
22065         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22066
22067         # allow for an llog to be created during the test
22068         [ $after_used -le $((before_used + 1)) ] ||
22069                 error "after ($after_used) > before ($before_used) + 1"
22070 }
22071 run_test 803 "verify agent object for remote object"
22072
22073 test_804() {
22074         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
22075         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
22076                 skip "MDS needs to be newer than 2.10.54"
22077         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22078
22079         mkdir -p $DIR/$tdir
22080         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
22081                 error "Fail to create $DIR/$tdir/dir0"
22082
22083         local fid=$($LFS path2fid $DIR/$tdir/dir0)
22084         local dev=$(mdsdevname 2)
22085
22086         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22087                 grep ${fid} || error "NOT found agent entry for dir0"
22088
22089         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
22090                 error "Fail to create $DIR/$tdir/dir1"
22091
22092         touch $DIR/$tdir/dir1/foo0 ||
22093                 error "Fail to create $DIR/$tdir/dir1/foo0"
22094         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
22095         local rc=0
22096
22097         for idx in $(seq $MDSCOUNT); do
22098                 dev=$(mdsdevname $idx)
22099                 do_facet mds${idx} \
22100                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22101                         grep ${fid} && rc=$idx
22102         done
22103
22104         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
22105                 error "Fail to rename foo0 to foo1"
22106         if [ $rc -eq 0 ]; then
22107                 for idx in $(seq $MDSCOUNT); do
22108                         dev=$(mdsdevname $idx)
22109                         do_facet mds${idx} \
22110                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22111                         grep ${fid} && rc=$idx
22112                 done
22113         fi
22114
22115         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
22116                 error "Fail to rename foo1 to foo2"
22117         if [ $rc -eq 0 ]; then
22118                 for idx in $(seq $MDSCOUNT); do
22119                         dev=$(mdsdevname $idx)
22120                         do_facet mds${idx} \
22121                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22122                         grep ${fid} && rc=$idx
22123                 done
22124         fi
22125
22126         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
22127
22128         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
22129                 error "Fail to link to $DIR/$tdir/dir1/foo2"
22130         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
22131                 error "Fail to rename foo2 to foo0"
22132         unlink $DIR/$tdir/dir1/foo0 ||
22133                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
22134         rm -rf $DIR/$tdir/dir0 ||
22135                 error "Fail to rm $DIR/$tdir/dir0"
22136
22137         for idx in $(seq $MDSCOUNT); do
22138                 dev=$(mdsdevname $idx)
22139                 rc=0
22140
22141                 stop mds${idx}
22142                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
22143                         rc=$?
22144                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
22145                         error "mount mds$idx failed"
22146                 df $MOUNT > /dev/null 2>&1
22147
22148                 # e2fsck should not return error
22149                 [ $rc -eq 0 ] ||
22150                         error "e2fsck detected error on MDT${idx}: rc=$rc"
22151         done
22152 }
22153 run_test 804 "verify agent entry for remote entry"
22154
22155 cleanup_805() {
22156         do_facet $SINGLEMDS zfs set quota=$old $fsset
22157         unlinkmany $DIR/$tdir/f- 1000000
22158         trap 0
22159 }
22160
22161 test_805() {
22162         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
22163         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
22164         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
22165                 skip "netfree not implemented before 0.7"
22166         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
22167                 skip "Need MDS version at least 2.10.57"
22168
22169         local fsset
22170         local freekb
22171         local usedkb
22172         local old
22173         local quota
22174         local pref="osd-zfs.$FSNAME-MDT0000."
22175
22176         # limit available space on MDS dataset to meet nospace issue
22177         # quickly. then ZFS 0.7.2 can use reserved space if asked
22178         # properly (using netfree flag in osd_declare_destroy()
22179         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
22180         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
22181                 gawk '{print $3}')
22182         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
22183         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
22184         let "usedkb=usedkb-freekb"
22185         let "freekb=freekb/2"
22186         if let "freekb > 5000"; then
22187                 let "freekb=5000"
22188         fi
22189         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
22190         trap cleanup_805 EXIT
22191         mkdir $DIR/$tdir
22192         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
22193         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
22194         rm -rf $DIR/$tdir || error "not able to remove"
22195         do_facet $SINGLEMDS zfs set quota=$old $fsset
22196         trap 0
22197 }
22198 run_test 805 "ZFS can remove from full fs"
22199
22200 # Size-on-MDS test
22201 check_lsom_data()
22202 {
22203         local file=$1
22204         local size=$($LFS getsom -s $file)
22205         local expect=$(stat -c %s $file)
22206
22207         [[ $size == $expect ]] ||
22208                 error "$file expected size: $expect, got: $size"
22209
22210         local blocks=$($LFS getsom -b $file)
22211         expect=$(stat -c %b $file)
22212         [[ $blocks == $expect ]] ||
22213                 error "$file expected blocks: $expect, got: $blocks"
22214 }
22215
22216 check_lsom_size()
22217 {
22218         local size=$($LFS getsom -s $1)
22219         local expect=$2
22220
22221         [[ $size == $expect ]] ||
22222                 error "$file expected size: $expect, got: $size"
22223 }
22224
22225 test_806() {
22226         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22227                 skip "Need MDS version at least 2.11.52"
22228
22229         local bs=1048576
22230
22231         touch $DIR/$tfile || error "touch $tfile failed"
22232
22233         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22234         save_lustre_params client "llite.*.xattr_cache" > $save
22235         lctl set_param llite.*.xattr_cache=0
22236         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22237
22238         # single-threaded write
22239         echo "Test SOM for single-threaded write"
22240         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
22241                 error "write $tfile failed"
22242         check_lsom_size $DIR/$tfile $bs
22243
22244         local num=32
22245         local size=$(($num * $bs))
22246         local offset=0
22247         local i
22248
22249         echo "Test SOM for single client multi-threaded($num) write"
22250         $TRUNCATE $DIR/$tfile 0
22251         for ((i = 0; i < $num; i++)); do
22252                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22253                 local pids[$i]=$!
22254                 offset=$((offset + $bs))
22255         done
22256         for (( i=0; i < $num; i++ )); do
22257                 wait ${pids[$i]}
22258         done
22259         check_lsom_size $DIR/$tfile $size
22260
22261         $TRUNCATE $DIR/$tfile 0
22262         for ((i = 0; i < $num; i++)); do
22263                 offset=$((offset - $bs))
22264                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22265                 local pids[$i]=$!
22266         done
22267         for (( i=0; i < $num; i++ )); do
22268                 wait ${pids[$i]}
22269         done
22270         check_lsom_size $DIR/$tfile $size
22271
22272         # multi-client writes
22273         num=$(get_node_count ${CLIENTS//,/ })
22274         size=$(($num * $bs))
22275         offset=0
22276         i=0
22277
22278         echo "Test SOM for multi-client ($num) writes"
22279         $TRUNCATE $DIR/$tfile 0
22280         for client in ${CLIENTS//,/ }; do
22281                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22282                 local pids[$i]=$!
22283                 i=$((i + 1))
22284                 offset=$((offset + $bs))
22285         done
22286         for (( i=0; i < $num; i++ )); do
22287                 wait ${pids[$i]}
22288         done
22289         check_lsom_size $DIR/$tfile $offset
22290
22291         i=0
22292         $TRUNCATE $DIR/$tfile 0
22293         for client in ${CLIENTS//,/ }; do
22294                 offset=$((offset - $bs))
22295                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22296                 local pids[$i]=$!
22297                 i=$((i + 1))
22298         done
22299         for (( i=0; i < $num; i++ )); do
22300                 wait ${pids[$i]}
22301         done
22302         check_lsom_size $DIR/$tfile $size
22303
22304         # verify truncate
22305         echo "Test SOM for truncate"
22306         $TRUNCATE $DIR/$tfile 1048576
22307         check_lsom_size $DIR/$tfile 1048576
22308         $TRUNCATE $DIR/$tfile 1234
22309         check_lsom_size $DIR/$tfile 1234
22310
22311         # verify SOM blocks count
22312         echo "Verify SOM block count"
22313         $TRUNCATE $DIR/$tfile 0
22314         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
22315                 error "failed to write file $tfile"
22316         check_lsom_data $DIR/$tfile
22317 }
22318 run_test 806 "Verify Lazy Size on MDS"
22319
22320 test_807() {
22321         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22322         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22323                 skip "Need MDS version at least 2.11.52"
22324
22325         # Registration step
22326         changelog_register || error "changelog_register failed"
22327         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
22328         changelog_users $SINGLEMDS | grep -q $cl_user ||
22329                 error "User $cl_user not found in changelog_users"
22330
22331         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22332         save_lustre_params client "llite.*.xattr_cache" > $save
22333         lctl set_param llite.*.xattr_cache=0
22334         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22335
22336         rm -rf $DIR/$tdir || error "rm $tdir failed"
22337         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22338         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
22339         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
22340         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
22341                 error "truncate $tdir/trunc failed"
22342
22343         local bs=1048576
22344         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
22345                 error "write $tfile failed"
22346
22347         # multi-client wirtes
22348         local num=$(get_node_count ${CLIENTS//,/ })
22349         local offset=0
22350         local i=0
22351
22352         echo "Test SOM for multi-client ($num) writes"
22353         touch $DIR/$tfile || error "touch $tfile failed"
22354         $TRUNCATE $DIR/$tfile 0
22355         for client in ${CLIENTS//,/ }; do
22356                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22357                 local pids[$i]=$!
22358                 i=$((i + 1))
22359                 offset=$((offset + $bs))
22360         done
22361         for (( i=0; i < $num; i++ )); do
22362                 wait ${pids[$i]}
22363         done
22364
22365         sleep 5
22366         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
22367         check_lsom_data $DIR/$tdir/trunc
22368         check_lsom_data $DIR/$tdir/single_dd
22369         check_lsom_data $DIR/$tfile
22370
22371         rm -rf $DIR/$tdir
22372         # Deregistration step
22373         changelog_deregister || error "changelog_deregister failed"
22374 }
22375 run_test 807 "verify LSOM syncing tool"
22376
22377 check_som_nologged()
22378 {
22379         local lines=$($LFS changelog $FSNAME-MDT0000 |
22380                 grep 'x=trusted.som' | wc -l)
22381         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
22382 }
22383
22384 test_808() {
22385         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22386                 skip "Need MDS version at least 2.11.55"
22387
22388         # Registration step
22389         changelog_register || error "changelog_register failed"
22390
22391         touch $DIR/$tfile || error "touch $tfile failed"
22392         check_som_nologged
22393
22394         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
22395                 error "write $tfile failed"
22396         check_som_nologged
22397
22398         $TRUNCATE $DIR/$tfile 1234
22399         check_som_nologged
22400
22401         $TRUNCATE $DIR/$tfile 1048576
22402         check_som_nologged
22403
22404         # Deregistration step
22405         changelog_deregister || error "changelog_deregister failed"
22406 }
22407 run_test 808 "Check trusted.som xattr not logged in Changelogs"
22408
22409 check_som_nodata()
22410 {
22411         $LFS getsom $1
22412         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
22413 }
22414
22415 test_809() {
22416         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22417                 skip "Need MDS version at least 2.11.56"
22418
22419         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
22420                 error "failed to create DoM-only file $DIR/$tfile"
22421         touch $DIR/$tfile || error "touch $tfile failed"
22422         check_som_nodata $DIR/$tfile
22423
22424         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
22425                 error "write $tfile failed"
22426         check_som_nodata $DIR/$tfile
22427
22428         $TRUNCATE $DIR/$tfile 1234
22429         check_som_nodata $DIR/$tfile
22430
22431         $TRUNCATE $DIR/$tfile 4097
22432         check_som_nodata $DIR/$file
22433 }
22434 run_test 809 "Verify no SOM xattr store for DoM-only files"
22435
22436 test_810() {
22437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22438         $GSS && skip_env "could not run with gss"
22439         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
22440                 skip "OST < 2.12.58 doesn't align checksum"
22441
22442         set_checksums 1
22443         stack_trap "set_checksums $ORIG_CSUM" EXIT
22444         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
22445
22446         local csum
22447         local before
22448         local after
22449         for csum in $CKSUM_TYPES; do
22450                 #define OBD_FAIL_OSC_NO_GRANT   0x411
22451                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
22452                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
22453                         eval set -- $i
22454                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
22455                         before=$(md5sum $DIR/$tfile)
22456                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
22457                         after=$(md5sum $DIR/$tfile)
22458                         [ "$before" == "$after" ] ||
22459                                 error "$csum: $before != $after bs=$1 seek=$2"
22460                 done
22461         done
22462 }
22463 run_test 810 "partial page writes on ZFS (LU-11663)"
22464
22465 test_811() {
22466         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
22467                 skip "Need MDS version at least 2.11.56"
22468
22469         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
22470         do_facet mds1 $LCTL set_param fail_loc=0x165
22471         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
22472
22473         stop mds1
22474         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22475
22476         sleep 5
22477         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
22478                 error "MDD orphan cleanup thread not quit"
22479 }
22480 run_test 811 "orphan name stub can be cleaned up in startup"
22481
22482 test_812a() {
22483         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
22484                 skip "OST < 2.12.51 doesn't support this fail_loc"
22485         [ "$SHARED_KEY" = true ] &&
22486                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22487
22488         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22489         # ensure ost1 is connected
22490         stat $DIR/$tfile >/dev/null || error "can't stat"
22491         wait_osc_import_state client ost1 FULL
22492         # no locks, no reqs to let the connection idle
22493         cancel_lru_locks osc
22494
22495         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
22496 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
22497         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
22498         wait_osc_import_state client ost1 CONNECTING
22499         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
22500
22501         stat $DIR/$tfile >/dev/null || error "can't stat file"
22502 }
22503 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
22504
22505 test_812b() { # LU-12378
22506         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
22507                 skip "OST < 2.12.51 doesn't support this fail_loc"
22508         [ "$SHARED_KEY" = true ] &&
22509                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22510
22511         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
22512         # ensure ost1 is connected
22513         stat $DIR/$tfile >/dev/null || error "can't stat"
22514         wait_osc_import_state client ost1 FULL
22515         # no locks, no reqs to let the connection idle
22516         cancel_lru_locks osc
22517
22518         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
22519 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
22520         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
22521         wait_osc_import_state client ost1 CONNECTING
22522         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
22523
22524         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
22525         wait_osc_import_state client ost1 IDLE
22526 }
22527 run_test 812b "do not drop no resend request for idle connect"
22528
22529 test_813() {
22530         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
22531         [ -z "$file_heat_sav" ] && skip "no file heat support"
22532
22533         local readsample
22534         local writesample
22535         local readbyte
22536         local writebyte
22537         local readsample1
22538         local writesample1
22539         local readbyte1
22540         local writebyte1
22541
22542         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
22543         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
22544
22545         $LCTL set_param -n llite.*.file_heat=1
22546         echo "Turn on file heat"
22547         echo "Period second: $period_second, Decay percentage: $decay_pct"
22548
22549         echo "QQQQ" > $DIR/$tfile
22550         echo "QQQQ" > $DIR/$tfile
22551         echo "QQQQ" > $DIR/$tfile
22552         cat $DIR/$tfile > /dev/null
22553         cat $DIR/$tfile > /dev/null
22554         cat $DIR/$tfile > /dev/null
22555         cat $DIR/$tfile > /dev/null
22556
22557         local out=$($LFS heat_get $DIR/$tfile)
22558
22559         $LFS heat_get $DIR/$tfile
22560         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22561         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22562         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22563         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22564
22565         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
22566         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
22567         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
22568         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
22569
22570         sleep $((period_second + 3))
22571         echo "Sleep $((period_second + 3)) seconds..."
22572         # The recursion formula to calculate the heat of the file f is as
22573         # follow:
22574         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
22575         # Where Hi is the heat value in the period between time points i*I and
22576         # (i+1)*I; Ci is the access count in the period; the symbol P refers
22577         # to the weight of Ci.
22578         out=$($LFS heat_get $DIR/$tfile)
22579         $LFS heat_get $DIR/$tfile
22580         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22581         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22582         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22583         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22584
22585         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
22586                 error "read sample ($readsample) is wrong"
22587         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
22588                 error "write sample ($writesample) is wrong"
22589         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
22590                 error "read bytes ($readbyte) is wrong"
22591         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
22592                 error "write bytes ($writebyte) is wrong"
22593
22594         echo "QQQQ" > $DIR/$tfile
22595         echo "QQQQ" > $DIR/$tfile
22596         echo "QQQQ" > $DIR/$tfile
22597         cat $DIR/$tfile > /dev/null
22598         cat $DIR/$tfile > /dev/null
22599         cat $DIR/$tfile > /dev/null
22600         cat $DIR/$tfile > /dev/null
22601
22602         sleep $((period_second + 3))
22603         echo "Sleep $((period_second + 3)) seconds..."
22604
22605         out=$($LFS heat_get $DIR/$tfile)
22606         $LFS heat_get $DIR/$tfile
22607         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22608         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22609         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22610         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22611
22612         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
22613                 4 * $decay_pct) / 100") -eq 1 ] ||
22614                 error "read sample ($readsample1) is wrong"
22615         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
22616                 3 * $decay_pct) / 100") -eq 1 ] ||
22617                 error "write sample ($writesample1) is wrong"
22618         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
22619                 20 * $decay_pct) / 100") -eq 1 ] ||
22620                 error "read bytes ($readbyte1) is wrong"
22621         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
22622                 15 * $decay_pct) / 100") -eq 1 ] ||
22623                 error "write bytes ($writebyte1) is wrong"
22624
22625         echo "Turn off file heat for the file $DIR/$tfile"
22626         $LFS heat_set -o $DIR/$tfile
22627
22628         echo "QQQQ" > $DIR/$tfile
22629         echo "QQQQ" > $DIR/$tfile
22630         echo "QQQQ" > $DIR/$tfile
22631         cat $DIR/$tfile > /dev/null
22632         cat $DIR/$tfile > /dev/null
22633         cat $DIR/$tfile > /dev/null
22634         cat $DIR/$tfile > /dev/null
22635
22636         out=$($LFS heat_get $DIR/$tfile)
22637         $LFS heat_get $DIR/$tfile
22638         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22639         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22640         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22641         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22642
22643         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
22644         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
22645         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
22646         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
22647
22648         echo "Trun on file heat for the file $DIR/$tfile"
22649         $LFS heat_set -O $DIR/$tfile
22650
22651         echo "QQQQ" > $DIR/$tfile
22652         echo "QQQQ" > $DIR/$tfile
22653         echo "QQQQ" > $DIR/$tfile
22654         cat $DIR/$tfile > /dev/null
22655         cat $DIR/$tfile > /dev/null
22656         cat $DIR/$tfile > /dev/null
22657         cat $DIR/$tfile > /dev/null
22658
22659         out=$($LFS heat_get $DIR/$tfile)
22660         $LFS heat_get $DIR/$tfile
22661         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22662         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22663         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22664         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22665
22666         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
22667         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
22668         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
22669         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
22670
22671         $LFS heat_set -c $DIR/$tfile
22672         $LCTL set_param -n llite.*.file_heat=0
22673         echo "Turn off file heat support for the Lustre filesystem"
22674
22675         echo "QQQQ" > $DIR/$tfile
22676         echo "QQQQ" > $DIR/$tfile
22677         echo "QQQQ" > $DIR/$tfile
22678         cat $DIR/$tfile > /dev/null
22679         cat $DIR/$tfile > /dev/null
22680         cat $DIR/$tfile > /dev/null
22681         cat $DIR/$tfile > /dev/null
22682
22683         out=$($LFS heat_get $DIR/$tfile)
22684         $LFS heat_get $DIR/$tfile
22685         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22686         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22687         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22688         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22689
22690         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
22691         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
22692         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
22693         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
22694
22695         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
22696         rm -f $DIR/$tfile
22697 }
22698 run_test 813 "File heat verfication"
22699
22700 test_814()
22701 {
22702         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
22703         echo -n y >> $DIR/$tfile
22704         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
22705         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
22706 }
22707 run_test 814 "sparse cp works as expected (LU-12361)"
22708
22709 test_815()
22710 {
22711         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
22712         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
22713 }
22714 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
22715
22716 test_816() {
22717         [ "$SHARED_KEY" = true ] &&
22718                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22719
22720         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22721         # ensure ost1 is connected
22722         stat $DIR/$tfile >/dev/null || error "can't stat"
22723         wait_osc_import_state client ost1 FULL
22724         # no locks, no reqs to let the connection idle
22725         cancel_lru_locks osc
22726         lru_resize_disable osc
22727         local before
22728         local now
22729         before=$($LCTL get_param -n \
22730                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
22731
22732         wait_osc_import_state client ost1 IDLE
22733         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
22734         now=$($LCTL get_param -n \
22735               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
22736         [ $before == $now ] || error "lru_size changed $before != $now"
22737 }
22738 run_test 816 "do not reset lru_resize on idle reconnect"
22739
22740 cleanup_817() {
22741         umount $tmpdir
22742         exportfs -u localhost:$DIR/nfsexp
22743         rm -rf $DIR/nfsexp
22744 }
22745
22746 test_817() {
22747         systemctl restart nfs-server.service || skip "failed to restart nfsd"
22748
22749         mkdir -p $DIR/nfsexp
22750         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
22751                 error "failed to export nfs"
22752
22753         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
22754         stack_trap cleanup_817 EXIT
22755
22756         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
22757                 error "failed to mount nfs to $tmpdir"
22758
22759         cp /bin/true $tmpdir
22760         $DIR/nfsexp/true || error "failed to execute 'true' command"
22761 }
22762 run_test 817 "nfsd won't cache write lock for exec file"
22763
22764 test_818() {
22765         mkdir $DIR/$tdir
22766         $LFS setstripe -c1 -i0 $DIR/$tfile
22767         $LFS setstripe -c1 -i1 $DIR/$tfile
22768         stop $SINGLEMDS
22769         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
22770         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
22771         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
22772                 error "start $SINGLEMDS failed"
22773         rm -rf $DIR/$tdir
22774 }
22775 run_test 818 "unlink with failed llog"
22776
22777 test_819a() {
22778         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22779         cancel_lru_locks osc
22780         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
22781         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
22782         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
22783         rm -f $TDIR/$tfile
22784 }
22785 run_test 819a "too big niobuf in read"
22786
22787 test_819b() {
22788         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
22789         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
22790         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22791         cancel_lru_locks osc
22792         sleep 1
22793         rm -f $TDIR/$tfile
22794 }
22795 run_test 819b "too big niobuf in write"
22796
22797 #
22798 # tests that do cleanup/setup should be run at the end
22799 #
22800
22801 test_900() {
22802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22803         local ls
22804
22805         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
22806         $LCTL set_param fail_loc=0x903
22807
22808         cancel_lru_locks MGC
22809
22810         FAIL_ON_ERROR=true cleanup
22811         FAIL_ON_ERROR=true setup
22812 }
22813 run_test 900 "umount should not race with any mgc requeue thread"
22814
22815 # LUS-6253/LU-11185
22816 test_901() {
22817         local oldc
22818         local newc
22819         local olds
22820         local news
22821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22822
22823         # some get_param have a bug to handle dot in param name
22824         cancel_lru_locks MGC
22825         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
22826         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
22827         umount_client $MOUNT || error "umount failed"
22828         mount_client $MOUNT || error "mount failed"
22829         cancel_lru_locks MGC
22830         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
22831         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
22832
22833         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
22834         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
22835
22836         return 0
22837 }
22838 run_test 901 "don't leak a mgc lock on client umount"
22839
22840 complete $SECONDS
22841 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
22842 check_and_cleanup_lustre
22843 if [ "$I_MOUNTED" != "yes" ]; then
22844         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
22845 fi
22846 exit_status