Whamcloud - gitweb
LU-12483 tests: fix sanity test 60h running conditions
[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-9096 LU-9054
45 ALWAYS_EXCEPT+=" 407     253     312 "
46
47 if $SHARED_KEY; then
48         # bug number:    LU-9795 LU-9795 LU-9795 LU-9795
49         ALWAYS_EXCEPT+=" 17n     60a     133g    300f "
50 fi
51
52 # skip the grant tests for ARM until they are fixed
53 if [[ $(uname -m) = aarch64 ]]; then
54         # bug number:    LU-11596
55         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
56         # bug number:    LU-11671 LU-11594 LU-11667 LU-11729
57         ALWAYS_EXCEPT+=" 45       103a      317      810"
58 fi
59
60 #                                  5          12          (min)"
61 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 300o"
62
63 if [ "$mds1_FSTYPE" = "zfs" ]; then
64         # bug number for skipped test: LU-1957
65         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  180"
66         #                                               13    (min)"
67         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
68 fi
69
70 # Get the SLES distro version
71 #
72 # Returns a version string that should only be used in comparing
73 # strings returned by version_code()
74 sles_version_code()
75 {
76         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
77
78         # All SuSE Linux versions have one decimal. version_code expects two
79         local sles_version=$version.0
80         version_code $sles_version
81 }
82
83 # Check if we are running on Ubuntu or SLES so we can make decisions on
84 # what tests to run
85 if [ -r /etc/SuSE-release ]; then
86         sles_version=$(sles_version_code)
87         [ $sles_version -lt $(version_code 11.4.0) ] &&
88                 # bug number for skipped test: LU-4341
89                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
90         [ $sles_version -lt $(version_code 12.0.0) ] &&
91                 # bug number for skipped test: LU-3703
92                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
93 elif [ -r /etc/os-release ]; then
94         if grep -qi ubuntu /etc/os-release; then
95                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
96                                                 -e 's/^VERSION=//p' \
97                                                 /etc/os-release |
98                                                 awk '{ print $1 }'))
99
100                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
101                         # bug number for skipped test:
102                         #                LU-10334 LU-10366
103                         ALWAYS_EXCEPT+=" 103a     410"
104                 fi
105         fi
106 fi
107
108 build_test_filter
109 FAIL_ON_ERROR=false
110
111 cleanup() {
112         echo -n "cln.."
113         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
114         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
115 }
116 setup() {
117         echo -n "mnt.."
118         load_modules
119         setupall || exit 10
120         echo "done"
121 }
122
123 check_swap_layouts_support()
124 {
125         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
126                 skip "Does not support layout lock."
127 }
128
129 check_and_setup_lustre
130 DIR=${DIR:-$MOUNT}
131 assert_DIR
132
133 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
134
135 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
136 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
137 rm -rf $DIR/[Rdfs][0-9]*
138
139 # $RUNAS_ID may get set incorrectly somewhere else
140 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
141         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
142
143 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
144
145 if [ "${ONLY}" = "MOUNT" ] ; then
146         echo "Lustre is up, please go on"
147         exit
148 fi
149
150 echo "preparing for tests involving mounts"
151 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
152 touch $EXT2_DEV
153 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
154 echo # add a newline after mke2fs.
155
156 umask 077
157
158 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
159 lctl set_param debug=-1 2> /dev/null || true
160 test_0a() {
161         touch $DIR/$tfile
162         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
163         rm $DIR/$tfile
164         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
165 }
166 run_test 0a "touch; rm ====================="
167
168 test_0b() {
169         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
170         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
171 }
172 run_test 0b "chmod 0755 $DIR ============================="
173
174 test_0c() {
175         $LCTL get_param mdc.*.import | grep "state: FULL" ||
176                 error "import not FULL"
177         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
178                 error "bad target"
179 }
180 run_test 0c "check import proc"
181
182 test_0d() { # LU-3397
183         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
184                 skip "proc exports not supported before 2.10.57"
185
186         local mgs_exp="mgs.MGS.exports"
187         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
188         local exp_client_nid
189         local exp_client_version
190         local exp_val
191         local imp_val
192         local temp_imp=$DIR/$tfile.import
193         local temp_exp=$DIR/$tfile.export
194
195         # save mgc import file to $temp_imp
196         $LCTL get_param mgc.*.import | tee $temp_imp
197         # Check if client uuid is found in MGS export
198         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
199                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
200                         $client_uuid ] &&
201                         break;
202         done
203         # save mgs export file to $temp_exp
204         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
205
206         # Compare the value of field "connect_flags"
207         imp_val=$(grep "connect_flags" $temp_imp)
208         exp_val=$(grep "connect_flags" $temp_exp)
209         [ "$exp_val" == "$imp_val" ] ||
210                 error "export flags '$exp_val' != import flags '$imp_val'"
211
212         # Compare the value of client version
213         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
214         exp_val=$(version_code $exp_client_version)
215         imp_val=$CLIENT_VERSION
216         [ "$exp_val" == "$imp_val" ] ||
217                 error "export client version '$exp_val' != '$imp_val'"
218 }
219 run_test 0d "check export proc ============================="
220
221 test_1() {
222         test_mkdir $DIR/$tdir
223         test_mkdir $DIR/$tdir/d2
224         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
225         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
226         rmdir $DIR/$tdir/d2
227         rmdir $DIR/$tdir
228         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
229 }
230 run_test 1 "mkdir; remkdir; rmdir"
231
232 test_2() {
233         test_mkdir $DIR/$tdir
234         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
235         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
236         rm -r $DIR/$tdir
237         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
238 }
239 run_test 2 "mkdir; touch; rmdir; check file"
240
241 test_3() {
242         test_mkdir $DIR/$tdir
243         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
244         touch $DIR/$tdir/$tfile
245         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
246         rm -r $DIR/$tdir
247         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
248 }
249 run_test 3 "mkdir; touch; rmdir; check dir"
250
251 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
252 test_4() {
253         test_mkdir -i 1 $DIR/$tdir
254
255         touch $DIR/$tdir/$tfile ||
256                 error "Create file under remote directory failed"
257
258         rmdir $DIR/$tdir &&
259                 error "Expect error removing in-use dir $DIR/$tdir"
260
261         test -d $DIR/$tdir || error "Remote directory disappeared"
262
263         rm -rf $DIR/$tdir || error "remove remote dir error"
264 }
265 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
266
267 test_5() {
268         test_mkdir $DIR/$tdir
269         test_mkdir $DIR/$tdir/d2
270         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
271         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
272         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
273 }
274 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
275
276 test_6a() {
277         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
278         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
279         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
280                 error "$tfile does not have perm 0666 or UID $UID"
281         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
282         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
283                 error "$tfile should be 0666 and owned by UID $UID"
284 }
285 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
286
287 test_6c() {
288         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
289
290         touch $DIR/$tfile
291         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
292         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
293                 error "$tfile should be owned by UID $RUNAS_ID"
294         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
295         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
296                 error "$tfile should be owned by UID $RUNAS_ID"
297 }
298 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
299
300 test_6e() {
301         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
302
303         touch $DIR/$tfile
304         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
305         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
306                 error "$tfile should be owned by GID $UID"
307         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
308         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
309                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
310 }
311 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
312
313 test_6g() {
314         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
315
316         test_mkdir $DIR/$tdir
317         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
318         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
319         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
320         test_mkdir $DIR/$tdir/d/subdir
321         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
322                 error "$tdir/d/subdir should be GID $RUNAS_GID"
323         if [[ $MDSCOUNT -gt 1 ]]; then
324                 # check remote dir sgid inherite
325                 $LFS mkdir -i 0 $DIR/$tdir.local ||
326                         error "mkdir $tdir.local failed"
327                 chmod g+s $DIR/$tdir.local ||
328                         error "chmod $tdir.local failed"
329                 chgrp $RUNAS_GID $DIR/$tdir.local ||
330                         error "chgrp $tdir.local failed"
331                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
332                         error "mkdir $tdir.remote failed"
333                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
334                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
335                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
336                         error "$tdir.remote should be mode 02755"
337         fi
338 }
339 run_test 6g "verify new dir in sgid dir inherits group"
340
341 test_6h() { # bug 7331
342         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
343
344         touch $DIR/$tfile || error "touch failed"
345         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
346         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
347                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
348         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
349                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
350 }
351 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
352
353 test_7a() {
354         test_mkdir $DIR/$tdir
355         $MCREATE $DIR/$tdir/$tfile
356         chmod 0666 $DIR/$tdir/$tfile
357         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
358                 error "$tdir/$tfile should be mode 0666"
359 }
360 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
361
362 test_7b() {
363         if [ ! -d $DIR/$tdir ]; then
364                 test_mkdir $DIR/$tdir
365         fi
366         $MCREATE $DIR/$tdir/$tfile
367         echo -n foo > $DIR/$tdir/$tfile
368         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
369         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
370 }
371 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
372
373 test_8() {
374         test_mkdir $DIR/$tdir
375         touch $DIR/$tdir/$tfile
376         chmod 0666 $DIR/$tdir/$tfile
377         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
378                 error "$tfile mode not 0666"
379 }
380 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
381
382 test_9() {
383         test_mkdir $DIR/$tdir
384         test_mkdir $DIR/$tdir/d2
385         test_mkdir $DIR/$tdir/d2/d3
386         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
387 }
388 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
389
390 test_10() {
391         test_mkdir $DIR/$tdir
392         test_mkdir $DIR/$tdir/d2
393         touch $DIR/$tdir/d2/$tfile
394         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
395                 error "$tdir/d2/$tfile not a file"
396 }
397 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
398
399 test_11() {
400         test_mkdir $DIR/$tdir
401         test_mkdir $DIR/$tdir/d2
402         chmod 0666 $DIR/$tdir/d2
403         chmod 0705 $DIR/$tdir/d2
404         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
405                 error "$tdir/d2 mode not 0705"
406 }
407 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
408
409 test_12() {
410         test_mkdir $DIR/$tdir
411         touch $DIR/$tdir/$tfile
412         chmod 0666 $DIR/$tdir/$tfile
413         chmod 0654 $DIR/$tdir/$tfile
414         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
415                 error "$tdir/d2 mode not 0654"
416 }
417 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
418
419 test_13() {
420         test_mkdir $DIR/$tdir
421         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
422         >  $DIR/$tdir/$tfile
423         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
424                 error "$tdir/$tfile size not 0 after truncate"
425 }
426 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
427
428 test_14() {
429         test_mkdir $DIR/$tdir
430         touch $DIR/$tdir/$tfile
431         rm $DIR/$tdir/$tfile
432         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
433 }
434 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
435
436 test_15() {
437         test_mkdir $DIR/$tdir
438         touch $DIR/$tdir/$tfile
439         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
440         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
441                 error "$tdir/${tfile_2} not a file after rename"
442         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
443 }
444 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
445
446 test_16() {
447         test_mkdir $DIR/$tdir
448         touch $DIR/$tdir/$tfile
449         rm -rf $DIR/$tdir/$tfile
450         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
451 }
452 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
453
454 test_17a() {
455         test_mkdir $DIR/$tdir
456         touch $DIR/$tdir/$tfile
457         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
458         ls -l $DIR/$tdir
459         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
460                 error "$tdir/l-exist not a symlink"
461         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
462                 error "$tdir/l-exist not referencing a file"
463         rm -f $DIR/$tdir/l-exist
464         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
465 }
466 run_test 17a "symlinks: create, remove (real)"
467
468 test_17b() {
469         test_mkdir $DIR/$tdir
470         ln -s no-such-file $DIR/$tdir/l-dangle
471         ls -l $DIR/$tdir
472         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
473                 error "$tdir/l-dangle not referencing no-such-file"
474         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
475                 error "$tdir/l-dangle not referencing non-existent file"
476         rm -f $DIR/$tdir/l-dangle
477         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
478 }
479 run_test 17b "symlinks: create, remove (dangling)"
480
481 test_17c() { # bug 3440 - don't save failed open RPC for replay
482         test_mkdir $DIR/$tdir
483         ln -s foo $DIR/$tdir/$tfile
484         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
485 }
486 run_test 17c "symlinks: open dangling (should return error)"
487
488 test_17d() {
489         test_mkdir $DIR/$tdir
490         ln -s foo $DIR/$tdir/$tfile
491         touch $DIR/$tdir/$tfile || error "creating to new symlink"
492 }
493 run_test 17d "symlinks: create dangling"
494
495 test_17e() {
496         test_mkdir $DIR/$tdir
497         local foo=$DIR/$tdir/$tfile
498         ln -s $foo $foo || error "create symlink failed"
499         ls -l $foo || error "ls -l failed"
500         ls $foo && error "ls not failed" || true
501 }
502 run_test 17e "symlinks: create recursive symlink (should return error)"
503
504 test_17f() {
505         test_mkdir $DIR/$tdir
506         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
507         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
508         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
509         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
510         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
511         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
512         ls -l  $DIR/$tdir
513 }
514 run_test 17f "symlinks: long and very long symlink name"
515
516 # str_repeat(S, N) generate a string that is string S repeated N times
517 str_repeat() {
518         local s=$1
519         local n=$2
520         local ret=''
521         while [ $((n -= 1)) -ge 0 ]; do
522                 ret=$ret$s
523         done
524         echo $ret
525 }
526
527 # Long symlinks and LU-2241
528 test_17g() {
529         test_mkdir $DIR/$tdir
530         local TESTS="59 60 61 4094 4095"
531
532         # Fix for inode size boundary in 2.1.4
533         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
534                 TESTS="4094 4095"
535
536         # Patch not applied to 2.2 or 2.3 branches
537         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
538         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
539                 TESTS="4094 4095"
540
541         # skip long symlink name for rhel6.5.
542         # rhel6.5 has a limit (PATH_MAX - sizeof(struct filename))
543         grep -q '6.5' /etc/redhat-release &>/dev/null &&
544                 TESTS="59 60 61 4062 4063"
545
546         for i in $TESTS; do
547                 local SYMNAME=$(str_repeat 'x' $i)
548                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
549                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
550         done
551 }
552 run_test 17g "symlinks: really long symlink name and inode boundaries"
553
554 test_17h() { #bug 17378
555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
556         remote_mds_nodsh && skip "remote MDS with nodsh"
557
558         local mdt_idx
559
560         test_mkdir $DIR/$tdir
561         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
562         $LFS setstripe -c -1 $DIR/$tdir
563         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
564         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
565         touch $DIR/$tdir/$tfile || true
566 }
567 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
568
569 test_17i() { #bug 20018
570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
571         remote_mds_nodsh && skip "remote MDS with nodsh"
572
573         local foo=$DIR/$tdir/$tfile
574         local mdt_idx
575
576         test_mkdir -c1 $DIR/$tdir
577         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
578         ln -s $foo $foo || error "create symlink failed"
579 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
580         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
581         ls -l $foo && error "error not detected"
582         return 0
583 }
584 run_test 17i "don't panic on short symlink (should return error)"
585
586 test_17k() { #bug 22301
587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
588         [[ -z "$(which rsync 2>/dev/null)" ]] &&
589                 skip "no rsync command"
590         rsync --help | grep -q xattr ||
591                 skip_env "$(rsync --version | head -n1) does not support xattrs"
592         test_mkdir $DIR/$tdir
593         test_mkdir $DIR/$tdir.new
594         touch $DIR/$tdir/$tfile
595         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
596         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
597                 error "rsync failed with xattrs enabled"
598 }
599 run_test 17k "symlinks: rsync with xattrs enabled"
600
601 test_17l() { # LU-279
602         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
603                 skip "no getfattr command"
604
605         test_mkdir $DIR/$tdir
606         touch $DIR/$tdir/$tfile
607         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
608         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
609                 # -h to not follow symlinks. -m '' to list all the xattrs.
610                 # grep to remove first line: '# file: $path'.
611                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
612                 do
613                         lgetxattr_size_check $path $xattr ||
614                                 error "lgetxattr_size_check $path $xattr failed"
615                 done
616         done
617 }
618 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
619
620 # LU-1540
621 test_17m() {
622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
623         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
624         remote_mds_nodsh && skip "remote MDS with nodsh"
625         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
626         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
627                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
628
629         local short_sym="0123456789"
630         local wdir=$DIR/$tdir
631         local i
632
633         test_mkdir $wdir
634         long_sym=$short_sym
635         # create a long symlink file
636         for ((i = 0; i < 4; ++i)); do
637                 long_sym=${long_sym}${long_sym}
638         done
639
640         echo "create 512 short and long symlink files under $wdir"
641         for ((i = 0; i < 256; ++i)); do
642                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
643                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
644         done
645
646         echo "erase them"
647         rm -f $wdir/*
648         sync
649         wait_delete_completed
650
651         echo "recreate the 512 symlink files with a shorter string"
652         for ((i = 0; i < 512; ++i)); do
653                 # rewrite the symlink file with a shorter string
654                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
655                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
656         done
657
658         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
659         local devname=$(mdsdevname $mds_index)
660
661         echo "stop and checking mds${mds_index}:"
662         # e2fsck should not return error
663         stop mds${mds_index}
664         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
665         rc=$?
666
667         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
668                 error "start mds${mds_index} failed"
669         df $MOUNT > /dev/null 2>&1
670         [ $rc -eq 0 ] ||
671                 error "e2fsck detected error for short/long symlink: rc=$rc"
672         rm -f $wdir/*
673 }
674 run_test 17m "run e2fsck against MDT which contains short/long symlink"
675
676 check_fs_consistency_17n() {
677         local mdt_index
678         local rc=0
679
680         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
681         # so it only check MDT1/MDT2 instead of all of MDTs.
682         for mdt_index in 1 2; do
683                 local devname=$(mdsdevname $mdt_index)
684                 # e2fsck should not return error
685                 stop mds${mdt_index}
686                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
687                         rc=$((rc + $?))
688
689                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
690                         error "mount mds$mdt_index failed"
691                 df $MOUNT > /dev/null 2>&1
692         done
693         return $rc
694 }
695
696 test_17n() {
697         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
699         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
700         remote_mds_nodsh && skip "remote MDS with nodsh"
701         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
702         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
703                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
704
705         local i
706
707         test_mkdir $DIR/$tdir
708         for ((i=0; i<10; i++)); do
709                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
710                         error "create remote dir error $i"
711                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
712                         error "create files under remote dir failed $i"
713         done
714
715         check_fs_consistency_17n ||
716                 error "e2fsck report error after create files under remote dir"
717
718         for ((i = 0; i < 10; i++)); do
719                 rm -rf $DIR/$tdir/remote_dir_${i} ||
720                         error "destroy remote dir error $i"
721         done
722
723         check_fs_consistency_17n ||
724                 error "e2fsck report error after unlink files under remote dir"
725
726         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
727                 skip "lustre < 2.4.50 does not support migrate mv"
728
729         for ((i = 0; i < 10; i++)); do
730                 mkdir -p $DIR/$tdir/remote_dir_${i}
731                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
732                         error "create files under remote dir failed $i"
733                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
734                         error "migrate remote dir error $i"
735         done
736         check_fs_consistency_17n || error "e2fsck report error after migration"
737
738         for ((i = 0; i < 10; i++)); do
739                 rm -rf $DIR/$tdir/remote_dir_${i} ||
740                         error "destroy remote dir error $i"
741         done
742
743         check_fs_consistency_17n || error "e2fsck report error after unlink"
744 }
745 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
746
747 test_17o() {
748         remote_mds_nodsh && skip "remote MDS with nodsh"
749         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
750                 skip "Need MDS version at least 2.3.64"
751
752         local wdir=$DIR/${tdir}o
753         local mdt_index
754         local rc=0
755
756         test_mkdir $wdir
757         touch $wdir/$tfile
758         mdt_index=$($LFS getstripe -m $wdir/$tfile)
759         mdt_index=$((mdt_index + 1))
760
761         cancel_lru_locks mdc
762         #fail mds will wait the failover finish then set
763         #following fail_loc to avoid interfer the recovery process.
764         fail mds${mdt_index}
765
766         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
767         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
768         ls -l $wdir/$tfile && rc=1
769         do_facet mds${mdt_index} lctl set_param fail_loc=0
770         [[ $rc -eq 0 ]] || error "stat file should fail"
771 }
772 run_test 17o "stat file with incompat LMA feature"
773
774 test_18() {
775         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
776         ls $DIR || error "Failed to ls $DIR: $?"
777 }
778 run_test 18 "touch .../f ; ls ... =============================="
779
780 test_19a() {
781         touch $DIR/$tfile
782         ls -l $DIR
783         rm $DIR/$tfile
784         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
785 }
786 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
787
788 test_19b() {
789         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
790 }
791 run_test 19b "ls -l .../f19 (should return error) =============="
792
793 test_19c() {
794         [ $RUNAS_ID -eq $UID ] &&
795                 skip_env "RUNAS_ID = UID = $UID -- skipping"
796
797         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
798 }
799 run_test 19c "$RUNAS touch .../f19 (should return error) =="
800
801 test_19d() {
802         cat $DIR/f19 && error || true
803 }
804 run_test 19d "cat .../f19 (should return error) =============="
805
806 test_20() {
807         touch $DIR/$tfile
808         rm $DIR/$tfile
809         touch $DIR/$tfile
810         rm $DIR/$tfile
811         touch $DIR/$tfile
812         rm $DIR/$tfile
813         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
814 }
815 run_test 20 "touch .../f ; ls -l ..."
816
817 test_21() {
818         test_mkdir $DIR/$tdir
819         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
820         ln -s dangle $DIR/$tdir/link
821         echo foo >> $DIR/$tdir/link
822         cat $DIR/$tdir/dangle
823         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
824         $CHECKSTAT -f -t file $DIR/$tdir/link ||
825                 error "$tdir/link not linked to a file"
826 }
827 run_test 21 "write to dangling link"
828
829 test_22() {
830         local wdir=$DIR/$tdir
831         test_mkdir $wdir
832         chown $RUNAS_ID:$RUNAS_GID $wdir
833         (cd $wdir || error "cd $wdir failed";
834                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
835                 $RUNAS tar xf -)
836         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
837         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
838         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
839                 error "checkstat -u failed"
840 }
841 run_test 22 "unpack tar archive as non-root user"
842
843 # was test_23
844 test_23a() {
845         test_mkdir $DIR/$tdir
846         local file=$DIR/$tdir/$tfile
847
848         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
849         openfile -f O_CREAT:O_EXCL $file &&
850                 error "$file recreate succeeded" || true
851 }
852 run_test 23a "O_CREAT|O_EXCL in subdir"
853
854 test_23b() { # bug 18988
855         test_mkdir $DIR/$tdir
856         local file=$DIR/$tdir/$tfile
857
858         rm -f $file
859         echo foo > $file || error "write filed"
860         echo bar >> $file || error "append filed"
861         $CHECKSTAT -s 8 $file || error "wrong size"
862         rm $file
863 }
864 run_test 23b "O_APPEND check"
865
866 # LU-9409, size with O_APPEND and tiny writes
867 test_23c() {
868         local file=$DIR/$tfile
869
870         # single dd
871         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
872         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
873         rm -f $file
874
875         # racing tiny writes
876         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
877         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
878         wait
879         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
880         rm -f $file
881
882         #racing tiny & normal writes
883         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
884         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
885         wait
886         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
887         rm -f $file
888
889         #racing tiny & normal writes 2, ugly numbers
890         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
891         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
892         wait
893         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
894         rm -f $file
895 }
896 run_test 23c "O_APPEND size checks for tiny writes"
897
898 # LU-11069 file offset is correct after appending writes
899 test_23d() {
900         local file=$DIR/$tfile
901         local offset
902
903         echo CentaurHauls > $file
904         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
905         if ((offset != 26)); then
906                 error "wrong offset, expected 26, got '$offset'"
907         fi
908 }
909 run_test 23d "file offset is correct after appending writes"
910
911 # rename sanity
912 test_24a() {
913         echo '-- same directory rename'
914         test_mkdir $DIR/$tdir
915         touch $DIR/$tdir/$tfile.1
916         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
917         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
918 }
919 run_test 24a "rename file to non-existent target"
920
921 test_24b() {
922         test_mkdir $DIR/$tdir
923         touch $DIR/$tdir/$tfile.{1,2}
924         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
925         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
926         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
927 }
928 run_test 24b "rename file to existing target"
929
930 test_24c() {
931         test_mkdir $DIR/$tdir
932         test_mkdir $DIR/$tdir/d$testnum.1
933         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
934         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
935         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
936 }
937 run_test 24c "rename directory to non-existent target"
938
939 test_24d() {
940         test_mkdir -c1 $DIR/$tdir
941         test_mkdir -c1 $DIR/$tdir/d$testnum.1
942         test_mkdir -c1 $DIR/$tdir/d$testnum.2
943         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
944         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
945         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
946 }
947 run_test 24d "rename directory to existing target"
948
949 test_24e() {
950         echo '-- cross directory renames --'
951         test_mkdir $DIR/R5a
952         test_mkdir $DIR/R5b
953         touch $DIR/R5a/f
954         mv $DIR/R5a/f $DIR/R5b/g
955         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
956         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
957 }
958 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
959
960 test_24f() {
961         test_mkdir $DIR/R6a
962         test_mkdir $DIR/R6b
963         touch $DIR/R6a/f $DIR/R6b/g
964         mv $DIR/R6a/f $DIR/R6b/g
965         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
966         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
967 }
968 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
969
970 test_24g() {
971         test_mkdir $DIR/R7a
972         test_mkdir $DIR/R7b
973         test_mkdir $DIR/R7a/d
974         mv $DIR/R7a/d $DIR/R7b/e
975         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
976         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
977 }
978 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
979
980 test_24h() {
981         test_mkdir -c1 $DIR/R8a
982         test_mkdir -c1 $DIR/R8b
983         test_mkdir -c1 $DIR/R8a/d
984         test_mkdir -c1 $DIR/R8b/e
985         mrename $DIR/R8a/d $DIR/R8b/e
986         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
987         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
988 }
989 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
990
991 test_24i() {
992         echo "-- rename error cases"
993         test_mkdir $DIR/R9
994         test_mkdir $DIR/R9/a
995         touch $DIR/R9/f
996         mrename $DIR/R9/f $DIR/R9/a
997         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
998         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
999         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1000 }
1001 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1002
1003 test_24j() {
1004         test_mkdir $DIR/R10
1005         mrename $DIR/R10/f $DIR/R10/g
1006         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1007         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1008         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1009 }
1010 run_test 24j "source does not exist ============================"
1011
1012 test_24k() {
1013         test_mkdir $DIR/R11a
1014         test_mkdir $DIR/R11a/d
1015         touch $DIR/R11a/f
1016         mv $DIR/R11a/f $DIR/R11a/d
1017         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1018         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1019 }
1020 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1021
1022 # bug 2429 - rename foo foo foo creates invalid file
1023 test_24l() {
1024         f="$DIR/f24l"
1025         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1026 }
1027 run_test 24l "Renaming a file to itself ========================"
1028
1029 test_24m() {
1030         f="$DIR/f24m"
1031         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1032         # on ext3 this does not remove either the source or target files
1033         # though the "expected" operation would be to remove the source
1034         $CHECKSTAT -t file ${f} || error "${f} missing"
1035         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1036 }
1037 run_test 24m "Renaming a file to a hard link to itself ========="
1038
1039 test_24n() {
1040     f="$DIR/f24n"
1041     # this stats the old file after it was renamed, so it should fail
1042     touch ${f}
1043     $CHECKSTAT ${f} || error "${f} missing"
1044     mv ${f} ${f}.rename
1045     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1046     $CHECKSTAT -a ${f} || error "${f} exists"
1047 }
1048 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1049
1050 test_24o() {
1051         test_mkdir $DIR/$tdir
1052         rename_many -s random -v -n 10 $DIR/$tdir
1053 }
1054 run_test 24o "rename of files during htree split"
1055
1056 test_24p() {
1057         test_mkdir $DIR/R12a
1058         test_mkdir $DIR/R12b
1059         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1060         mrename $DIR/R12a $DIR/R12b
1061         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1062         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1063         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1064         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1065 }
1066 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1067
1068 cleanup_multiop_pause() {
1069         trap 0
1070         kill -USR1 $MULTIPID
1071 }
1072
1073 test_24q() {
1074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1075
1076         test_mkdir $DIR/R13a
1077         test_mkdir $DIR/R13b
1078         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1079         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1080         MULTIPID=$!
1081
1082         trap cleanup_multiop_pause EXIT
1083         mrename $DIR/R13a $DIR/R13b
1084         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1085         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1086         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1087         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1088         cleanup_multiop_pause
1089         wait $MULTIPID || error "multiop close failed"
1090 }
1091 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1092
1093 test_24r() { #bug 3789
1094         test_mkdir $DIR/R14a
1095         test_mkdir $DIR/R14a/b
1096         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1097         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1098         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1099 }
1100 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1101
1102 test_24s() {
1103         test_mkdir $DIR/R15a
1104         test_mkdir $DIR/R15a/b
1105         test_mkdir $DIR/R15a/b/c
1106         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1107         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1108         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1109 }
1110 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1111 test_24t() {
1112         test_mkdir $DIR/R16a
1113         test_mkdir $DIR/R16a/b
1114         test_mkdir $DIR/R16a/b/c
1115         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1116         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1117         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1118 }
1119 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1120
1121 test_24u() { # bug12192
1122         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1123         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1124 }
1125 run_test 24u "create stripe file"
1126
1127 simple_cleanup_common() {
1128         local rc=0
1129         trap 0
1130         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1131
1132         local start=$SECONDS
1133         rm -rf $DIR/$tdir
1134         rc=$?
1135         wait_delete_completed
1136         echo "cleanup time $((SECONDS - start))"
1137         return $rc
1138 }
1139
1140 max_pages_per_rpc() {
1141         local mdtname="$(printf "MDT%04x" ${1:-0})"
1142         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1143 }
1144
1145 test_24v() {
1146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1147
1148         local nrfiles=${COUNT:-100000}
1149         local fname="$DIR/$tdir/$tfile"
1150
1151         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1152         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1153
1154         test_mkdir "$(dirname $fname)"
1155         # assume MDT0000 has the fewest inodes
1156         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1157         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1158         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1159
1160         trap simple_cleanup_common EXIT
1161
1162         createmany -m "$fname" $nrfiles
1163
1164         cancel_lru_locks mdc
1165         lctl set_param mdc.*.stats clear
1166
1167         # was previously test_24D: LU-6101
1168         # readdir() returns correct number of entries after cursor reload
1169         local num_ls=$(ls $DIR/$tdir | wc -l)
1170         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1171         local num_all=$(ls -a $DIR/$tdir | wc -l)
1172         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1173                 [ $num_all -ne $((nrfiles + 2)) ]; then
1174                         error "Expected $nrfiles files, got $num_ls " \
1175                                 "($num_uniq unique $num_all .&..)"
1176         fi
1177         # LU-5 large readdir
1178         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1179         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1180         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1181         # take into account of overhead in lu_dirpage header and end mark in
1182         # each page, plus one in rpc_num calculation.
1183         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1184         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1185         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1186         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1187         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1188         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1189         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1190         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1191                 error "large readdir doesn't take effect: " \
1192                       "$mds_readpage should be about $rpc_max"
1193
1194         simple_cleanup_common
1195 }
1196 run_test 24v "list large directory (test hash collision, b=17560)"
1197
1198 test_24w() { # bug21506
1199         SZ1=234852
1200         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1201         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1202         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1203         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1204         [[ "$SZ1" -eq "$SZ2" ]] ||
1205                 error "Error reading at the end of the file $tfile"
1206 }
1207 run_test 24w "Reading a file larger than 4Gb"
1208
1209 test_24x() {
1210         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1212         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1213                 skip "Need MDS version at least 2.7.56"
1214
1215         local MDTIDX=1
1216         local remote_dir=$DIR/$tdir/remote_dir
1217
1218         test_mkdir $DIR/$tdir
1219         $LFS mkdir -i $MDTIDX $remote_dir ||
1220                 error "create remote directory failed"
1221
1222         test_mkdir $DIR/$tdir/src_dir
1223         touch $DIR/$tdir/src_file
1224         test_mkdir $remote_dir/tgt_dir
1225         touch $remote_dir/tgt_file
1226
1227         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1228                 error "rename dir cross MDT failed!"
1229
1230         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1231                 error "rename file cross MDT failed!"
1232
1233         touch $DIR/$tdir/ln_file
1234         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1235                 error "ln file cross MDT failed"
1236
1237         rm -rf $DIR/$tdir || error "Can not delete directories"
1238 }
1239 run_test 24x "cross MDT rename/link"
1240
1241 test_24y() {
1242         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1244
1245         local remote_dir=$DIR/$tdir/remote_dir
1246         local mdtidx=1
1247
1248         test_mkdir $DIR/$tdir
1249         $LFS mkdir -i $mdtidx $remote_dir ||
1250                 error "create remote directory failed"
1251
1252         test_mkdir $remote_dir/src_dir
1253         touch $remote_dir/src_file
1254         test_mkdir $remote_dir/tgt_dir
1255         touch $remote_dir/tgt_file
1256
1257         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1258                 error "rename subdir in the same remote dir failed!"
1259
1260         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1261                 error "rename files in the same remote dir failed!"
1262
1263         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1264                 error "link files in the same remote dir failed!"
1265
1266         rm -rf $DIR/$tdir || error "Can not delete directories"
1267 }
1268 run_test 24y "rename/link on the same dir should succeed"
1269
1270 test_24z() {
1271         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1272         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1273                 skip "Need MDS version at least 2.12.51"
1274
1275         local index
1276
1277         for index in 0 1; do
1278                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1279                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1280         done
1281
1282         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1283
1284         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1285         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1286
1287         local mdts=$(comma_list $(mdts_nodes))
1288
1289         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1290         stack_trap "do_nodes $mdts $LCTL \
1291                 set_param mdt.*.enable_remote_rename=1" EXIT
1292
1293         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1294
1295         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1296         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1297 }
1298 run_test 24z "cross-MDT rename is done as cp"
1299
1300 test_24A() { # LU-3182
1301         local NFILES=5000
1302
1303         rm -rf $DIR/$tdir
1304         test_mkdir $DIR/$tdir
1305         trap simple_cleanup_common EXIT
1306         createmany -m $DIR/$tdir/$tfile $NFILES
1307         local t=$(ls $DIR/$tdir | wc -l)
1308         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1309         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1310         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1311            [ $v -ne $((NFILES + 2)) ] ; then
1312                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1313         fi
1314
1315         simple_cleanup_common || error "Can not delete directories"
1316 }
1317 run_test 24A "readdir() returns correct number of entries."
1318
1319 test_24B() { # LU-4805
1320         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1321
1322         local count
1323
1324         test_mkdir $DIR/$tdir
1325         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1326                 error "create striped dir failed"
1327
1328         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1329         [ $count -eq 2 ] || error "Expected 2, got $count"
1330
1331         touch $DIR/$tdir/striped_dir/a
1332
1333         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1334         [ $count -eq 3 ] || error "Expected 3, got $count"
1335
1336         touch $DIR/$tdir/striped_dir/.f
1337
1338         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1339         [ $count -eq 4 ] || error "Expected 4, got $count"
1340
1341         rm -rf $DIR/$tdir || error "Can not delete directories"
1342 }
1343 run_test 24B "readdir for striped dir return correct number of entries"
1344
1345 test_24C() {
1346         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1347
1348         mkdir $DIR/$tdir
1349         mkdir $DIR/$tdir/d0
1350         mkdir $DIR/$tdir/d1
1351
1352         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1353                 error "create striped dir failed"
1354
1355         cd $DIR/$tdir/d0/striped_dir
1356
1357         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1358         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1359         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1360
1361         [ "$d0_ino" = "$parent_ino" ] ||
1362                 error ".. wrong, expect $d0_ino, get $parent_ino"
1363
1364         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1365                 error "mv striped dir failed"
1366
1367         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1368
1369         [ "$d1_ino" = "$parent_ino" ] ||
1370                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1371 }
1372 run_test 24C "check .. in striped dir"
1373
1374 test_24E() {
1375         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1377
1378         mkdir -p $DIR/$tdir
1379         mkdir $DIR/$tdir/src_dir
1380         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1381                 error "create remote source failed"
1382
1383         touch $DIR/$tdir/src_dir/src_child/a
1384
1385         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1386                 error "create remote target dir failed"
1387
1388         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1389                 error "create remote target child failed"
1390
1391         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1392                 error "rename dir cross MDT failed!"
1393
1394         find $DIR/$tdir
1395
1396         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1397                 error "src_child still exists after rename"
1398
1399         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1400                 error "missing file(a) after rename"
1401
1402         rm -rf $DIR/$tdir || error "Can not delete directories"
1403 }
1404 run_test 24E "cross MDT rename/link"
1405
1406 test_24F () {
1407         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1408
1409         local repeats=1000
1410         [ "$SLOW" = "no" ] && repeats=100
1411
1412         mkdir -p $DIR/$tdir
1413
1414         echo "$repeats repeats"
1415         for ((i = 0; i < repeats; i++)); do
1416                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1417                 touch $DIR/$tdir/test/a || error "touch fails"
1418                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1419                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1420         done
1421
1422         true
1423 }
1424 run_test 24F "hash order vs readdir (LU-11330)"
1425
1426 test_25a() {
1427         echo '== symlink sanity ============================================='
1428
1429         test_mkdir $DIR/d25
1430         ln -s d25 $DIR/s25
1431         touch $DIR/s25/foo ||
1432                 error "File creation in symlinked directory failed"
1433 }
1434 run_test 25a "create file in symlinked directory ==============="
1435
1436 test_25b() {
1437         [ ! -d $DIR/d25 ] && test_25a
1438         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1439 }
1440 run_test 25b "lookup file in symlinked directory ==============="
1441
1442 test_26a() {
1443         test_mkdir $DIR/d26
1444         test_mkdir $DIR/d26/d26-2
1445         ln -s d26/d26-2 $DIR/s26
1446         touch $DIR/s26/foo || error "File creation failed"
1447 }
1448 run_test 26a "multiple component symlink ======================="
1449
1450 test_26b() {
1451         test_mkdir -p $DIR/$tdir/d26-2
1452         ln -s $tdir/d26-2/foo $DIR/s26-2
1453         touch $DIR/s26-2 || error "File creation failed"
1454 }
1455 run_test 26b "multiple component symlink at end of lookup ======"
1456
1457 test_26c() {
1458         test_mkdir $DIR/d26.2
1459         touch $DIR/d26.2/foo
1460         ln -s d26.2 $DIR/s26.2-1
1461         ln -s s26.2-1 $DIR/s26.2-2
1462         ln -s s26.2-2 $DIR/s26.2-3
1463         chmod 0666 $DIR/s26.2-3/foo
1464 }
1465 run_test 26c "chain of symlinks"
1466
1467 # recursive symlinks (bug 439)
1468 test_26d() {
1469         ln -s d26-3/foo $DIR/d26-3
1470 }
1471 run_test 26d "create multiple component recursive symlink"
1472
1473 test_26e() {
1474         [ ! -h $DIR/d26-3 ] && test_26d
1475         rm $DIR/d26-3
1476 }
1477 run_test 26e "unlink multiple component recursive symlink"
1478
1479 # recursive symlinks (bug 7022)
1480 test_26f() {
1481         test_mkdir $DIR/$tdir
1482         test_mkdir $DIR/$tdir/$tfile
1483         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1484         test_mkdir -p lndir/bar1
1485         test_mkdir $DIR/$tdir/$tfile/$tfile
1486         cd $tfile                || error "cd $tfile failed"
1487         ln -s .. dotdot          || error "ln dotdot failed"
1488         ln -s dotdot/lndir lndir || error "ln lndir failed"
1489         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1490         output=`ls $tfile/$tfile/lndir/bar1`
1491         [ "$output" = bar1 ] && error "unexpected output"
1492         rm -r $tfile             || error "rm $tfile failed"
1493         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1494 }
1495 run_test 26f "rm -r of a directory which has recursive symlink"
1496
1497 test_27a() {
1498         test_mkdir $DIR/$tdir
1499         $LFS getstripe $DIR/$tdir
1500         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1501         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1502         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1503 }
1504 run_test 27a "one stripe file"
1505
1506 test_27b() {
1507         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1508
1509         test_mkdir $DIR/$tdir
1510         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1511         $LFS getstripe -c $DIR/$tdir/$tfile
1512         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1513                 error "two-stripe file doesn't have two stripes"
1514
1515         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1516 }
1517 run_test 27b "create and write to two stripe file"
1518
1519 # 27c family tests specific striping, setstripe -o
1520 test_27ca() {
1521         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1522         test_mkdir -p $DIR/$tdir
1523         local osts="1"
1524
1525         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1526         $LFS getstripe -i $DIR/$tdir/$tfile
1527         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1528                 error "stripe not on specified OST"
1529
1530         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1531 }
1532 run_test 27ca "one stripe on specified OST"
1533
1534 test_27cb() {
1535         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1536         test_mkdir -p $DIR/$tdir
1537         local osts="1,0"
1538         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1539         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1540         echo "$getstripe"
1541
1542         # Strip getstripe output to a space separated list of OSTs
1543         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1544                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1545         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1546                 error "stripes not on specified OSTs"
1547
1548         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1549 }
1550 run_test 27cb "two stripes on specified OSTs"
1551
1552 test_27cc() {
1553         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1554         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1555                 skip "server does not support overstriping"
1556
1557         test_mkdir -p $DIR/$tdir
1558         local osts="0,0"
1559         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1560         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1561         echo "$getstripe"
1562
1563         # Strip getstripe output to a space separated list of OSTs
1564         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1565                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1566         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1567                 error "stripes not on specified OSTs"
1568
1569         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1570 }
1571 run_test 27cc "two stripes on the same OST"
1572
1573 test_27cd() {
1574         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1575         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1576                 skip "server does not support overstriping"
1577         test_mkdir -p $DIR/$tdir
1578         local osts="0,1,1,0"
1579         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1580         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1581         echo "$getstripe"
1582
1583         # Strip getstripe output to a space separated list of OSTs
1584         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1585                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1586         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1587                 error "stripes not on specified OSTs"
1588
1589         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1590 }
1591 run_test 27cd "four stripes on two OSTs"
1592
1593 test_27ce() {
1594         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1595                 skip_env "too many osts, skipping"
1596         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1597                 skip "server does not support overstriping"
1598         # We do one more stripe than we have OSTs
1599         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1600                 skip_env "ea_inode feature disabled"
1601
1602         test_mkdir -p $DIR/$tdir
1603         local osts=""
1604         for i in $(seq 0 $OSTCOUNT);
1605         do
1606                 osts=$osts"0"
1607                 if [ $i -ne $OSTCOUNT ]; then
1608                         osts=$osts","
1609                 fi
1610         done
1611         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1612         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1613         echo "$getstripe"
1614
1615         # Strip getstripe output to a space separated list of OSTs
1616         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1617                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1618         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1619                 error "stripes not on specified OSTs"
1620
1621         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1622 }
1623 run_test 27ce "more stripes than OSTs with -o"
1624
1625 test_27d() {
1626         test_mkdir $DIR/$tdir
1627         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1628                 error "setstripe failed"
1629         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1630         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1631 }
1632 run_test 27d "create file with default settings"
1633
1634 test_27e() {
1635         # LU-5839 adds check for existed layout before setting it
1636         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1637                 skip "Need MDS version at least 2.7.56"
1638
1639         test_mkdir $DIR/$tdir
1640         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1641         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1642         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1643 }
1644 run_test 27e "setstripe existing file (should return error)"
1645
1646 test_27f() {
1647         test_mkdir $DIR/$tdir
1648         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1649                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1650         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1651                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1652         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1653         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1654 }
1655 run_test 27f "setstripe with bad stripe size (should return error)"
1656
1657 test_27g() {
1658         test_mkdir $DIR/$tdir
1659         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1660         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1661                 error "$DIR/$tdir/$tfile has object"
1662 }
1663 run_test 27g "$LFS getstripe with no objects"
1664
1665 test_27ga() {
1666         test_mkdir $DIR/$tdir
1667         touch $DIR/$tdir/$tfile || error "touch failed"
1668         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1669         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1670         local rc=$?
1671         (( rc == 2 )) || error "getstripe did not return ENOENT"
1672 }
1673 run_test 27ga "$LFS getstripe with missing file (should return error)"
1674
1675 test_27i() {
1676         test_mkdir $DIR/$tdir
1677         touch $DIR/$tdir/$tfile || error "touch failed"
1678         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1679                 error "missing objects"
1680 }
1681 run_test 27i "$LFS getstripe with some objects"
1682
1683 test_27j() {
1684         test_mkdir $DIR/$tdir
1685         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1686                 error "setstripe failed" || true
1687 }
1688 run_test 27j "setstripe with bad stripe offset (should return error)"
1689
1690 test_27k() { # bug 2844
1691         test_mkdir $DIR/$tdir
1692         local file=$DIR/$tdir/$tfile
1693         local ll_max_blksize=$((4 * 1024 * 1024))
1694         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1695         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1696         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1697         dd if=/dev/zero of=$file bs=4k count=1
1698         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1699         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1700 }
1701 run_test 27k "limit i_blksize for broken user apps"
1702
1703 test_27l() {
1704         mcreate $DIR/$tfile || error "creating file"
1705         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1706                 error "setstripe should have failed" || true
1707 }
1708 run_test 27l "check setstripe permissions (should return error)"
1709
1710 test_27m() {
1711         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1712
1713         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1714                 skip_env "multiple clients -- skipping"
1715
1716         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1717                    head -n1)
1718         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1719                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1720         fi
1721         trap simple_cleanup_common EXIT
1722         test_mkdir $DIR/$tdir
1723         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1724         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1725                 error "dd should fill OST0"
1726         i=2
1727         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1728                 i=$((i + 1))
1729                 [ $i -gt 256 ] && break
1730         done
1731         i=$((i + 1))
1732         touch $DIR/$tdir/$tfile.$i
1733         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1734             awk '{print $1}'| grep -w "0") ] &&
1735                 error "OST0 was full but new created file still use it"
1736         i=$((i + 1))
1737         touch $DIR/$tdir/$tfile.$i
1738         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1739             awk '{print $1}'| grep -w "0") ] &&
1740                 error "OST0 was full but new created file still use it"
1741         simple_cleanup_common
1742 }
1743 run_test 27m "create file while OST0 was full"
1744
1745 sleep_maxage() {
1746         local delay=$(do_facet $SINGLEMDS lctl get_param -n lo[vd].*.qos_maxage |
1747                       awk '{ print $1 * 2; exit; }')
1748         sleep $delay
1749 }
1750
1751 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1752 # if the OST isn't full anymore.
1753 reset_enospc() {
1754         local OSTIDX=${1:-""}
1755
1756         local list=$(comma_list $(osts_nodes))
1757         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1758
1759         do_nodes $list lctl set_param fail_loc=0
1760         sync    # initiate all OST_DESTROYs from MDS to OST
1761         sleep_maxage
1762 }
1763
1764 exhaust_precreations() {
1765         local OSTIDX=$1
1766         local FAILLOC=$2
1767         local FAILIDX=${3:-$OSTIDX}
1768         local ofacet=ost$((OSTIDX + 1))
1769
1770         test_mkdir -p -c1 $DIR/$tdir
1771         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1772         local mfacet=mds$((mdtidx + 1))
1773         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1774
1775         local OST=$(ostname_from_index $OSTIDX)
1776
1777         # on the mdt's osc
1778         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1779         local last_id=$(do_facet $mfacet lctl get_param -n \
1780                         osp.$mdtosc_proc1.prealloc_last_id)
1781         local next_id=$(do_facet $mfacet lctl get_param -n \
1782                         osp.$mdtosc_proc1.prealloc_next_id)
1783
1784         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1785         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1786
1787         test_mkdir -p $DIR/$tdir/${OST}
1788         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1789 #define OBD_FAIL_OST_ENOSPC              0x215
1790         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1791         echo "Creating to objid $last_id on ost $OST..."
1792         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1793         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1794         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1795         sleep_maxage
1796 }
1797
1798 exhaust_all_precreations() {
1799         local i
1800         for (( i=0; i < OSTCOUNT; i++ )) ; do
1801                 exhaust_precreations $i $1 -1
1802         done
1803 }
1804
1805 test_27n() {
1806         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1808         remote_mds_nodsh && skip "remote MDS with nodsh"
1809         remote_ost_nodsh && skip "remote OST with nodsh"
1810
1811         reset_enospc
1812         rm -f $DIR/$tdir/$tfile
1813         exhaust_precreations 0 0x80000215
1814         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1815         touch $DIR/$tdir/$tfile || error "touch failed"
1816         $LFS getstripe $DIR/$tdir/$tfile
1817         reset_enospc
1818 }
1819 run_test 27n "create file with some full OSTs"
1820
1821 test_27o() {
1822         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1824         remote_mds_nodsh && skip "remote MDS with nodsh"
1825         remote_ost_nodsh && skip "remote OST with nodsh"
1826
1827         reset_enospc
1828         rm -f $DIR/$tdir/$tfile
1829         exhaust_all_precreations 0x215
1830
1831         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1832
1833         reset_enospc
1834         rm -rf $DIR/$tdir/*
1835 }
1836 run_test 27o "create file with all full OSTs (should error)"
1837
1838 test_27p() {
1839         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1841         remote_mds_nodsh && skip "remote MDS with nodsh"
1842         remote_ost_nodsh && skip "remote OST with nodsh"
1843
1844         reset_enospc
1845         rm -f $DIR/$tdir/$tfile
1846         test_mkdir $DIR/$tdir
1847
1848         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1849         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1850         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1851
1852         exhaust_precreations 0 0x80000215
1853         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1854         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1855         $LFS getstripe $DIR/$tdir/$tfile
1856
1857         reset_enospc
1858 }
1859 run_test 27p "append to a truncated file with some full OSTs"
1860
1861 test_27q() {
1862         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1864         remote_mds_nodsh && skip "remote MDS with nodsh"
1865         remote_ost_nodsh && skip "remote OST with nodsh"
1866
1867         reset_enospc
1868         rm -f $DIR/$tdir/$tfile
1869
1870         test_mkdir $DIR/$tdir
1871         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1872         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1873                 error "truncate $DIR/$tdir/$tfile failed"
1874         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1875
1876         exhaust_all_precreations 0x215
1877
1878         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1879         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1880
1881         reset_enospc
1882 }
1883 run_test 27q "append to truncated file with all OSTs full (should error)"
1884
1885 test_27r() {
1886         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1888         remote_mds_nodsh && skip "remote MDS with nodsh"
1889         remote_ost_nodsh && skip "remote OST with nodsh"
1890
1891         reset_enospc
1892         rm -f $DIR/$tdir/$tfile
1893         exhaust_precreations 0 0x80000215
1894
1895         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1896
1897         reset_enospc
1898 }
1899 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1900
1901 test_27s() { # bug 10725
1902         test_mkdir $DIR/$tdir
1903         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1904         local stripe_count=0
1905         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1906         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1907                 error "stripe width >= 2^32 succeeded" || true
1908
1909 }
1910 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1911
1912 test_27t() { # bug 10864
1913         WDIR=$(pwd)
1914         WLFS=$(which lfs)
1915         cd $DIR
1916         touch $tfile
1917         $WLFS getstripe $tfile
1918         cd $WDIR
1919 }
1920 run_test 27t "check that utils parse path correctly"
1921
1922 test_27u() { # bug 4900
1923         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1924         remote_mds_nodsh && skip "remote MDS with nodsh"
1925
1926         local index
1927         local list=$(comma_list $(mdts_nodes))
1928
1929 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1930         do_nodes $list $LCTL set_param fail_loc=0x139
1931         test_mkdir -p $DIR/$tdir
1932         trap simple_cleanup_common EXIT
1933         createmany -o $DIR/$tdir/t- 1000
1934         do_nodes $list $LCTL set_param fail_loc=0
1935
1936         TLOG=$TMP/$tfile.getstripe
1937         $LFS getstripe $DIR/$tdir > $TLOG
1938         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1939         unlinkmany $DIR/$tdir/t- 1000
1940         trap 0
1941         [[ $OBJS -gt 0 ]] &&
1942                 error "$OBJS objects created on OST-0. See $TLOG" ||
1943                 rm -f $TLOG
1944 }
1945 run_test 27u "skip object creation on OSC w/o objects"
1946
1947 test_27v() { # bug 4900
1948         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1950         remote_mds_nodsh && skip "remote MDS with nodsh"
1951         remote_ost_nodsh && skip "remote OST with nodsh"
1952
1953         exhaust_all_precreations 0x215
1954         reset_enospc
1955
1956         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1957
1958         touch $DIR/$tdir/$tfile
1959         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1960         # all except ost1
1961         for (( i=1; i < OSTCOUNT; i++ )); do
1962                 do_facet ost$i lctl set_param fail_loc=0x705
1963         done
1964         local START=`date +%s`
1965         createmany -o $DIR/$tdir/$tfile 32
1966
1967         local FINISH=`date +%s`
1968         local TIMEOUT=`lctl get_param -n timeout`
1969         local PROCESS=$((FINISH - START))
1970         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1971                error "$FINISH - $START >= $TIMEOUT / 2"
1972         sleep $((TIMEOUT / 2 - PROCESS))
1973         reset_enospc
1974 }
1975 run_test 27v "skip object creation on slow OST"
1976
1977 test_27w() { # bug 10997
1978         test_mkdir $DIR/$tdir
1979         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1980         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1981                 error "stripe size $size != 65536" || true
1982         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1983                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1984 }
1985 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1986
1987 test_27wa() {
1988         [[ $OSTCOUNT -lt 2 ]] &&
1989                 skip_env "skipping multiple stripe count/offset test"
1990
1991         test_mkdir $DIR/$tdir
1992         for i in $(seq 1 $OSTCOUNT); do
1993                 offset=$((i - 1))
1994                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
1995                         error "setstripe -c $i -i $offset failed"
1996                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
1997                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
1998                 [ $count -ne $i ] && error "stripe count $count != $i" || true
1999                 [ $index -ne $offset ] &&
2000                         error "stripe offset $index != $offset" || true
2001         done
2002 }
2003 run_test 27wa "check $LFS setstripe -c -i options"
2004
2005 test_27x() {
2006         remote_ost_nodsh && skip "remote OST with nodsh"
2007         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2009
2010         OFFSET=$(($OSTCOUNT - 1))
2011         OSTIDX=0
2012         local OST=$(ostname_from_index $OSTIDX)
2013
2014         test_mkdir $DIR/$tdir
2015         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2016         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2017         sleep_maxage
2018         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2019         for i in $(seq 0 $OFFSET); do
2020                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2021                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2022                 error "OST0 was degraded but new created file still use it"
2023         done
2024         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2025 }
2026 run_test 27x "create files while OST0 is degraded"
2027
2028 test_27y() {
2029         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2030         remote_mds_nodsh && skip "remote MDS with nodsh"
2031         remote_ost_nodsh && skip "remote OST with nodsh"
2032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2033
2034         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2035         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2036                 osp.$mdtosc.prealloc_last_id)
2037         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2038                 osp.$mdtosc.prealloc_next_id)
2039         local fcount=$((last_id - next_id))
2040         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2041         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2042
2043         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2044                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2045         local OST_DEACTIVE_IDX=-1
2046         local OSC
2047         local OSTIDX
2048         local OST
2049
2050         for OSC in $MDS_OSCS; do
2051                 OST=$(osc_to_ost $OSC)
2052                 OSTIDX=$(index_from_ostuuid $OST)
2053                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2054                         OST_DEACTIVE_IDX=$OSTIDX
2055                 fi
2056                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2057                         echo $OSC "is Deactivated:"
2058                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2059                 fi
2060         done
2061
2062         OSTIDX=$(index_from_ostuuid $OST)
2063         test_mkdir $DIR/$tdir
2064         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2065
2066         for OSC in $MDS_OSCS; do
2067                 OST=$(osc_to_ost $OSC)
2068                 OSTIDX=$(index_from_ostuuid $OST)
2069                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2070                         echo $OST "is degraded:"
2071                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2072                                                 obdfilter.$OST.degraded=1
2073                 fi
2074         done
2075
2076         sleep_maxage
2077         createmany -o $DIR/$tdir/$tfile $fcount
2078
2079         for OSC in $MDS_OSCS; do
2080                 OST=$(osc_to_ost $OSC)
2081                 OSTIDX=$(index_from_ostuuid $OST)
2082                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2083                         echo $OST "is recovered from degraded:"
2084                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2085                                                 obdfilter.$OST.degraded=0
2086                 else
2087                         do_facet $SINGLEMDS lctl --device %$OSC activate
2088                 fi
2089         done
2090
2091         # all osp devices get activated, hence -1 stripe count restored
2092         local stripe_count=0
2093
2094         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2095         # devices get activated.
2096         sleep_maxage
2097         $LFS setstripe -c -1 $DIR/$tfile
2098         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2099         rm -f $DIR/$tfile
2100         [ $stripe_count -ne $OSTCOUNT ] &&
2101                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2102         return 0
2103 }
2104 run_test 27y "create files while OST0 is degraded and the rest inactive"
2105
2106 check_seq_oid()
2107 {
2108         log "check file $1"
2109
2110         lmm_count=$($LFS getstripe -c $1)
2111         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2112         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2113
2114         local old_ifs="$IFS"
2115         IFS=$'[:]'
2116         fid=($($LFS path2fid $1))
2117         IFS="$old_ifs"
2118
2119         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2120         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2121
2122         # compare lmm_seq and lu_fid->f_seq
2123         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2124         # compare lmm_object_id and lu_fid->oid
2125         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2126
2127         # check the trusted.fid attribute of the OST objects of the file
2128         local have_obdidx=false
2129         local stripe_nr=0
2130         $LFS getstripe $1 | while read obdidx oid hex seq; do
2131                 # skip lines up to and including "obdidx"
2132                 [ -z "$obdidx" ] && break
2133                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2134                 $have_obdidx || continue
2135
2136                 local ost=$((obdidx + 1))
2137                 local dev=$(ostdevname $ost)
2138                 local oid_hex
2139
2140                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2141
2142                 seq=$(echo $seq | sed -e "s/^0x//g")
2143                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2144                         oid_hex=$(echo $oid)
2145                 else
2146                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2147                 fi
2148                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2149
2150                 local ff=""
2151                 #
2152                 # Don't unmount/remount the OSTs if we don't need to do that.
2153                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2154                 # update too, until that use mount/ll_decode_filter_fid/mount.
2155                 # Re-enable when debugfs will understand new filter_fid.
2156                 #
2157                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2158                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2159                                 $dev 2>/dev/null" | grep "parent=")
2160                 fi
2161                 if [ -z "$ff" ]; then
2162                         stop ost$ost
2163                         mount_fstype ost$ost
2164                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2165                                 $(facet_mntpt ost$ost)/$obj_file)
2166                         unmount_fstype ost$ost
2167                         start ost$ost $dev $OST_MOUNT_OPTS
2168                         clients_up
2169                 fi
2170
2171                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2172
2173                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2174
2175                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2176                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2177                 #
2178                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2179                 #       stripe_size=1048576 component_id=1 component_start=0 \
2180                 #       component_end=33554432
2181                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2182                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2183                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2184                 local ff_pstripe
2185                 if grep -q 'stripe=' <<<$ff; then
2186                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2187                 else
2188                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2189                         # into f_ver in this case.  See comment on ff_parent.
2190                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2191                 fi
2192
2193                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2194                 [ $ff_pseq = $lmm_seq ] ||
2195                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2196                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2197                 [ $ff_poid = $lmm_oid ] ||
2198                         error "FF parent OID $ff_poid != $lmm_oid"
2199                 (($ff_pstripe == $stripe_nr)) ||
2200                         error "FF stripe $ff_pstripe != $stripe_nr"
2201
2202                 stripe_nr=$((stripe_nr + 1))
2203                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2204                         continue
2205                 if grep -q 'stripe_count=' <<<$ff; then
2206                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2207                                             -e 's/ .*//' <<<$ff)
2208                         [ $lmm_count = $ff_scnt ] ||
2209                                 error "FF stripe count $lmm_count != $ff_scnt"
2210                 fi
2211         done
2212 }
2213
2214 test_27z() {
2215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2216         remote_ost_nodsh && skip "remote OST with nodsh"
2217
2218         test_mkdir $DIR/$tdir
2219         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2220                 { error "setstripe -c -1 failed"; return 1; }
2221         # We need to send a write to every object to get parent FID info set.
2222         # This _should_ also work for setattr, but does not currently.
2223         # touch $DIR/$tdir/$tfile-1 ||
2224         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2225                 { error "dd $tfile-1 failed"; return 2; }
2226         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2227                 { error "setstripe -c -1 failed"; return 3; }
2228         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2229                 { error "dd $tfile-2 failed"; return 4; }
2230
2231         # make sure write RPCs have been sent to OSTs
2232         sync; sleep 5; sync
2233
2234         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2235         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2236 }
2237 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2238
2239 test_27A() { # b=19102
2240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2241
2242         save_layout_restore_at_exit $MOUNT
2243         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2244         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2245                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2246         local default_size=$($LFS getstripe -S $MOUNT)
2247         local default_offset=$($LFS getstripe -i $MOUNT)
2248         local dsize=$(do_facet $SINGLEMDS \
2249                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2250         [ $default_size -eq $dsize ] ||
2251                 error "stripe size $default_size != $dsize"
2252         [ $default_offset -eq -1 ] ||
2253                 error "stripe offset $default_offset != -1"
2254 }
2255 run_test 27A "check filesystem-wide default LOV EA values"
2256
2257 test_27B() { # LU-2523
2258         test_mkdir $DIR/$tdir
2259         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2260         touch $DIR/$tdir/f0
2261         # open f1 with O_LOV_DELAY_CREATE
2262         # rename f0 onto f1
2263         # call setstripe ioctl on open file descriptor for f1
2264         # close
2265         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2266                 $DIR/$tdir/f0
2267
2268         rm -f $DIR/$tdir/f1
2269         # open f1 with O_LOV_DELAY_CREATE
2270         # unlink f1
2271         # call setstripe ioctl on open file descriptor for f1
2272         # close
2273         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2274
2275         # Allow multiop to fail in imitation of NFS's busted semantics.
2276         true
2277 }
2278 run_test 27B "call setstripe on open unlinked file/rename victim"
2279
2280 # 27C family tests full striping and overstriping
2281 test_27Ca() { #LU-2871
2282         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2283
2284         declare -a ost_idx
2285         local index
2286         local found
2287         local i
2288         local j
2289
2290         test_mkdir $DIR/$tdir
2291         cd $DIR/$tdir
2292         for i in $(seq 0 $((OSTCOUNT - 1))); do
2293                 # set stripe across all OSTs starting from OST$i
2294                 $LFS setstripe -i $i -c -1 $tfile$i
2295                 # get striping information
2296                 ost_idx=($($LFS getstripe $tfile$i |
2297                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2298                 echo ${ost_idx[@]}
2299
2300                 # check the layout
2301                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2302                         error "${#ost_idx[@]} != $OSTCOUNT"
2303
2304                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2305                         found=0
2306                         for j in $(echo ${ost_idx[@]}); do
2307                                 if [ $index -eq $j ]; then
2308                                         found=1
2309                                         break
2310                                 fi
2311                         done
2312                         [ $found = 1 ] ||
2313                                 error "Can not find $index in ${ost_idx[@]}"
2314                 done
2315         done
2316 }
2317 run_test 27Ca "check full striping across all OSTs"
2318
2319 test_27Cb() {
2320         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2321                 skip "server does not support overstriping"
2322         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2323                 skip_env "too many osts, skipping"
2324
2325         test_mkdir -p $DIR/$tdir
2326         local setcount=$(($OSTCOUNT * 2))
2327         [ $setcount -ge 160 ] || large_xattr_enabled ||
2328                 skip_env "ea_inode feature disabled"
2329
2330         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2331                 error "setstripe failed"
2332
2333         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2334         [ $count -eq $setcount ] ||
2335                 error "stripe count $count, should be $setcount"
2336
2337         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2338                 error "overstriped should be set in pattern"
2339
2340         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2341                 error "dd failed"
2342 }
2343 run_test 27Cb "more stripes than OSTs with -C"
2344
2345 test_27Cc() {
2346         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2347                 skip "server does not support overstriping"
2348         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2349
2350         test_mkdir -p $DIR/$tdir
2351         local setcount=$(($OSTCOUNT - 1))
2352
2353         [ $setcount -ge 160 ] || large_xattr_enabled ||
2354                 skip_env "ea_inode feature disabled"
2355
2356         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2357                 error "setstripe failed"
2358
2359         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2360         [ $count -eq $setcount ] ||
2361                 error "stripe count $count, should be $setcount"
2362
2363         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2364                 error "overstriped should not be set in pattern"
2365
2366         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2367                 error "dd failed"
2368 }
2369 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2370
2371 test_27Cd() {
2372         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2373                 skip "server does not support overstriping"
2374         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2375         large_xattr_enabled || skip_env "ea_inode feature disabled"
2376
2377         test_mkdir -p $DIR/$tdir
2378         local setcount=$LOV_MAX_STRIPE_COUNT
2379
2380         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2381                 error "setstripe failed"
2382
2383         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2384         [ $count -eq $setcount ] ||
2385                 error "stripe count $count, should be $setcount"
2386
2387         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2388                 error "overstriped should be set in pattern"
2389
2390         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2391                 error "dd failed"
2392
2393         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2394 }
2395 run_test 27Cd "test maximum stripe count"
2396
2397 test_27Ce() {
2398         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2399                 skip "server does not support overstriping"
2400         test_mkdir -p $DIR/$tdir
2401
2402         pool_add $TESTNAME || error "Pool creation failed"
2403         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2404
2405         local setcount=8
2406
2407         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2408                 error "setstripe failed"
2409
2410         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2411         [ $count -eq $setcount ] ||
2412                 error "stripe count $count, should be $setcount"
2413
2414         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2415                 error "overstriped should be set in pattern"
2416
2417         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2418                 error "dd failed"
2419
2420         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2421 }
2422 run_test 27Ce "test pool with overstriping"
2423
2424 test_27Cf() {
2425         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2426                 skip "server does not support overstriping"
2427         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2428                 skip_env "too many osts, skipping"
2429
2430         test_mkdir -p $DIR/$tdir
2431
2432         local setcount=$(($OSTCOUNT * 2))
2433         [ $setcount -ge 160 ] || large_xattr_enabled ||
2434                 skip_env "ea_inode feature disabled"
2435
2436         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2437                 error "setstripe failed"
2438
2439         echo 1 > $DIR/$tdir/$tfile
2440
2441         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2442         [ $count -eq $setcount ] ||
2443                 error "stripe count $count, should be $setcount"
2444
2445         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2446                 error "overstriped should be set in pattern"
2447
2448         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2449                 error "dd failed"
2450
2451         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2452 }
2453 run_test 27Cf "test default inheritance with overstriping"
2454
2455 test_27D() {
2456         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2457         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2458         remote_mds_nodsh && skip "remote MDS with nodsh"
2459
2460         local POOL=${POOL:-testpool}
2461         local first_ost=0
2462         local last_ost=$(($OSTCOUNT - 1))
2463         local ost_step=1
2464         local ost_list=$(seq $first_ost $ost_step $last_ost)
2465         local ost_range="$first_ost $last_ost $ost_step"
2466
2467         if ! combined_mgs_mds ; then
2468                 mount_mgs_client
2469         fi
2470
2471         test_mkdir $DIR/$tdir
2472         pool_add $POOL || error "pool_add failed"
2473         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2474
2475         local skip27D
2476         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2477                 skip27D+="-s 29"
2478         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2479                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2480                         skip27D+=" -s 30,31"
2481         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2482           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2483                 skip27D+=" -s 32,33"
2484         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2485                 error "llapi_layout_test failed"
2486
2487         destroy_test_pools || error "destroy test pools failed"
2488
2489         if ! combined_mgs_mds ; then
2490                 umount_mgs_client
2491         fi
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         local pool=$TESTNAME
2628         local ostrange="1 1 1"
2629
2630         save_layout_restore_at_exit $MOUNT
2631         $LFS setstripe -c 2 -i 0 $MOUNT
2632         pool_add $pool || error "pool_add failed"
2633         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2634         test_mkdir $DIR/$tdir
2635         $LFS setstripe -p $pool $DIR/$tdir
2636         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2637         $LFS getstripe $DIR/$tdir/$tfile
2638 }
2639 run_test 27I "check that root dir striping does not break parent dir one"
2640
2641 test_27J() {
2642         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
2643                 skip "Need MDS version newer than 2.12.51"
2644
2645         test_mkdir $DIR/$tdir
2646         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2647         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2648
2649         # create foreign file (raw way)
2650         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2651                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2652
2653         # verify foreign file (raw way)
2654         parse_foreign_file -f $DIR/$tdir/$tfile |
2655                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2656                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2657         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2658                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2659         parse_foreign_file -f $DIR/$tdir/$tfile |
2660                 grep "lov_foreign_size: 73" ||
2661                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2662         parse_foreign_file -f $DIR/$tdir/$tfile |
2663                 grep "lov_foreign_type: 1" ||
2664                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2665         parse_foreign_file -f $DIR/$tdir/$tfile |
2666                 grep "lov_foreign_flags: 0x0000DA08" ||
2667                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2668         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2669                 grep "lov_foreign_value: 0x" |
2670                 sed -e 's/lov_foreign_value: 0x//')
2671         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2672         [[ $lov = ${lov2// /} ]] ||
2673                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2674
2675         # create foreign file (lfs + API)
2676         $LFS setstripe --foreign=daos --flags 0xda08 \
2677                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2678                 error "$DIR/$tdir/${tfile}2: create failed"
2679
2680         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2681                 grep "lfm_magic:.*0x0BD70BD0" ||
2682                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2683         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2684         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2685                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2686         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2687                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2688         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2689                 grep "lfm_flags:.*0x0000DA08" ||
2690                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2691         $LFS getstripe $DIR/$tdir/${tfile}2 |
2692                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2693                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2694
2695         # modify striping should fail
2696         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2697                 error "$DIR/$tdir/$tfile: setstripe should fail"
2698         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2699                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2700
2701         # R/W should fail
2702         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2703         cat $DIR/$tdir/${tfile}2 &&
2704                 error "$DIR/$tdir/${tfile}2: read should fail"
2705         cat /etc/passwd > $DIR/$tdir/$tfile &&
2706                 error "$DIR/$tdir/$tfile: write should fail"
2707         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2708                 error "$DIR/$tdir/${tfile}2: write should fail"
2709
2710         # chmod should work
2711         chmod 222 $DIR/$tdir/$tfile ||
2712                 error "$DIR/$tdir/$tfile: chmod failed"
2713         chmod 222 $DIR/$tdir/${tfile}2 ||
2714                 error "$DIR/$tdir/${tfile}2: chmod failed"
2715
2716         # chown should work
2717         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2718                 error "$DIR/$tdir/$tfile: chown failed"
2719         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2720                 error "$DIR/$tdir/${tfile}2: chown failed"
2721
2722         # rename should work
2723         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2724                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2725         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2726                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2727
2728         #remove foreign file
2729         rm $DIR/$tdir/${tfile}.new ||
2730                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2731         rm $DIR/$tdir/${tfile}2.new ||
2732                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2733 }
2734 run_test 27J "basic ops on file with foreign LOV"
2735
2736 test_27K() {
2737         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
2738                 skip "Need MDS version newer than 2.12.49"
2739
2740         test_mkdir $DIR/$tdir
2741         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2742         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2743
2744         # create foreign dir (raw way)
2745         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2746                 error "create_foreign_dir FAILED"
2747
2748         # verify foreign dir (raw way)
2749         parse_foreign_dir -d $DIR/$tdir/$tdir |
2750                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2751                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2752         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2753                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2754         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2755                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2756         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2757                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2758         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2759                 grep "lmv_foreign_value: 0x" |
2760                 sed 's/lmv_foreign_value: 0x//')
2761         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2762                 sed 's/ //g')
2763         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2764
2765         # create foreign dir (lfs + API)
2766         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2767                 $DIR/$tdir/${tdir}2 ||
2768                 error "$DIR/$tdir/${tdir}2: create failed"
2769
2770         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2771                 grep "lfm_magic:.*0x0CD50CD0" ||
2772                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2773         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2774         # - sizeof(lfm_type) - sizeof(lfm_flags)
2775         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2776                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2777         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2778                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2779         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2780                 grep "lfm_flags:.*0x0000DA05" ||
2781                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2782         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2783                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2784                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2785
2786         # file create in dir should fail
2787         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2788         touch $DIR/$tdir/${tdir}2/$tfile &&
2789                 "$DIR/${tdir}2: file create should fail"
2790
2791         # chmod should work
2792         chmod 777 $DIR/$tdir/$tdir ||
2793                 error "$DIR/$tdir: chmod failed"
2794         chmod 777 $DIR/$tdir/${tdir}2 ||
2795                 error "$DIR/${tdir}2: chmod failed"
2796
2797         # chown should work
2798         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2799                 error "$DIR/$tdir: chown failed"
2800         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2801                 error "$DIR/${tdir}2: chown failed"
2802
2803         # rename should work
2804         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2805                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2806         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2807                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2808
2809         #remove foreign dir
2810         rmdir $DIR/$tdir/${tdir}.new ||
2811                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2812         rmdir $DIR/$tdir/${tdir}2.new ||
2813                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2814 }
2815 run_test 27K "basic ops on dir with foreign LMV"
2816
2817 # createtest also checks that device nodes are created and
2818 # then visible correctly (#2091)
2819 test_28() { # bug 2091
2820         test_mkdir $DIR/d28
2821         $CREATETEST $DIR/d28/ct || error "createtest failed"
2822 }
2823 run_test 28 "create/mknod/mkdir with bad file types ============"
2824
2825 test_29() {
2826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2827
2828         sync; sleep 1; sync # flush out any dirty pages from previous tests
2829         cancel_lru_locks
2830         test_mkdir $DIR/d29
2831         touch $DIR/d29/foo
2832         log 'first d29'
2833         ls -l $DIR/d29
2834
2835         declare -i LOCKCOUNTORIG=0
2836         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2837                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2838         done
2839         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2840
2841         declare -i LOCKUNUSEDCOUNTORIG=0
2842         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2843                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2844         done
2845
2846         log 'second d29'
2847         ls -l $DIR/d29
2848         log 'done'
2849
2850         declare -i LOCKCOUNTCURRENT=0
2851         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2852                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
2853         done
2854
2855         declare -i LOCKUNUSEDCOUNTCURRENT=0
2856         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2857                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
2858         done
2859
2860         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
2861                 $LCTL set_param -n ldlm.dump_namespaces ""
2862                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
2863                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2864                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2865                 return 2
2866         fi
2867         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
2868                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
2869                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2870                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2871                 return 3
2872         fi
2873 }
2874 run_test 29 "IT_GETATTR regression  ============================"
2875
2876 test_30a() { # was test_30
2877         cp $(which ls) $DIR || cp /bin/ls $DIR
2878         $DIR/ls / || error "Can't execute binary from lustre"
2879         rm $DIR/ls
2880 }
2881 run_test 30a "execute binary from Lustre (execve) =============="
2882
2883 test_30b() {
2884         cp `which ls` $DIR || cp /bin/ls $DIR
2885         chmod go+rx $DIR/ls
2886         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
2887         rm $DIR/ls
2888 }
2889 run_test 30b "execute binary from Lustre as non-root ==========="
2890
2891 test_30c() { # b=22376
2892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2893
2894         cp `which ls` $DIR || cp /bin/ls $DIR
2895         chmod a-rw $DIR/ls
2896         cancel_lru_locks mdc
2897         cancel_lru_locks osc
2898         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
2899         rm -f $DIR/ls
2900 }
2901 run_test 30c "execute binary from Lustre without read perms ===="
2902
2903 test_31a() {
2904         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
2905         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
2906 }
2907 run_test 31a "open-unlink file =================================="
2908
2909 test_31b() {
2910         touch $DIR/f31 || error "touch $DIR/f31 failed"
2911         ln $DIR/f31 $DIR/f31b || error "ln failed"
2912         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
2913         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
2914 }
2915 run_test 31b "unlink file with multiple links while open ======="
2916
2917 test_31c() {
2918         touch $DIR/f31 || error "touch $DIR/f31 failed"
2919         ln $DIR/f31 $DIR/f31c || error "ln failed"
2920         multiop_bg_pause $DIR/f31 O_uc ||
2921                 error "multiop_bg_pause for $DIR/f31 failed"
2922         MULTIPID=$!
2923         $MULTIOP $DIR/f31c Ouc
2924         kill -USR1 $MULTIPID
2925         wait $MULTIPID
2926 }
2927 run_test 31c "open-unlink file with multiple links ============="
2928
2929 test_31d() {
2930         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
2931         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
2932 }
2933 run_test 31d "remove of open directory ========================="
2934
2935 test_31e() { # bug 2904
2936         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
2937 }
2938 run_test 31e "remove of open non-empty directory ==============="
2939
2940 test_31f() { # bug 4554
2941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2942
2943         set -vx
2944         test_mkdir $DIR/d31f
2945         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2946         cp /etc/hosts $DIR/d31f
2947         ls -l $DIR/d31f
2948         $LFS getstripe $DIR/d31f/hosts
2949         multiop_bg_pause $DIR/d31f D_c || return 1
2950         MULTIPID=$!
2951
2952         rm -rv $DIR/d31f || error "first of $DIR/d31f"
2953         test_mkdir $DIR/d31f
2954         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2955         cp /etc/hosts $DIR/d31f
2956         ls -l $DIR/d31f
2957         $LFS getstripe $DIR/d31f/hosts
2958         multiop_bg_pause $DIR/d31f D_c || return 1
2959         MULTIPID2=$!
2960
2961         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
2962         wait $MULTIPID || error "first opendir $MULTIPID failed"
2963
2964         sleep 6
2965
2966         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
2967         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
2968         set +vx
2969 }
2970 run_test 31f "remove of open directory with open-unlink file ==="
2971
2972 test_31g() {
2973         echo "-- cross directory link --"
2974         test_mkdir -c1 $DIR/${tdir}ga
2975         test_mkdir -c1 $DIR/${tdir}gb
2976         touch $DIR/${tdir}ga/f
2977         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
2978         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
2979         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
2980         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
2981         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
2982 }
2983 run_test 31g "cross directory link==============="
2984
2985 test_31h() {
2986         echo "-- cross directory link --"
2987         test_mkdir -c1 $DIR/${tdir}
2988         test_mkdir -c1 $DIR/${tdir}/dir
2989         touch $DIR/${tdir}/f
2990         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
2991         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
2992         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
2993         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
2994         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
2995 }
2996 run_test 31h "cross directory link under child==============="
2997
2998 test_31i() {
2999         echo "-- cross directory link --"
3000         test_mkdir -c1 $DIR/$tdir
3001         test_mkdir -c1 $DIR/$tdir/dir
3002         touch $DIR/$tdir/dir/f
3003         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3004         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3005         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3006         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3007         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3008 }
3009 run_test 31i "cross directory link under parent==============="
3010
3011 test_31j() {
3012         test_mkdir -c1 -p $DIR/$tdir
3013         test_mkdir -c1 -p $DIR/$tdir/dir1
3014         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3015         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3016         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3017         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3018         return 0
3019 }
3020 run_test 31j "link for directory==============="
3021
3022 test_31k() {
3023         test_mkdir -c1 -p $DIR/$tdir
3024         touch $DIR/$tdir/s
3025         touch $DIR/$tdir/exist
3026         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3027         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3028         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3029         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3030         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3031         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3032         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3033         return 0
3034 }
3035 run_test 31k "link to file: the same, non-existing, dir==============="
3036
3037 test_31m() {
3038         mkdir $DIR/d31m
3039         touch $DIR/d31m/s
3040         mkdir $DIR/d31m2
3041         touch $DIR/d31m2/exist
3042         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3043         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3044         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3045         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3046         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3047         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3048         return 0
3049 }
3050 run_test 31m "link to file: the same, non-existing, dir==============="
3051
3052 test_31n() {
3053         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3054         nlink=$(stat --format=%h $DIR/$tfile)
3055         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3056         local fd=$(free_fd)
3057         local cmd="exec $fd<$DIR/$tfile"
3058         eval $cmd
3059         cmd="exec $fd<&-"
3060         trap "eval $cmd" EXIT
3061         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3062         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3063         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3064         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3065         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3066         eval $cmd
3067 }
3068 run_test 31n "check link count of unlinked file"
3069
3070 link_one() {
3071         local TEMPNAME=$(mktemp $1_XXXXXX)
3072         mlink $TEMPNAME $1 2> /dev/null &&
3073                 echo "$BASHPID: link $TEMPNAME to $1 succeeded"
3074         munlink $TEMPNAME
3075 }
3076
3077 test_31o() { # LU-2901
3078         test_mkdir $DIR/$tdir
3079         for LOOP in $(seq 100); do
3080                 rm -f $DIR/$tdir/$tfile*
3081                 for THREAD in $(seq 8); do
3082                         link_one $DIR/$tdir/$tfile.$LOOP &
3083                 done
3084                 wait
3085                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3086                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3087                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3088                         break || true
3089         done
3090 }
3091 run_test 31o "duplicate hard links with same filename"
3092
3093 test_31p() {
3094         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3095
3096         test_mkdir $DIR/$tdir
3097         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3098         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3099
3100         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3101                 error "open unlink test1 failed"
3102         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3103                 error "open unlink test2 failed"
3104
3105         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3106                 error "test1 still exists"
3107         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3108                 error "test2 still exists"
3109 }
3110 run_test 31p "remove of open striped directory"
3111
3112 cleanup_test32_mount() {
3113         local rc=0
3114         trap 0
3115         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3116         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3117         losetup -d $loopdev || true
3118         rm -rf $DIR/$tdir
3119         return $rc
3120 }
3121
3122 test_32a() {
3123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3124
3125         echo "== more mountpoints and symlinks ================="
3126         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3127         trap cleanup_test32_mount EXIT
3128         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3129         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3130                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3131         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3132                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3133         cleanup_test32_mount
3134 }
3135 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3136
3137 test_32b() {
3138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3139
3140         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3141         trap cleanup_test32_mount EXIT
3142         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3143         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3144                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3145         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3146                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3147         cleanup_test32_mount
3148 }
3149 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3150
3151 test_32c() {
3152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3153
3154         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3155         trap cleanup_test32_mount EXIT
3156         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3157         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3158                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3159         test_mkdir -p $DIR/$tdir/d2/test_dir
3160         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3161                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3162         cleanup_test32_mount
3163 }
3164 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3165
3166 test_32d() {
3167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3168
3169         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3170         trap cleanup_test32_mount EXIT
3171         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3172         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3173                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3174         test_mkdir -p $DIR/$tdir/d2/test_dir
3175         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3176                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3177         cleanup_test32_mount
3178 }
3179 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3180
3181 test_32e() {
3182         rm -fr $DIR/$tdir
3183         test_mkdir -p $DIR/$tdir/tmp
3184         local tmp_dir=$DIR/$tdir/tmp
3185         ln -s $DIR/$tdir $tmp_dir/symlink11
3186         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3187         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3188         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3189 }
3190 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3191
3192 test_32f() {
3193         rm -fr $DIR/$tdir
3194         test_mkdir -p $DIR/$tdir/tmp
3195         local tmp_dir=$DIR/$tdir/tmp
3196         ln -s $DIR/$tdir $tmp_dir/symlink11
3197         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3198         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3199         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3200 }
3201 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3202
3203 test_32g() {
3204         local tmp_dir=$DIR/$tdir/tmp
3205         test_mkdir -p $tmp_dir
3206         test_mkdir $DIR/${tdir}2
3207         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3208         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3209         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3210         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3211         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3212         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3213 }
3214 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3215
3216 test_32h() {
3217         rm -fr $DIR/$tdir $DIR/${tdir}2
3218         tmp_dir=$DIR/$tdir/tmp
3219         test_mkdir -p $tmp_dir
3220         test_mkdir $DIR/${tdir}2
3221         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3222         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3223         ls $tmp_dir/symlink12 || error "listing symlink12"
3224         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3225 }
3226 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3227
3228 test_32i() {
3229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3230
3231         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3232         trap cleanup_test32_mount EXIT
3233         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3234         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3235                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3236         touch $DIR/$tdir/test_file
3237         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3238                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3239         cleanup_test32_mount
3240 }
3241 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3242
3243 test_32j() {
3244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3245
3246         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3247         trap cleanup_test32_mount EXIT
3248         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3249         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3250                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3251         touch $DIR/$tdir/test_file
3252         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3253                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3254         cleanup_test32_mount
3255 }
3256 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3257
3258 test_32k() {
3259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3260
3261         rm -fr $DIR/$tdir
3262         trap cleanup_test32_mount EXIT
3263         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3264         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3265                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3266         test_mkdir -p $DIR/$tdir/d2
3267         touch $DIR/$tdir/d2/test_file || error "touch failed"
3268         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3269                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3270         cleanup_test32_mount
3271 }
3272 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3273
3274 test_32l() {
3275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3276
3277         rm -fr $DIR/$tdir
3278         trap cleanup_test32_mount EXIT
3279         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3280         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3281                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3282         test_mkdir -p $DIR/$tdir/d2
3283         touch $DIR/$tdir/d2/test_file || error "touch failed"
3284         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3285                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3286         cleanup_test32_mount
3287 }
3288 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3289
3290 test_32m() {
3291         rm -fr $DIR/d32m
3292         test_mkdir -p $DIR/d32m/tmp
3293         TMP_DIR=$DIR/d32m/tmp
3294         ln -s $DIR $TMP_DIR/symlink11
3295         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3296         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3297                 error "symlink11 not a link"
3298         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3299                 error "symlink01 not a link"
3300 }
3301 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3302
3303 test_32n() {
3304         rm -fr $DIR/d32n
3305         test_mkdir -p $DIR/d32n/tmp
3306         TMP_DIR=$DIR/d32n/tmp
3307         ln -s $DIR $TMP_DIR/symlink11
3308         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3309         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3310         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3311 }
3312 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3313
3314 test_32o() {
3315         touch $DIR/$tfile
3316         test_mkdir -p $DIR/d32o/tmp
3317         TMP_DIR=$DIR/d32o/tmp
3318         ln -s $DIR/$tfile $TMP_DIR/symlink12
3319         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3320         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3321                 error "symlink12 not a link"
3322         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3323         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3324                 error "$DIR/d32o/tmp/symlink12 not file type"
3325         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3326                 error "$DIR/d32o/symlink02 not file type"
3327 }
3328 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3329
3330 test_32p() {
3331         log 32p_1
3332         rm -fr $DIR/d32p
3333         log 32p_2
3334         rm -f $DIR/$tfile
3335         log 32p_3
3336         touch $DIR/$tfile
3337         log 32p_4
3338         test_mkdir -p $DIR/d32p/tmp
3339         log 32p_5
3340         TMP_DIR=$DIR/d32p/tmp
3341         log 32p_6
3342         ln -s $DIR/$tfile $TMP_DIR/symlink12
3343         log 32p_7
3344         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3345         log 32p_8
3346         cat $DIR/d32p/tmp/symlink12 ||
3347                 error "Can't open $DIR/d32p/tmp/symlink12"
3348         log 32p_9
3349         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3350         log 32p_10
3351 }
3352 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3353
3354 test_32q() {
3355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3356
3357         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3358         trap cleanup_test32_mount EXIT
3359         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3360         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3361         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3362                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3363         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3364         cleanup_test32_mount
3365 }
3366 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3367
3368 test_32r() {
3369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3370
3371         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3372         trap cleanup_test32_mount EXIT
3373         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3374         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3375         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3376                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3377         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3378         cleanup_test32_mount
3379 }
3380 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3381
3382 test_33aa() {
3383         rm -f $DIR/$tfile
3384         touch $DIR/$tfile
3385         chmod 444 $DIR/$tfile
3386         chown $RUNAS_ID $DIR/$tfile
3387         log 33_1
3388         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3389         log 33_2
3390 }
3391 run_test 33aa "write file with mode 444 (should return error)"
3392
3393 test_33a() {
3394         rm -fr $DIR/$tdir
3395         test_mkdir $DIR/$tdir
3396         chown $RUNAS_ID $DIR/$tdir
3397         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3398                 error "$RUNAS create $tdir/$tfile failed"
3399         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3400                 error "open RDWR" || true
3401 }
3402 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3403
3404 test_33b() {
3405         rm -fr $DIR/$tdir
3406         test_mkdir $DIR/$tdir
3407         chown $RUNAS_ID $DIR/$tdir
3408         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3409 }
3410 run_test 33b "test open file with malformed flags (No panic)"
3411
3412 test_33c() {
3413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3414         remote_ost_nodsh && skip "remote OST with nodsh"
3415
3416         local ostnum
3417         local ostname
3418         local write_bytes
3419         local all_zeros
3420
3421         all_zeros=:
3422         rm -fr $DIR/$tdir
3423         test_mkdir $DIR/$tdir
3424         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3425
3426         sync
3427         for ostnum in $(seq $OSTCOUNT); do
3428                 # test-framework's OST numbering is one-based, while Lustre's
3429                 # is zero-based
3430                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3431                 # Parsing llobdstat's output sucks; we could grep the /proc
3432                 # path, but that's likely to not be as portable as using the
3433                 # llobdstat utility.  So we parse lctl output instead.
3434                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3435                         obdfilter/$ostname/stats |
3436                         awk '/^write_bytes/ {print $7}' )
3437                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3438                 if (( ${write_bytes:-0} > 0 ))
3439                 then
3440                         all_zeros=false
3441                         break;
3442                 fi
3443         done
3444
3445         $all_zeros || return 0
3446
3447         # Write four bytes
3448         echo foo > $DIR/$tdir/bar
3449         # Really write them
3450         sync
3451
3452         # Total up write_bytes after writing.  We'd better find non-zeros.
3453         for ostnum in $(seq $OSTCOUNT); do
3454                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3455                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3456                         obdfilter/$ostname/stats |
3457                         awk '/^write_bytes/ {print $7}' )
3458                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3459                 if (( ${write_bytes:-0} > 0 ))
3460                 then
3461                         all_zeros=false
3462                         break;
3463                 fi
3464         done
3465
3466         if $all_zeros
3467         then
3468                 for ostnum in $(seq $OSTCOUNT); do
3469                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3470                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3471                         do_facet ost$ostnum lctl get_param -n \
3472                                 obdfilter/$ostname/stats
3473                 done
3474                 error "OST not keeping write_bytes stats (b22312)"
3475         fi
3476 }
3477 run_test 33c "test llobdstat and write_bytes"
3478
3479 test_33d() {
3480         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3482
3483         local MDTIDX=1
3484         local remote_dir=$DIR/$tdir/remote_dir
3485
3486         test_mkdir $DIR/$tdir
3487         $LFS mkdir -i $MDTIDX $remote_dir ||
3488                 error "create remote directory failed"
3489
3490         touch $remote_dir/$tfile
3491         chmod 444 $remote_dir/$tfile
3492         chown $RUNAS_ID $remote_dir/$tfile
3493
3494         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3495
3496         chown $RUNAS_ID $remote_dir
3497         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3498                                         error "create" || true
3499         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3500                                     error "open RDWR" || true
3501         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3502 }
3503 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3504
3505 test_33e() {
3506         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3507
3508         mkdir $DIR/$tdir
3509
3510         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3511         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3512         mkdir $DIR/$tdir/local_dir
3513
3514         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3515         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3516         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3517
3518         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3519                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3520
3521         rmdir $DIR/$tdir/* || error "rmdir failed"
3522
3523         umask 777
3524         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3525         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3526         mkdir $DIR/$tdir/local_dir
3527
3528         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3529         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3530         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3531
3532         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3533                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3534
3535         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3536
3537         umask 000
3538         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3539         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3540         mkdir $DIR/$tdir/local_dir
3541
3542         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3543         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3544         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3545
3546         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3547                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3548 }
3549 run_test 33e "mkdir and striped directory should have same mode"
3550
3551 cleanup_33f() {
3552         trap 0
3553         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3554 }
3555
3556 test_33f() {
3557         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3558         remote_mds_nodsh && skip "remote MDS with nodsh"
3559
3560         mkdir $DIR/$tdir
3561         chmod go+rwx $DIR/$tdir
3562         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3563         trap cleanup_33f EXIT
3564
3565         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3566                 error "cannot create striped directory"
3567
3568         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3569                 error "cannot create files in striped directory"
3570
3571         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3572                 error "cannot remove files in striped directory"
3573
3574         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3575                 error "cannot remove striped directory"
3576
3577         cleanup_33f
3578 }
3579 run_test 33f "nonroot user can create, access, and remove a striped directory"
3580
3581 test_33g() {
3582         mkdir -p $DIR/$tdir/dir2
3583
3584         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3585         echo $err
3586         [[ $err =~ "exists" ]] || error "Not exists error"
3587 }
3588 run_test 33g "nonroot user create already existing root created file"
3589
3590 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3591 test_34a() {
3592         rm -f $DIR/f34
3593         $MCREATE $DIR/f34 || error "mcreate failed"
3594         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3595                 error "getstripe failed"
3596         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3597         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3598                 error "getstripe failed"
3599         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3600                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3601 }
3602 run_test 34a "truncate file that has not been opened ==========="
3603
3604 test_34b() {
3605         [ ! -f $DIR/f34 ] && test_34a
3606         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3607                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3608         $OPENFILE -f O_RDONLY $DIR/f34
3609         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3610                 error "getstripe failed"
3611         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3612                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3613 }
3614 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3615
3616 test_34c() {
3617         [ ! -f $DIR/f34 ] && test_34a
3618         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3619                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3620         $OPENFILE -f O_RDWR $DIR/f34
3621         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3622                 error "$LFS getstripe failed"
3623         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3624                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3625 }
3626 run_test 34c "O_RDWR opening file-with-size works =============="
3627
3628 test_34d() {
3629         [ ! -f $DIR/f34 ] && test_34a
3630         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3631                 error "dd failed"
3632         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3633                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3634         rm $DIR/f34
3635 }
3636 run_test 34d "write to sparse file ============================="
3637
3638 test_34e() {
3639         rm -f $DIR/f34e
3640         $MCREATE $DIR/f34e || error "mcreate failed"
3641         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3642         $CHECKSTAT -s 1000 $DIR/f34e ||
3643                 error "Size of $DIR/f34e not equal to 1000 bytes"
3644         $OPENFILE -f O_RDWR $DIR/f34e
3645         $CHECKSTAT -s 1000 $DIR/f34e ||
3646                 error "Size of $DIR/f34e not equal to 1000 bytes"
3647 }
3648 run_test 34e "create objects, some with size and some without =="
3649
3650 test_34f() { # bug 6242, 6243
3651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3652
3653         SIZE34F=48000
3654         rm -f $DIR/f34f
3655         $MCREATE $DIR/f34f || error "mcreate failed"
3656         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3657         dd if=$DIR/f34f of=$TMP/f34f
3658         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3659         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3660         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3661         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3662         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3663 }
3664 run_test 34f "read from a file with no objects until EOF ======="
3665
3666 test_34g() {
3667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3668
3669         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3670                 error "dd failed"
3671         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3672         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3673                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3674         cancel_lru_locks osc
3675         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3676                 error "wrong size after lock cancel"
3677
3678         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3679         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3680                 error "expanding truncate failed"
3681         cancel_lru_locks osc
3682         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3683                 error "wrong expanded size after lock cancel"
3684 }
3685 run_test 34g "truncate long file ==============================="
3686
3687 test_34h() {
3688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3689
3690         local gid=10
3691         local sz=1000
3692
3693         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3694         sync # Flush the cache so that multiop below does not block on cache
3695              # flush when getting the group lock
3696         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3697         MULTIPID=$!
3698
3699         # Since just timed wait is not good enough, let's do a sync write
3700         # that way we are sure enough time for a roundtrip + processing
3701         # passed + 2 seconds of extra margin.
3702         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3703         rm $DIR/${tfile}-1
3704         sleep 2
3705
3706         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3707                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3708                 kill -9 $MULTIPID
3709         fi
3710         wait $MULTIPID
3711         local nsz=`stat -c %s $DIR/$tfile`
3712         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3713 }
3714 run_test 34h "ftruncate file under grouplock should not block"
3715
3716 test_35a() {
3717         cp /bin/sh $DIR/f35a
3718         chmod 444 $DIR/f35a
3719         chown $RUNAS_ID $DIR/f35a
3720         $RUNAS $DIR/f35a && error || true
3721         rm $DIR/f35a
3722 }
3723 run_test 35a "exec file with mode 444 (should return and not leak)"
3724
3725 test_36a() {
3726         rm -f $DIR/f36
3727         utime $DIR/f36 || error "utime failed for MDS"
3728 }
3729 run_test 36a "MDS utime check (mknod, utime)"
3730
3731 test_36b() {
3732         echo "" > $DIR/f36
3733         utime $DIR/f36 || error "utime failed for OST"
3734 }
3735 run_test 36b "OST utime check (open, utime)"
3736
3737 test_36c() {
3738         rm -f $DIR/d36/f36
3739         test_mkdir $DIR/d36
3740         chown $RUNAS_ID $DIR/d36
3741         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3742 }
3743 run_test 36c "non-root MDS utime check (mknod, utime)"
3744
3745 test_36d() {
3746         [ ! -d $DIR/d36 ] && test_36c
3747         echo "" > $DIR/d36/f36
3748         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3749 }
3750 run_test 36d "non-root OST utime check (open, utime)"
3751
3752 test_36e() {
3753         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3754
3755         test_mkdir $DIR/$tdir
3756         touch $DIR/$tdir/$tfile
3757         $RUNAS utime $DIR/$tdir/$tfile &&
3758                 error "utime worked, expected failure" || true
3759 }
3760 run_test 36e "utime on non-owned file (should return error)"
3761
3762 subr_36fh() {
3763         local fl="$1"
3764         local LANG_SAVE=$LANG
3765         local LC_LANG_SAVE=$LC_LANG
3766         export LANG=C LC_LANG=C # for date language
3767
3768         DATESTR="Dec 20  2000"
3769         test_mkdir $DIR/$tdir
3770         lctl set_param fail_loc=$fl
3771         date; date +%s
3772         cp /etc/hosts $DIR/$tdir/$tfile
3773         sync & # write RPC generated with "current" inode timestamp, but delayed
3774         sleep 1
3775         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3776         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3777         cancel_lru_locks $OSC
3778         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3779         date; date +%s
3780         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3781                 echo "BEFORE: $LS_BEFORE" && \
3782                 echo "AFTER : $LS_AFTER" && \
3783                 echo "WANT  : $DATESTR" && \
3784                 error "$DIR/$tdir/$tfile timestamps changed" || true
3785
3786         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3787 }
3788
3789 test_36f() {
3790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3791
3792         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3793         subr_36fh "0x80000214"
3794 }
3795 run_test 36f "utime on file racing with OST BRW write =========="
3796
3797 test_36g() {
3798         remote_ost_nodsh && skip "remote OST with nodsh"
3799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3800         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3801                 skip "Need MDS version at least 2.12.51"
3802
3803         local fmd_max_age
3804         local fmd
3805         local facet="ost1"
3806         local tgt="obdfilter"
3807
3808         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3809
3810         test_mkdir $DIR/$tdir
3811         fmd_max_age=$(do_facet $facet \
3812                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3813                 head -n 1")
3814
3815         echo "FMD max age: ${fmd_max_age}s"
3816         touch $DIR/$tdir/$tfile
3817         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3818                 gawk '{cnt=cnt+$1}  END{print cnt}')
3819         echo "FMD before: $fmd"
3820         [[ $fmd == 0 ]] &&
3821                 error "FMD wasn't create by touch"
3822         sleep $((fmd_max_age + 12))
3823         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3824                 gawk '{cnt=cnt+$1}  END{print cnt}')
3825         echo "FMD after: $fmd"
3826         [[ $fmd == 0 ]] ||
3827                 error "FMD wasn't expired by ping"
3828 }
3829 run_test 36g "FMD cache expiry ====================="
3830
3831 test_36h() {
3832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3833
3834         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3835         subr_36fh "0x80000227"
3836 }
3837 run_test 36h "utime on file racing with OST BRW write =========="
3838
3839 test_36i() {
3840         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3841
3842         test_mkdir $DIR/$tdir
3843         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3844
3845         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3846         local new_mtime=$((mtime + 200))
3847
3848         #change Modify time of striped dir
3849         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3850                         error "change mtime failed"
3851
3852         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
3853
3854         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
3855 }
3856 run_test 36i "change mtime on striped directory"
3857
3858 # test_37 - duplicate with tests 32q 32r
3859
3860 test_38() {
3861         local file=$DIR/$tfile
3862         touch $file
3863         openfile -f O_DIRECTORY $file
3864         local RC=$?
3865         local ENOTDIR=20
3866         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
3867         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
3868 }
3869 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
3870
3871 test_39a() { # was test_39
3872         touch $DIR/$tfile
3873         touch $DIR/${tfile}2
3874 #       ls -l  $DIR/$tfile $DIR/${tfile}2
3875 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
3876 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
3877         sleep 2
3878         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
3879         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
3880                 echo "mtime"
3881                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
3882                 echo "atime"
3883                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
3884                 echo "ctime"
3885                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
3886                 error "O_TRUNC didn't change timestamps"
3887         fi
3888 }
3889 run_test 39a "mtime changed on create"
3890
3891 test_39b() {
3892         test_mkdir -c1 $DIR/$tdir
3893         cp -p /etc/passwd $DIR/$tdir/fopen
3894         cp -p /etc/passwd $DIR/$tdir/flink
3895         cp -p /etc/passwd $DIR/$tdir/funlink
3896         cp -p /etc/passwd $DIR/$tdir/frename
3897         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
3898
3899         sleep 1
3900         echo "aaaaaa" >> $DIR/$tdir/fopen
3901         echo "aaaaaa" >> $DIR/$tdir/flink
3902         echo "aaaaaa" >> $DIR/$tdir/funlink
3903         echo "aaaaaa" >> $DIR/$tdir/frename
3904
3905         local open_new=`stat -c %Y $DIR/$tdir/fopen`
3906         local link_new=`stat -c %Y $DIR/$tdir/flink`
3907         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
3908         local rename_new=`stat -c %Y $DIR/$tdir/frename`
3909
3910         cat $DIR/$tdir/fopen > /dev/null
3911         ln $DIR/$tdir/flink $DIR/$tdir/flink2
3912         rm -f $DIR/$tdir/funlink2
3913         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
3914
3915         for (( i=0; i < 2; i++ )) ; do
3916                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
3917                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
3918                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
3919                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
3920
3921                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
3922                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
3923                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
3924                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
3925
3926                 cancel_lru_locks $OSC
3927                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3928         done
3929 }
3930 run_test 39b "mtime change on open, link, unlink, rename  ======"
3931
3932 # this should be set to past
3933 TEST_39_MTIME=`date -d "1 year ago" +%s`
3934
3935 # bug 11063
3936 test_39c() {
3937         touch $DIR1/$tfile
3938         sleep 2
3939         local mtime0=`stat -c %Y $DIR1/$tfile`
3940
3941         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3942         local mtime1=`stat -c %Y $DIR1/$tfile`
3943         [ "$mtime1" = $TEST_39_MTIME ] || \
3944                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
3945
3946         local d1=`date +%s`
3947         echo hello >> $DIR1/$tfile
3948         local d2=`date +%s`
3949         local mtime2=`stat -c %Y $DIR1/$tfile`
3950         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
3951                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
3952
3953         mv $DIR1/$tfile $DIR1/$tfile-1
3954
3955         for (( i=0; i < 2; i++ )) ; do
3956                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
3957                 [ "$mtime2" = "$mtime3" ] || \
3958                         error "mtime ($mtime2) changed (to $mtime3) on rename"
3959
3960                 cancel_lru_locks $OSC
3961                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3962         done
3963 }
3964 run_test 39c "mtime change on rename ==========================="
3965
3966 # bug 21114
3967 test_39d() {
3968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3969
3970         touch $DIR1/$tfile
3971         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3972
3973         for (( i=0; i < 2; i++ )) ; do
3974                 local mtime=`stat -c %Y $DIR1/$tfile`
3975                 [ $mtime = $TEST_39_MTIME ] || \
3976                         error "mtime($mtime) is not set to $TEST_39_MTIME"
3977
3978                 cancel_lru_locks $OSC
3979                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3980         done
3981 }
3982 run_test 39d "create, utime, stat =============================="
3983
3984 # bug 21114
3985 test_39e() {
3986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3987
3988         touch $DIR1/$tfile
3989         local mtime1=`stat -c %Y $DIR1/$tfile`
3990
3991         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3992
3993         for (( i=0; i < 2; i++ )) ; do
3994                 local mtime2=`stat -c %Y $DIR1/$tfile`
3995                 [ $mtime2 = $TEST_39_MTIME ] || \
3996                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3997
3998                 cancel_lru_locks $OSC
3999                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4000         done
4001 }
4002 run_test 39e "create, stat, utime, stat ========================"
4003
4004 # bug 21114
4005 test_39f() {
4006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4007
4008         touch $DIR1/$tfile
4009         mtime1=`stat -c %Y $DIR1/$tfile`
4010
4011         sleep 2
4012         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4013
4014         for (( i=0; i < 2; i++ )) ; do
4015                 local mtime2=`stat -c %Y $DIR1/$tfile`
4016                 [ $mtime2 = $TEST_39_MTIME ] || \
4017                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4018
4019                 cancel_lru_locks $OSC
4020                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4021         done
4022 }
4023 run_test 39f "create, stat, sleep, utime, stat ================="
4024
4025 # bug 11063
4026 test_39g() {
4027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4028
4029         echo hello >> $DIR1/$tfile
4030         local mtime1=`stat -c %Y $DIR1/$tfile`
4031
4032         sleep 2
4033         chmod o+r $DIR1/$tfile
4034
4035         for (( i=0; i < 2; i++ )) ; do
4036                 local mtime2=`stat -c %Y $DIR1/$tfile`
4037                 [ "$mtime1" = "$mtime2" ] || \
4038                         error "lost mtime: $mtime2, should be $mtime1"
4039
4040                 cancel_lru_locks $OSC
4041                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4042         done
4043 }
4044 run_test 39g "write, chmod, stat ==============================="
4045
4046 # bug 11063
4047 test_39h() {
4048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4049
4050         touch $DIR1/$tfile
4051         sleep 1
4052
4053         local d1=`date`
4054         echo hello >> $DIR1/$tfile
4055         local mtime1=`stat -c %Y $DIR1/$tfile`
4056
4057         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4058         local d2=`date`
4059         if [ "$d1" != "$d2" ]; then
4060                 echo "write and touch not within one second"
4061         else
4062                 for (( i=0; i < 2; i++ )) ; do
4063                         local mtime2=`stat -c %Y $DIR1/$tfile`
4064                         [ "$mtime2" = $TEST_39_MTIME ] || \
4065                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4066
4067                         cancel_lru_locks $OSC
4068                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4069                 done
4070         fi
4071 }
4072 run_test 39h "write, utime within one second, stat ============="
4073
4074 test_39i() {
4075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4076
4077         touch $DIR1/$tfile
4078         sleep 1
4079
4080         echo hello >> $DIR1/$tfile
4081         local mtime1=`stat -c %Y $DIR1/$tfile`
4082
4083         mv $DIR1/$tfile $DIR1/$tfile-1
4084
4085         for (( i=0; i < 2; i++ )) ; do
4086                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4087
4088                 [ "$mtime1" = "$mtime2" ] || \
4089                         error "lost mtime: $mtime2, should be $mtime1"
4090
4091                 cancel_lru_locks $OSC
4092                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4093         done
4094 }
4095 run_test 39i "write, rename, stat =============================="
4096
4097 test_39j() {
4098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4099
4100         start_full_debug_logging
4101         touch $DIR1/$tfile
4102         sleep 1
4103
4104         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4105         lctl set_param fail_loc=0x80000412
4106         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4107                 error "multiop failed"
4108         local multipid=$!
4109         local mtime1=`stat -c %Y $DIR1/$tfile`
4110
4111         mv $DIR1/$tfile $DIR1/$tfile-1
4112
4113         kill -USR1 $multipid
4114         wait $multipid || error "multiop close failed"
4115
4116         for (( i=0; i < 2; i++ )) ; do
4117                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4118                 [ "$mtime1" = "$mtime2" ] ||
4119                         error "mtime is lost on close: $mtime2, " \
4120                               "should be $mtime1"
4121
4122                 cancel_lru_locks $OSC
4123                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4124         done
4125         lctl set_param fail_loc=0
4126         stop_full_debug_logging
4127 }
4128 run_test 39j "write, rename, close, stat ======================="
4129
4130 test_39k() {
4131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4132
4133         touch $DIR1/$tfile
4134         sleep 1
4135
4136         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4137         local multipid=$!
4138         local mtime1=`stat -c %Y $DIR1/$tfile`
4139
4140         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4141
4142         kill -USR1 $multipid
4143         wait $multipid || error "multiop close failed"
4144
4145         for (( i=0; i < 2; i++ )) ; do
4146                 local mtime2=`stat -c %Y $DIR1/$tfile`
4147
4148                 [ "$mtime2" = $TEST_39_MTIME ] || \
4149                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4150
4151                 cancel_lru_locks osc
4152                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4153         done
4154 }
4155 run_test 39k "write, utime, close, stat ========================"
4156
4157 # this should be set to future
4158 TEST_39_ATIME=`date -d "1 year" +%s`
4159
4160 test_39l() {
4161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4162         remote_mds_nodsh && skip "remote MDS with nodsh"
4163
4164         local atime_diff=$(do_facet $SINGLEMDS \
4165                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4166         rm -rf $DIR/$tdir
4167         mkdir -p $DIR/$tdir
4168
4169         # test setting directory atime to future
4170         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4171         local atime=$(stat -c %X $DIR/$tdir)
4172         [ "$atime" = $TEST_39_ATIME ] ||
4173                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4174
4175         # test setting directory atime from future to now
4176         local now=$(date +%s)
4177         touch -a -d @$now $DIR/$tdir
4178
4179         atime=$(stat -c %X $DIR/$tdir)
4180         [ "$atime" -eq "$now"  ] ||
4181                 error "atime is not updated from future: $atime, $now"
4182
4183         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4184         sleep 3
4185
4186         # test setting directory atime when now > dir atime + atime_diff
4187         local d1=$(date +%s)
4188         ls $DIR/$tdir
4189         local d2=$(date +%s)
4190         cancel_lru_locks mdc
4191         atime=$(stat -c %X $DIR/$tdir)
4192         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4193                 error "atime is not updated  : $atime, should be $d2"
4194
4195         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4196         sleep 3
4197
4198         # test not setting directory atime when now < dir atime + atime_diff
4199         ls $DIR/$tdir
4200         cancel_lru_locks mdc
4201         atime=$(stat -c %X $DIR/$tdir)
4202         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4203                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4204
4205         do_facet $SINGLEMDS \
4206                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4207 }
4208 run_test 39l "directory atime update ==========================="
4209
4210 test_39m() {
4211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4212
4213         touch $DIR1/$tfile
4214         sleep 2
4215         local far_past_mtime=$(date -d "May 29 1953" +%s)
4216         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4217
4218         touch -m -d @$far_past_mtime $DIR1/$tfile
4219         touch -a -d @$far_past_atime $DIR1/$tfile
4220
4221         for (( i=0; i < 2; i++ )) ; do
4222                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4223                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4224                         error "atime or mtime set incorrectly"
4225
4226                 cancel_lru_locks $OSC
4227                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4228         done
4229 }
4230 run_test 39m "test atime and mtime before 1970"
4231
4232 test_39n() { # LU-3832
4233         remote_mds_nodsh && skip "remote MDS with nodsh"
4234
4235         local atime_diff=$(do_facet $SINGLEMDS \
4236                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4237         local atime0
4238         local atime1
4239         local atime2
4240
4241         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4242
4243         rm -rf $DIR/$tfile
4244         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4245         atime0=$(stat -c %X $DIR/$tfile)
4246
4247         sleep 5
4248         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4249         atime1=$(stat -c %X $DIR/$tfile)
4250
4251         sleep 5
4252         cancel_lru_locks mdc
4253         cancel_lru_locks osc
4254         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4255         atime2=$(stat -c %X $DIR/$tfile)
4256
4257         do_facet $SINGLEMDS \
4258                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4259
4260         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4261         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4262 }
4263 run_test 39n "check that O_NOATIME is honored"
4264
4265 test_39o() {
4266         TESTDIR=$DIR/$tdir/$tfile
4267         [ -e $TESTDIR ] && rm -rf $TESTDIR
4268         mkdir -p $TESTDIR
4269         cd $TESTDIR
4270         links1=2
4271         ls
4272         mkdir a b
4273         ls
4274         links2=$(stat -c %h .)
4275         [ $(($links1 + 2)) != $links2 ] &&
4276                 error "wrong links count $(($links1 + 2)) != $links2"
4277         rmdir b
4278         links3=$(stat -c %h .)
4279         [ $(($links1 + 1)) != $links3 ] &&
4280                 error "wrong links count $links1 != $links3"
4281         return 0
4282 }
4283 run_test 39o "directory cached attributes updated after create"
4284
4285 test_39p() {
4286         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4287
4288         local MDTIDX=1
4289         TESTDIR=$DIR/$tdir/$tdir
4290         [ -e $TESTDIR ] && rm -rf $TESTDIR
4291         test_mkdir -p $TESTDIR
4292         cd $TESTDIR
4293         links1=2
4294         ls
4295         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4296         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4297         ls
4298         links2=$(stat -c %h .)
4299         [ $(($links1 + 2)) != $links2 ] &&
4300                 error "wrong links count $(($links1 + 2)) != $links2"
4301         rmdir remote_dir2
4302         links3=$(stat -c %h .)
4303         [ $(($links1 + 1)) != $links3 ] &&
4304                 error "wrong links count $links1 != $links3"
4305         return 0
4306 }
4307 run_test 39p "remote directory cached attributes updated after create ========"
4308
4309
4310 test_39q() { # LU-8041
4311         local testdir=$DIR/$tdir
4312         mkdir -p $testdir
4313         multiop_bg_pause $testdir D_c || error "multiop failed"
4314         local multipid=$!
4315         cancel_lru_locks mdc
4316         kill -USR1 $multipid
4317         local atime=$(stat -c %X $testdir)
4318         [ "$atime" -ne 0 ] || error "atime is zero"
4319 }
4320 run_test 39q "close won't zero out atime"
4321
4322 test_40() {
4323         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4324         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4325                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4326         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4327                 error "$tfile is not 4096 bytes in size"
4328 }
4329 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4330
4331 test_41() {
4332         # bug 1553
4333         small_write $DIR/f41 18
4334 }
4335 run_test 41 "test small file write + fstat ====================="
4336
4337 count_ost_writes() {
4338         lctl get_param -n ${OSC}.*.stats |
4339                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4340                         END { printf("%0.0f", writes) }'
4341 }
4342
4343 # decent default
4344 WRITEBACK_SAVE=500
4345 DIRTY_RATIO_SAVE=40
4346 MAX_DIRTY_RATIO=50
4347 BG_DIRTY_RATIO_SAVE=10
4348 MAX_BG_DIRTY_RATIO=25
4349
4350 start_writeback() {
4351         trap 0
4352         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4353         # dirty_ratio, dirty_background_ratio
4354         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4355                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4356                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4357                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4358         else
4359                 # if file not here, we are a 2.4 kernel
4360                 kill -CONT `pidof kupdated`
4361         fi
4362 }
4363
4364 stop_writeback() {
4365         # setup the trap first, so someone cannot exit the test at the
4366         # exact wrong time and mess up a machine
4367         trap start_writeback EXIT
4368         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4369         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4370                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4371                 sysctl -w vm.dirty_writeback_centisecs=0
4372                 sysctl -w vm.dirty_writeback_centisecs=0
4373                 # save and increase /proc/sys/vm/dirty_ratio
4374                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4375                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4376                 # save and increase /proc/sys/vm/dirty_background_ratio
4377                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4378                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4379         else
4380                 # if file not here, we are a 2.4 kernel
4381                 kill -STOP `pidof kupdated`
4382         fi
4383 }
4384
4385 # ensure that all stripes have some grant before we test client-side cache
4386 setup_test42() {
4387         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4388                 dd if=/dev/zero of=$i bs=4k count=1
4389                 rm $i
4390         done
4391 }
4392
4393 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4394 # file truncation, and file removal.
4395 test_42a() {
4396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4397
4398         setup_test42
4399         cancel_lru_locks $OSC
4400         stop_writeback
4401         sync; sleep 1; sync # just to be safe
4402         BEFOREWRITES=`count_ost_writes`
4403         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4404         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4405         AFTERWRITES=`count_ost_writes`
4406         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4407                 error "$BEFOREWRITES < $AFTERWRITES"
4408         start_writeback
4409 }
4410 run_test 42a "ensure that we don't flush on close"
4411
4412 test_42b() {
4413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4414
4415         setup_test42
4416         cancel_lru_locks $OSC
4417         stop_writeback
4418         sync
4419         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4420         BEFOREWRITES=$(count_ost_writes)
4421         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4422         AFTERWRITES=$(count_ost_writes)
4423         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4424                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4425         fi
4426         BEFOREWRITES=$(count_ost_writes)
4427         sync || error "sync: $?"
4428         AFTERWRITES=$(count_ost_writes)
4429         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4430                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4431         fi
4432         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4433         start_writeback
4434         return 0
4435 }
4436 run_test 42b "test destroy of file with cached dirty data ======"
4437
4438 # if these tests just want to test the effect of truncation,
4439 # they have to be very careful.  consider:
4440 # - the first open gets a {0,EOF}PR lock
4441 # - the first write conflicts and gets a {0, count-1}PW
4442 # - the rest of the writes are under {count,EOF}PW
4443 # - the open for truncate tries to match a {0,EOF}PR
4444 #   for the filesize and cancels the PWs.
4445 # any number of fixes (don't get {0,EOF} on open, match
4446 # composite locks, do smarter file size management) fix
4447 # this, but for now we want these tests to verify that
4448 # the cancellation with truncate intent works, so we
4449 # start the file with a full-file pw lock to match against
4450 # until the truncate.
4451 trunc_test() {
4452         test=$1
4453         file=$DIR/$test
4454         offset=$2
4455         cancel_lru_locks $OSC
4456         stop_writeback
4457         # prime the file with 0,EOF PW to match
4458         touch $file
4459         $TRUNCATE $file 0
4460         sync; sync
4461         # now the real test..
4462         dd if=/dev/zero of=$file bs=1024 count=100
4463         BEFOREWRITES=`count_ost_writes`
4464         $TRUNCATE $file $offset
4465         cancel_lru_locks $OSC
4466         AFTERWRITES=`count_ost_writes`
4467         start_writeback
4468 }
4469
4470 test_42c() {
4471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4472
4473         trunc_test 42c 1024
4474         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4475                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4476         rm $file
4477 }
4478 run_test 42c "test partial truncate of file with cached dirty data"
4479
4480 test_42d() {
4481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4482
4483         trunc_test 42d 0
4484         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4485                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4486         rm $file
4487 }
4488 run_test 42d "test complete truncate of file with cached dirty data"
4489
4490 test_42e() { # bug22074
4491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4492
4493         local TDIR=$DIR/${tdir}e
4494         local pages=16 # hardcoded 16 pages, don't change it.
4495         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4496         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4497         local max_dirty_mb
4498         local warmup_files
4499
4500         test_mkdir $DIR/${tdir}e
4501         $LFS setstripe -c 1 $TDIR
4502         createmany -o $TDIR/f $files
4503
4504         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4505
4506         # we assume that with $OSTCOUNT files, at least one of them will
4507         # be allocated on OST0.
4508         warmup_files=$((OSTCOUNT * max_dirty_mb))
4509         createmany -o $TDIR/w $warmup_files
4510
4511         # write a large amount of data into one file and sync, to get good
4512         # avail_grant number from OST.
4513         for ((i=0; i<$warmup_files; i++)); do
4514                 idx=$($LFS getstripe -i $TDIR/w$i)
4515                 [ $idx -ne 0 ] && continue
4516                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4517                 break
4518         done
4519         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4520         sync
4521         $LCTL get_param $proc_osc0/cur_dirty_bytes
4522         $LCTL get_param $proc_osc0/cur_grant_bytes
4523
4524         # create as much dirty pages as we can while not to trigger the actual
4525         # RPCs directly. but depends on the env, VFS may trigger flush during this
4526         # period, hopefully we are good.
4527         for ((i=0; i<$warmup_files; i++)); do
4528                 idx=$($LFS getstripe -i $TDIR/w$i)
4529                 [ $idx -ne 0 ] && continue
4530                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4531         done
4532         $LCTL get_param $proc_osc0/cur_dirty_bytes
4533         $LCTL get_param $proc_osc0/cur_grant_bytes
4534
4535         # perform the real test
4536         $LCTL set_param $proc_osc0/rpc_stats 0
4537         for ((;i<$files; i++)); do
4538                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4539                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4540         done
4541         sync
4542         $LCTL get_param $proc_osc0/rpc_stats
4543
4544         local percent=0
4545         local have_ppr=false
4546         $LCTL get_param $proc_osc0/rpc_stats |
4547                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4548                         # skip lines until we are at the RPC histogram data
4549                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4550                         $have_ppr || continue
4551
4552                         # we only want the percent stat for < 16 pages
4553                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4554
4555                         percent=$((percent + WPCT))
4556                         if [[ $percent -gt 15 ]]; then
4557                                 error "less than 16-pages write RPCs" \
4558                                       "$percent% > 15%"
4559                                 break
4560                         fi
4561                 done
4562         rm -rf $TDIR
4563 }
4564 run_test 42e "verify sub-RPC writes are not done synchronously"
4565
4566 test_43A() { # was test_43
4567         test_mkdir $DIR/$tdir
4568         cp -p /bin/ls $DIR/$tdir/$tfile
4569         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4570         pid=$!
4571         # give multiop a chance to open
4572         sleep 1
4573
4574         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4575         kill -USR1 $pid
4576 }
4577 run_test 43A "execution of file opened for write should return -ETXTBSY"
4578
4579 test_43a() {
4580         test_mkdir $DIR/$tdir
4581         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4582         $DIR/$tdir/sleep 60 &
4583         SLEEP_PID=$!
4584         # Make sure exec of $tdir/sleep wins race with truncate
4585         sleep 1
4586         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4587         kill $SLEEP_PID
4588 }
4589 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4590
4591 test_43b() {
4592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4593
4594         test_mkdir $DIR/$tdir
4595         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4596         $DIR/$tdir/sleep 60 &
4597         SLEEP_PID=$!
4598         # Make sure exec of $tdir/sleep wins race with truncate
4599         sleep 1
4600         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4601         kill $SLEEP_PID
4602 }
4603 run_test 43b "truncate of file being executed should return -ETXTBSY"
4604
4605 test_43c() {
4606         local testdir="$DIR/$tdir"
4607         test_mkdir $testdir
4608         cp $SHELL $testdir/
4609         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4610                 ( cd $testdir && md5sum -c )
4611 }
4612 run_test 43c "md5sum of copy into lustre"
4613
4614 test_44A() { # was test_44
4615         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4616
4617         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4618         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4619 }
4620 run_test 44A "zero length read from a sparse stripe"
4621
4622 test_44a() {
4623         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4624                 awk '{ print $2 }')
4625         [ -z "$nstripe" ] && skip "can't get stripe info"
4626         [[ $nstripe -gt $OSTCOUNT ]] &&
4627                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4628
4629         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4630                 awk '{ print $2 }')
4631         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4632                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4633                         awk '{ print $2 }')
4634         fi
4635
4636         OFFSETS="0 $((stride/2)) $((stride-1))"
4637         for offset in $OFFSETS; do
4638                 for i in $(seq 0 $((nstripe-1))); do
4639                         local GLOBALOFFSETS=""
4640                         # size in Bytes
4641                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4642                         local myfn=$DIR/d44a-$size
4643                         echo "--------writing $myfn at $size"
4644                         ll_sparseness_write $myfn $size ||
4645                                 error "ll_sparseness_write"
4646                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4647                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4648                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4649
4650                         for j in $(seq 0 $((nstripe-1))); do
4651                                 # size in Bytes
4652                                 size=$((((j + $nstripe )*$stride + $offset)))
4653                                 ll_sparseness_write $myfn $size ||
4654                                         error "ll_sparseness_write"
4655                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4656                         done
4657                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4658                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4659                         rm -f $myfn
4660                 done
4661         done
4662 }
4663 run_test 44a "test sparse pwrite ==============================="
4664
4665 dirty_osc_total() {
4666         tot=0
4667         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4668                 tot=$(($tot + $d))
4669         done
4670         echo $tot
4671 }
4672 do_dirty_record() {
4673         before=`dirty_osc_total`
4674         echo executing "\"$*\""
4675         eval $*
4676         after=`dirty_osc_total`
4677         echo before $before, after $after
4678 }
4679 test_45() {
4680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4681
4682         f="$DIR/f45"
4683         # Obtain grants from OST if it supports it
4684         echo blah > ${f}_grant
4685         stop_writeback
4686         sync
4687         do_dirty_record "echo blah > $f"
4688         [[ $before -eq $after ]] && error "write wasn't cached"
4689         do_dirty_record "> $f"
4690         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4691         do_dirty_record "echo blah > $f"
4692         [[ $before -eq $after ]] && error "write wasn't cached"
4693         do_dirty_record "sync"
4694         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4695         do_dirty_record "echo blah > $f"
4696         [[ $before -eq $after ]] && error "write wasn't cached"
4697         do_dirty_record "cancel_lru_locks osc"
4698         [[ $before -gt $after ]] ||
4699                 error "lock cancellation didn't lower dirty count"
4700         start_writeback
4701 }
4702 run_test 45 "osc io page accounting ============================"
4703
4704 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4705 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4706 # objects offset and an assert hit when an rpc was built with 1023's mapped
4707 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4708 test_46() {
4709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4710
4711         f="$DIR/f46"
4712         stop_writeback
4713         sync
4714         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4715         sync
4716         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4717         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4718         sync
4719         start_writeback
4720 }
4721 run_test 46 "dirtying a previously written page ================"
4722
4723 # test_47 is removed "Device nodes check" is moved to test_28
4724
4725 test_48a() { # bug 2399
4726         [ "$mds1_FSTYPE" = "zfs" ] &&
4727         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4728                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4729
4730         test_mkdir $DIR/$tdir
4731         cd $DIR/$tdir
4732         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4733         test_mkdir $DIR/$tdir
4734         touch foo || error "'touch foo' failed after recreating cwd"
4735         test_mkdir bar
4736         touch .foo || error "'touch .foo' failed after recreating cwd"
4737         test_mkdir .bar
4738         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4739         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4740         cd . || error "'cd .' failed after recreating cwd"
4741         mkdir . && error "'mkdir .' worked after recreating cwd"
4742         rmdir . && error "'rmdir .' worked after recreating cwd"
4743         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4744         cd .. || error "'cd ..' failed after recreating cwd"
4745 }
4746 run_test 48a "Access renamed working dir (should return errors)="
4747
4748 test_48b() { # bug 2399
4749         rm -rf $DIR/$tdir
4750         test_mkdir $DIR/$tdir
4751         cd $DIR/$tdir
4752         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4753         touch foo && error "'touch foo' worked after removing cwd"
4754         mkdir foo && error "'mkdir foo' worked after removing cwd"
4755         touch .foo && error "'touch .foo' worked after removing cwd"
4756         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4757         ls . > /dev/null && error "'ls .' worked after removing cwd"
4758         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4759         mkdir . && error "'mkdir .' worked after removing cwd"
4760         rmdir . && error "'rmdir .' worked after removing cwd"
4761         ln -s . foo && error "'ln -s .' worked after removing cwd"
4762         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4763 }
4764 run_test 48b "Access removed working dir (should return errors)="
4765
4766 test_48c() { # bug 2350
4767         #lctl set_param debug=-1
4768         #set -vx
4769         rm -rf $DIR/$tdir
4770         test_mkdir -p $DIR/$tdir/dir
4771         cd $DIR/$tdir/dir
4772         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4773         $TRACE touch foo && error "touch foo worked after removing cwd"
4774         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4775         touch .foo && error "touch .foo worked after removing cwd"
4776         mkdir .foo && error "mkdir .foo worked after removing cwd"
4777         $TRACE ls . && error "'ls .' worked after removing cwd"
4778         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4779         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4780         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4781         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4782         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4783 }
4784 run_test 48c "Access removed working subdir (should return errors)"
4785
4786 test_48d() { # bug 2350
4787         #lctl set_param debug=-1
4788         #set -vx
4789         rm -rf $DIR/$tdir
4790         test_mkdir -p $DIR/$tdir/dir
4791         cd $DIR/$tdir/dir
4792         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4793         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4794         $TRACE touch foo && error "'touch foo' worked after removing parent"
4795         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4796         touch .foo && error "'touch .foo' worked after removing parent"
4797         mkdir .foo && error "mkdir .foo worked after removing parent"
4798         $TRACE ls . && error "'ls .' worked after removing parent"
4799         $TRACE ls .. && error "'ls ..' worked after removing parent"
4800         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4801         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4802         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4803         true
4804 }
4805 run_test 48d "Access removed parent subdir (should return errors)"
4806
4807 test_48e() { # bug 4134
4808         #lctl set_param debug=-1
4809         #set -vx
4810         rm -rf $DIR/$tdir
4811         test_mkdir -p $DIR/$tdir/dir
4812         cd $DIR/$tdir/dir
4813         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4814         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4815         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4816         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4817         # On a buggy kernel addition of "touch foo" after cd .. will
4818         # produce kernel oops in lookup_hash_it
4819         touch ../foo && error "'cd ..' worked after recreate parent"
4820         cd $DIR
4821         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4822 }
4823 run_test 48e "Access to recreated parent subdir (should return errors)"
4824
4825 test_49() { # LU-1030
4826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4827         remote_ost_nodsh && skip "remote OST with nodsh"
4828
4829         # get ost1 size - lustre-OST0000
4830         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4831                 awk '{ print $4 }')
4832         # write 800M at maximum
4833         [[ $ost1_size -lt 2 ]] && ost1_size=2
4834         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4835
4836         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4837         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4838         local dd_pid=$!
4839
4840         # change max_pages_per_rpc while writing the file
4841         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4842         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4843         # loop until dd process exits
4844         while ps ax -opid | grep -wq $dd_pid; do
4845                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4846                 sleep $((RANDOM % 5 + 1))
4847         done
4848         # restore original max_pages_per_rpc
4849         $LCTL set_param $osc1_mppc=$orig_mppc
4850         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4851 }
4852 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4853
4854 test_50() {
4855         # bug 1485
4856         test_mkdir $DIR/$tdir
4857         cd $DIR/$tdir
4858         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4859 }
4860 run_test 50 "special situations: /proc symlinks  ==============="
4861
4862 test_51a() {    # was test_51
4863         # bug 1516 - create an empty entry right after ".." then split dir
4864         test_mkdir -c1 $DIR/$tdir
4865         touch $DIR/$tdir/foo
4866         $MCREATE $DIR/$tdir/bar
4867         rm $DIR/$tdir/foo
4868         createmany -m $DIR/$tdir/longfile 201
4869         FNUM=202
4870         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4871                 $MCREATE $DIR/$tdir/longfile$FNUM
4872                 FNUM=$(($FNUM + 1))
4873                 echo -n "+"
4874         done
4875         echo
4876         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4877 }
4878 run_test 51a "special situations: split htree with empty entry =="
4879
4880 cleanup_print_lfs_df () {
4881         trap 0
4882         $LFS df
4883         $LFS df -i
4884 }
4885
4886 test_51b() {
4887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4888
4889         local dir=$DIR/$tdir
4890         local nrdirs=$((65536 + 100))
4891
4892         # cleanup the directory
4893         rm -fr $dir
4894
4895         test_mkdir -c1 $dir
4896
4897         $LFS df
4898         $LFS df -i
4899         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
4900         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4901         [[ $numfree -lt $nrdirs ]] &&
4902                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
4903
4904         # need to check free space for the directories as well
4905         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4906         numfree=$(( blkfree / $(fs_inode_ksize) ))
4907         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
4908
4909         trap cleanup_print_lfs_df EXIT
4910
4911         # create files
4912         createmany -d $dir/d $nrdirs || {
4913                 unlinkmany $dir/d $nrdirs
4914                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4915         }
4916
4917         # really created :
4918         nrdirs=$(ls -U $dir | wc -l)
4919
4920         # unlink all but 100 subdirectories, then check it still works
4921         local left=100
4922         local delete=$((nrdirs - left))
4923
4924         $LFS df
4925         $LFS df -i
4926
4927         # for ldiskfs the nlink count should be 1, but this is OSD specific
4928         # and so this is listed for informational purposes only
4929         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4930         unlinkmany -d $dir/d $delete ||
4931                 error "unlink of first $delete subdirs failed"
4932
4933         echo "nlink between: $(stat -c %h $dir)"
4934         local found=$(ls -U $dir | wc -l)
4935         [ $found -ne $left ] &&
4936                 error "can't find subdirs: found only $found, expected $left"
4937
4938         unlinkmany -d $dir/d $delete $left ||
4939                 error "unlink of second $left subdirs failed"
4940         # regardless of whether the backing filesystem tracks nlink accurately
4941         # or not, the nlink count shouldn't be more than "." and ".." here
4942         local after=$(stat -c %h $dir)
4943         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4944                 echo "nlink after: $after"
4945
4946         cleanup_print_lfs_df
4947 }
4948 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4949
4950 test_51d() {
4951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4952         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
4953
4954         test_mkdir $DIR/$tdir
4955         createmany -o $DIR/$tdir/t- 1000
4956         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4957         for N in $(seq 0 $((OSTCOUNT - 1))); do
4958                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4959                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4960                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4961                         '($1 == '$N') { objs += 1 } \
4962                         END { printf("%0.0f", objs) }')
4963                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4964         done
4965         unlinkmany $DIR/$tdir/t- 1000
4966
4967         NLAST=0
4968         for N in $(seq 1 $((OSTCOUNT - 1))); do
4969                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4970                         error "OST $N has less objects vs OST $NLAST" \
4971                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4972                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4973                         error "OST $N has less objects vs OST $NLAST" \
4974                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4975
4976                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4977                         error "OST $N has less #0 objects vs OST $NLAST" \
4978                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4979                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4980                         error "OST $N has less #0 objects vs OST $NLAST" \
4981                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4982                 NLAST=$N
4983         done
4984         rm -f $TMP/$tfile
4985 }
4986 run_test 51d "check object distribution"
4987
4988 test_51e() {
4989         if [ "$mds1_FSTYPE" != ldiskfs ]; then
4990                 skip_env "ldiskfs only test"
4991         fi
4992
4993         test_mkdir -c1 $DIR/$tdir
4994         test_mkdir -c1 $DIR/$tdir/d0
4995
4996         touch $DIR/$tdir/d0/foo
4997         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
4998                 error "file exceed 65000 nlink limit!"
4999         unlinkmany $DIR/$tdir/d0/f- 65001
5000         return 0
5001 }
5002 run_test 51e "check file nlink limit"
5003
5004 test_51f() {
5005         test_mkdir $DIR/$tdir
5006
5007         local max=100000
5008         local ulimit_old=$(ulimit -n)
5009         local spare=20 # number of spare fd's for scripts/libraries, etc.
5010         local mdt=$($LFS getstripe -m $DIR/$tdir)
5011         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5012
5013         echo "MDT$mdt numfree=$numfree, max=$max"
5014         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5015         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5016                 while ! ulimit -n $((numfree + spare)); do
5017                         numfree=$((numfree * 3 / 4))
5018                 done
5019                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5020         else
5021                 echo "left ulimit at $ulimit_old"
5022         fi
5023
5024         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5025                 unlinkmany $DIR/$tdir/f $numfree
5026                 error "create+open $numfree files in $DIR/$tdir failed"
5027         }
5028         ulimit -n $ulimit_old
5029
5030         # if createmany exits at 120s there will be fewer than $numfree files
5031         unlinkmany $DIR/$tdir/f $numfree || true
5032 }
5033 run_test 51f "check many open files limit"
5034
5035 test_52a() {
5036         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5037         test_mkdir $DIR/$tdir
5038         touch $DIR/$tdir/foo
5039         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5040         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5041         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5042         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5043         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5044                                         error "link worked"
5045         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5046         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5047         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5048                                                      error "lsattr"
5049         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5050         cp -r $DIR/$tdir $TMP/
5051         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5052 }
5053 run_test 52a "append-only flag test (should return errors)"
5054
5055 test_52b() {
5056         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5057         test_mkdir $DIR/$tdir
5058         touch $DIR/$tdir/foo
5059         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5060         cat test > $DIR/$tdir/foo && error "cat test worked"
5061         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5062         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5063         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5064                                         error "link worked"
5065         echo foo >> $DIR/$tdir/foo && error "echo worked"
5066         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5067         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5068         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5069         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5070                                                         error "lsattr"
5071         chattr -i $DIR/$tdir/foo || error "chattr failed"
5072
5073         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5074 }
5075 run_test 52b "immutable flag test (should return errors) ======="
5076
5077 test_53() {
5078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5079         remote_mds_nodsh && skip "remote MDS with nodsh"
5080         remote_ost_nodsh && skip "remote OST with nodsh"
5081
5082         local param
5083         local param_seq
5084         local ostname
5085         local mds_last
5086         local mds_last_seq
5087         local ost_last
5088         local ost_last_seq
5089         local ost_last_id
5090         local ostnum
5091         local node
5092         local found=false
5093         local support_last_seq=true
5094
5095         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5096                 support_last_seq=false
5097
5098         # only test MDT0000
5099         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5100         local value
5101         for value in $(do_facet $SINGLEMDS \
5102                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5103                 param=$(echo ${value[0]} | cut -d "=" -f1)
5104                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5105
5106                 if $support_last_seq; then
5107                         param_seq=$(echo $param |
5108                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5109                         mds_last_seq=$(do_facet $SINGLEMDS \
5110                                        $LCTL get_param -n $param_seq)
5111                 fi
5112                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5113
5114                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5115                 node=$(facet_active_host ost$((ostnum+1)))
5116                 param="obdfilter.$ostname.last_id"
5117                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5118                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5119                         ost_last_id=$ost_last
5120
5121                         if $support_last_seq; then
5122                                 ost_last_id=$(echo $ost_last |
5123                                               awk -F':' '{print $2}' |
5124                                               sed -e "s/^0x//g")
5125                                 ost_last_seq=$(echo $ost_last |
5126                                                awk -F':' '{print $1}')
5127                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5128                         fi
5129
5130                         if [[ $ost_last_id != $mds_last ]]; then
5131                                 error "$ost_last_id != $mds_last"
5132                         else
5133                                 found=true
5134                                 break
5135                         fi
5136                 done
5137         done
5138         $found || error "can not match last_seq/last_id for $mdtosc"
5139         return 0
5140 }
5141 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5142
5143 test_54a() {
5144         perl -MSocket -e ';' || skip "no Socket perl module installed"
5145
5146         $SOCKETSERVER $DIR/socket ||
5147                 error "$SOCKETSERVER $DIR/socket failed: $?"
5148         $SOCKETCLIENT $DIR/socket ||
5149                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5150         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5151 }
5152 run_test 54a "unix domain socket test =========================="
5153
5154 test_54b() {
5155         f="$DIR/f54b"
5156         mknod $f c 1 3
5157         chmod 0666 $f
5158         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5159 }
5160 run_test 54b "char device works in lustre ======================"
5161
5162 find_loop_dev() {
5163         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5164         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5165         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5166
5167         for i in $(seq 3 7); do
5168                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5169                 LOOPDEV=$LOOPBASE$i
5170                 LOOPNUM=$i
5171                 break
5172         done
5173 }
5174
5175 cleanup_54c() {
5176         local rc=0
5177         loopdev="$DIR/loop54c"
5178
5179         trap 0
5180         $UMOUNT $DIR/$tdir || rc=$?
5181         losetup -d $loopdev || true
5182         losetup -d $LOOPDEV || true
5183         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5184         return $rc
5185 }
5186
5187 test_54c() {
5188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5189
5190         loopdev="$DIR/loop54c"
5191
5192         find_loop_dev
5193         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5194         trap cleanup_54c EXIT
5195         mknod $loopdev b 7 $LOOPNUM
5196         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5197         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5198         losetup $loopdev $DIR/$tfile ||
5199                 error "can't set up $loopdev for $DIR/$tfile"
5200         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5201         test_mkdir $DIR/$tdir
5202         mount -t ext2 $loopdev $DIR/$tdir ||
5203                 error "error mounting $loopdev on $DIR/$tdir"
5204         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5205                 error "dd write"
5206         df $DIR/$tdir
5207         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5208                 error "dd read"
5209         cleanup_54c
5210 }
5211 run_test 54c "block device works in lustre ====================="
5212
5213 test_54d() {
5214         f="$DIR/f54d"
5215         string="aaaaaa"
5216         mknod $f p
5217         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5218 }
5219 run_test 54d "fifo device works in lustre ======================"
5220
5221 test_54e() {
5222         f="$DIR/f54e"
5223         string="aaaaaa"
5224         cp -aL /dev/console $f
5225         echo $string > $f || error "echo $string to $f failed"
5226 }
5227 run_test 54e "console/tty device works in lustre ======================"
5228
5229 test_56a() {
5230         local numfiles=3
5231         local dir=$DIR/$tdir
5232
5233         rm -rf $dir
5234         test_mkdir -p $dir/dir
5235         for i in $(seq $numfiles); do
5236                 touch $dir/file$i
5237                 touch $dir/dir/file$i
5238         done
5239
5240         local numcomp=$($LFS getstripe --component-count $dir)
5241
5242         [[ $numcomp == 0 ]] && numcomp=1
5243
5244         # test lfs getstripe with --recursive
5245         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5246
5247         [[ $filenum -eq $((numfiles * 2)) ]] ||
5248                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5249         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5250         [[ $filenum -eq $numfiles ]] ||
5251                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5252         echo "$LFS getstripe showed obdidx or l_ost_idx"
5253
5254         # test lfs getstripe with file instead of dir
5255         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5256         [[ $filenum -eq 1 ]] ||
5257                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5258         echo "$LFS getstripe file1 passed"
5259
5260         #test lfs getstripe with --verbose
5261         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5262         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5263                 error "$LFS getstripe --verbose $dir: "\
5264                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5265         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5266                 error "$LFS getstripe $dir: showed lmm_magic"
5267
5268         #test lfs getstripe with -v prints lmm_fid
5269         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5270         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5271                 error "$LFS getstripe -v $dir: "\
5272                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5273         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5274                 error "$LFS getstripe $dir: showed lmm_fid by default"
5275         echo "$LFS getstripe --verbose passed"
5276
5277         #check for FID information
5278         local fid1=$($LFS getstripe --fid $dir/file1)
5279         local fid2=$($LFS getstripe --verbose $dir/file1 |
5280                      awk '/lmm_fid: / { print $2; exit; }')
5281         local fid3=$($LFS path2fid $dir/file1)
5282
5283         [ "$fid1" != "$fid2" ] &&
5284                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5285         [ "$fid1" != "$fid3" ] &&
5286                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5287         echo "$LFS getstripe --fid passed"
5288
5289         #test lfs getstripe with --obd
5290         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5291                 error "$LFS getstripe --obd wrong_uuid: should return error"
5292
5293         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5294
5295         local ostidx=1
5296         local obduuid=$(ostuuid_from_index $ostidx)
5297         local found=$($LFS getstripe -r --obd $obduuid $dir |
5298                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5299
5300         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5301         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5302                 ((filenum--))
5303         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5304                 ((filenum--))
5305
5306         [[ $found -eq $filenum ]] ||
5307                 error "$LFS getstripe --obd: found $found expect $filenum"
5308         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5309                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5310                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5311                 error "$LFS getstripe --obd: should not show file on other obd"
5312         echo "$LFS getstripe --obd passed"
5313 }
5314 run_test 56a "check $LFS getstripe"
5315
5316 test_56b() {
5317         local dir=$DIR/$tdir
5318         local numdirs=3
5319
5320         test_mkdir $dir
5321         for i in $(seq $numdirs); do
5322                 test_mkdir $dir/dir$i
5323         done
5324
5325         # test lfs getdirstripe default mode is non-recursion, which is
5326         # different from lfs getstripe
5327         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5328
5329         [[ $dircnt -eq 1 ]] ||
5330                 error "$LFS getdirstripe: found $dircnt, not 1"
5331         dircnt=$($LFS getdirstripe --recursive $dir |
5332                 grep -c lmv_stripe_count)
5333         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5334                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5335 }
5336 run_test 56b "check $LFS getdirstripe"
5337
5338 test_56c() {
5339         remote_ost_nodsh && skip "remote OST with nodsh"
5340
5341         local ost_idx=0
5342         local ost_name=$(ostname_from_index $ost_idx)
5343         local old_status=$(ost_dev_status $ost_idx)
5344
5345         [[ -z "$old_status" ]] ||
5346                 skip_env "OST $ost_name is in $old_status status"
5347
5348         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5349         sleep_maxage
5350
5351         local new_status=$(ost_dev_status $ost_idx)
5352
5353         [[ "$new_status" = "D" ]] ||
5354                 error "OST $ost_name is in status of '$new_status', not 'D'"
5355
5356         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5357         sleep_maxage
5358
5359         new_status=$(ost_dev_status $ost_idx)
5360         [[ -z "$new_status" ]] ||
5361                 error "OST $ost_name is in status of '$new_status', not ''"
5362 }
5363 run_test 56c "check 'lfs df' showing device status"
5364
5365 NUMFILES=3
5366 NUMDIRS=3
5367 setup_56() {
5368         local local_tdir="$1"
5369         local local_numfiles="$2"
5370         local local_numdirs="$3"
5371         local dir_params="$4"
5372         local dir_stripe_params="$5"
5373
5374         if [ ! -d "$local_tdir" ] ; then
5375                 test_mkdir -p $dir_stripe_params $local_tdir
5376                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5377                 for i in $(seq $local_numfiles) ; do
5378                         touch $local_tdir/file$i
5379                 done
5380                 for i in $(seq $local_numdirs) ; do
5381                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5382                         for j in $(seq $local_numfiles) ; do
5383                                 touch $local_tdir/dir$i/file$j
5384                         done
5385                 done
5386         fi
5387 }
5388
5389 setup_56_special() {
5390         local local_tdir=$1
5391         local local_numfiles=$2
5392         local local_numdirs=$3
5393
5394         setup_56 $local_tdir $local_numfiles $local_numdirs
5395
5396         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5397                 for i in $(seq $local_numfiles) ; do
5398                         mknod $local_tdir/loop${i}b b 7 $i
5399                         mknod $local_tdir/null${i}c c 1 3
5400                         ln -s $local_tdir/file1 $local_tdir/link${i}
5401                 done
5402                 for i in $(seq $local_numdirs) ; do
5403                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5404                         mknod $local_tdir/dir$i/null${i}c c 1 3
5405                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5406                 done
5407         fi
5408 }
5409
5410 test_56g() {
5411         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5412         local expected=$(($NUMDIRS + 2))
5413
5414         setup_56 $dir $NUMFILES $NUMDIRS
5415
5416         # test lfs find with -name
5417         for i in $(seq $NUMFILES) ; do
5418                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5419
5420                 [ $nums -eq $expected ] ||
5421                         error "lfs find -name '*$i' $dir wrong: "\
5422                               "found $nums, expected $expected"
5423         done
5424 }
5425 run_test 56g "check lfs find -name"
5426
5427 test_56h() {
5428         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5429         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5430
5431         setup_56 $dir $NUMFILES $NUMDIRS
5432
5433         # test lfs find with ! -name
5434         for i in $(seq $NUMFILES) ; do
5435                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5436
5437                 [ $nums -eq $expected ] ||
5438                         error "lfs find ! -name '*$i' $dir wrong: "\
5439                               "found $nums, expected $expected"
5440         done
5441 }
5442 run_test 56h "check lfs find ! -name"
5443
5444 test_56i() {
5445         local dir=$DIR/$tdir
5446
5447         test_mkdir $dir
5448
5449         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5450         local out=$($cmd)
5451
5452         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5453 }
5454 run_test 56i "check 'lfs find -ost UUID' skips directories"
5455
5456 test_56j() {
5457         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5458
5459         setup_56_special $dir $NUMFILES $NUMDIRS
5460
5461         local expected=$((NUMDIRS + 1))
5462         local cmd="$LFS find -type d $dir"
5463         local nums=$($cmd | wc -l)
5464
5465         [ $nums -eq $expected ] ||
5466                 error "'$cmd' wrong: found $nums, expected $expected"
5467 }
5468 run_test 56j "check lfs find -type d"
5469
5470 test_56k() {
5471         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5472
5473         setup_56_special $dir $NUMFILES $NUMDIRS
5474
5475         local expected=$(((NUMDIRS + 1) * NUMFILES))
5476         local cmd="$LFS find -type f $dir"
5477         local nums=$($cmd | wc -l)
5478
5479         [ $nums -eq $expected ] ||
5480                 error "'$cmd' wrong: found $nums, expected $expected"
5481 }
5482 run_test 56k "check lfs find -type f"
5483
5484 test_56l() {
5485         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5486
5487         setup_56_special $dir $NUMFILES $NUMDIRS
5488
5489         local expected=$((NUMDIRS + NUMFILES))
5490         local cmd="$LFS find -type b $dir"
5491         local nums=$($cmd | wc -l)
5492
5493         [ $nums -eq $expected ] ||
5494                 error "'$cmd' wrong: found $nums, expected $expected"
5495 }
5496 run_test 56l "check lfs find -type b"
5497
5498 test_56m() {
5499         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5500
5501         setup_56_special $dir $NUMFILES $NUMDIRS
5502
5503         local expected=$((NUMDIRS + NUMFILES))
5504         local cmd="$LFS find -type c $dir"
5505         local nums=$($cmd | wc -l)
5506         [ $nums -eq $expected ] ||
5507                 error "'$cmd' wrong: found $nums, expected $expected"
5508 }
5509 run_test 56m "check lfs find -type c"
5510
5511 test_56n() {
5512         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5513         setup_56_special $dir $NUMFILES $NUMDIRS
5514
5515         local expected=$((NUMDIRS + NUMFILES))
5516         local cmd="$LFS find -type l $dir"
5517         local nums=$($cmd | wc -l)
5518
5519         [ $nums -eq $expected ] ||
5520                 error "'$cmd' wrong: found $nums, expected $expected"
5521 }
5522 run_test 56n "check lfs find -type l"
5523
5524 test_56o() {
5525         local dir=$DIR/$tdir
5526
5527         setup_56 $dir $NUMFILES $NUMDIRS
5528         utime $dir/file1 > /dev/null || error "utime (1)"
5529         utime $dir/file2 > /dev/null || error "utime (2)"
5530         utime $dir/dir1 > /dev/null || error "utime (3)"
5531         utime $dir/dir2 > /dev/null || error "utime (4)"
5532         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5533         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5534
5535         local expected=4
5536         local nums=$($LFS find -mtime +0 $dir | wc -l)
5537
5538         [ $nums -eq $expected ] ||
5539                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5540
5541         expected=12
5542         cmd="$LFS find -mtime 0 $dir"
5543         nums=$($cmd | wc -l)
5544         [ $nums -eq $expected ] ||
5545                 error "'$cmd' wrong: found $nums, expected $expected"
5546 }
5547 run_test 56o "check lfs find -mtime for old files"
5548
5549 test_56ob() {
5550         local dir=$DIR/$tdir
5551         local expected=1
5552         local count=0
5553
5554         # just to make sure there is something that won't be found
5555         test_mkdir $dir
5556         touch $dir/$tfile.now
5557
5558         for age in year week day hour min; do
5559                 count=$((count + 1))
5560
5561                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5562                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5563                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5564
5565                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5566                 local nums=$($cmd | wc -l)
5567                 [ $nums -eq $expected ] ||
5568                         error "'$cmd' wrong: found $nums, expected $expected"
5569
5570                 cmd="$LFS find $dir -atime $count${age:0:1}"
5571                 nums=$($cmd | wc -l)
5572                 [ $nums -eq $expected ] ||
5573                         error "'$cmd' wrong: found $nums, expected $expected"
5574         done
5575
5576         sleep 2
5577         cmd="$LFS find $dir -ctime +1s -type f"
5578         nums=$($cmd | wc -l)
5579         (( $nums == $count * 2 + 1)) ||
5580                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5581 }
5582 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5583
5584 test_56p() {
5585         [ $RUNAS_ID -eq $UID ] &&
5586                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5587
5588         local dir=$DIR/$tdir
5589
5590         setup_56 $dir $NUMFILES $NUMDIRS
5591         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5592
5593         local expected=$NUMFILES
5594         local cmd="$LFS find -uid $RUNAS_ID $dir"
5595         local nums=$($cmd | wc -l)
5596
5597         [ $nums -eq $expected ] ||
5598                 error "'$cmd' wrong: found $nums, expected $expected"
5599
5600         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5601         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5602         nums=$($cmd | wc -l)
5603         [ $nums -eq $expected ] ||
5604                 error "'$cmd' wrong: found $nums, expected $expected"
5605 }
5606 run_test 56p "check lfs find -uid and ! -uid"
5607
5608 test_56q() {
5609         [ $RUNAS_ID -eq $UID ] &&
5610                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5611
5612         local dir=$DIR/$tdir
5613
5614         setup_56 $dir $NUMFILES $NUMDIRS
5615         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5616
5617         local expected=$NUMFILES
5618         local cmd="$LFS find -gid $RUNAS_GID $dir"
5619         local nums=$($cmd | wc -l)
5620
5621         [ $nums -eq $expected ] ||
5622                 error "'$cmd' wrong: found $nums, expected $expected"
5623
5624         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5625         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5626         nums=$($cmd | wc -l)
5627         [ $nums -eq $expected ] ||
5628                 error "'$cmd' wrong: found $nums, expected $expected"
5629 }
5630 run_test 56q "check lfs find -gid and ! -gid"
5631
5632 test_56r() {
5633         local dir=$DIR/$tdir
5634
5635         setup_56 $dir $NUMFILES $NUMDIRS
5636
5637         local expected=12
5638         local cmd="$LFS find -size 0 -type f $dir"
5639         local nums=$($cmd | wc -l)
5640
5641         [ $nums -eq $expected ] ||
5642                 error "'$cmd' wrong: found $nums, expected $expected"
5643         expected=0
5644         cmd="$LFS find ! -size 0 -type f $dir"
5645         nums=$($cmd | wc -l)
5646         [ $nums -eq $expected ] ||
5647                 error "'$cmd' wrong: found $nums, expected $expected"
5648         echo "test" > $dir/$tfile
5649         echo "test2" > $dir/$tfile.2 && sync
5650         expected=1
5651         cmd="$LFS find -size 5 -type f $dir"
5652         nums=$($cmd | wc -l)
5653         [ $nums -eq $expected ] ||
5654                 error "'$cmd' wrong: found $nums, expected $expected"
5655         expected=1
5656         cmd="$LFS find -size +5 -type f $dir"
5657         nums=$($cmd | wc -l)
5658         [ $nums -eq $expected ] ||
5659                 error "'$cmd' wrong: found $nums, expected $expected"
5660         expected=2
5661         cmd="$LFS find -size +0 -type f $dir"
5662         nums=$($cmd | wc -l)
5663         [ $nums -eq $expected ] ||
5664                 error "'$cmd' wrong: found $nums, expected $expected"
5665         expected=2
5666         cmd="$LFS find ! -size -5 -type f $dir"
5667         nums=$($cmd | wc -l)
5668         [ $nums -eq $expected ] ||
5669                 error "'$cmd' wrong: found $nums, expected $expected"
5670         expected=12
5671         cmd="$LFS find -size -5 -type f $dir"
5672         nums=$($cmd | wc -l)
5673         [ $nums -eq $expected ] ||
5674                 error "'$cmd' wrong: found $nums, expected $expected"
5675 }
5676 run_test 56r "check lfs find -size works"
5677
5678 test_56s() { # LU-611 #LU-9369
5679         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5680
5681         local dir=$DIR/$tdir
5682         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5683
5684         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5685         for i in $(seq $NUMDIRS); do
5686                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5687         done
5688
5689         local expected=$NUMDIRS
5690         local cmd="$LFS find -c $OSTCOUNT $dir"
5691         local nums=$($cmd | wc -l)
5692
5693         [ $nums -eq $expected ] || {
5694                 $LFS getstripe -R $dir
5695                 error "'$cmd' wrong: found $nums, expected $expected"
5696         }
5697
5698         expected=$((NUMDIRS + onestripe))
5699         cmd="$LFS find -stripe-count +0 -type f $dir"
5700         nums=$($cmd | wc -l)
5701         [ $nums -eq $expected ] || {
5702                 $LFS getstripe -R $dir
5703                 error "'$cmd' wrong: found $nums, expected $expected"
5704         }
5705
5706         expected=$onestripe
5707         cmd="$LFS find -stripe-count 1 -type f $dir"
5708         nums=$($cmd | wc -l)
5709         [ $nums -eq $expected ] || {
5710                 $LFS getstripe -R $dir
5711                 error "'$cmd' wrong: found $nums, expected $expected"
5712         }
5713
5714         cmd="$LFS find -stripe-count -2 -type f $dir"
5715         nums=$($cmd | wc -l)
5716         [ $nums -eq $expected ] || {
5717                 $LFS getstripe -R $dir
5718                 error "'$cmd' wrong: found $nums, expected $expected"
5719         }
5720
5721         expected=0
5722         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5723         nums=$($cmd | wc -l)
5724         [ $nums -eq $expected ] || {
5725                 $LFS getstripe -R $dir
5726                 error "'$cmd' wrong: found $nums, expected $expected"
5727         }
5728 }
5729 run_test 56s "check lfs find -stripe-count works"
5730
5731 test_56t() { # LU-611 #LU-9369
5732         local dir=$DIR/$tdir
5733
5734         setup_56 $dir 0 $NUMDIRS
5735         for i in $(seq $NUMDIRS); do
5736                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5737         done
5738
5739         local expected=$NUMDIRS
5740         local cmd="$LFS find -S 8M $dir"
5741         local nums=$($cmd | wc -l)
5742
5743         [ $nums -eq $expected ] || {
5744                 $LFS getstripe -R $dir
5745                 error "'$cmd' wrong: found $nums, expected $expected"
5746         }
5747         rm -rf $dir
5748
5749         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5750
5751         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5752
5753         expected=$(((NUMDIRS + 1) * NUMFILES))
5754         cmd="$LFS find -stripe-size 512k -type f $dir"
5755         nums=$($cmd | wc -l)
5756         [ $nums -eq $expected ] ||
5757                 error "'$cmd' wrong: found $nums, expected $expected"
5758
5759         cmd="$LFS find -stripe-size +320k -type f $dir"
5760         nums=$($cmd | wc -l)
5761         [ $nums -eq $expected ] ||
5762                 error "'$cmd' wrong: found $nums, expected $expected"
5763
5764         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5765         cmd="$LFS find -stripe-size +200k -type f $dir"
5766         nums=$($cmd | wc -l)
5767         [ $nums -eq $expected ] ||
5768                 error "'$cmd' wrong: found $nums, expected $expected"
5769
5770         cmd="$LFS find -stripe-size -640k -type f $dir"
5771         nums=$($cmd | wc -l)
5772         [ $nums -eq $expected ] ||
5773                 error "'$cmd' wrong: found $nums, expected $expected"
5774
5775         expected=4
5776         cmd="$LFS find -stripe-size 256k -type f $dir"
5777         nums=$($cmd | wc -l)
5778         [ $nums -eq $expected ] ||
5779                 error "'$cmd' wrong: found $nums, expected $expected"
5780
5781         cmd="$LFS find -stripe-size -320k -type f $dir"
5782         nums=$($cmd | wc -l)
5783         [ $nums -eq $expected ] ||
5784                 error "'$cmd' wrong: found $nums, expected $expected"
5785
5786         expected=0
5787         cmd="$LFS find -stripe-size 1024k -type f $dir"
5788         nums=$($cmd | wc -l)
5789         [ $nums -eq $expected ] ||
5790                 error "'$cmd' wrong: found $nums, expected $expected"
5791 }
5792 run_test 56t "check lfs find -stripe-size works"
5793
5794 test_56u() { # LU-611
5795         local dir=$DIR/$tdir
5796
5797         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5798
5799         if [[ $OSTCOUNT -gt 1 ]]; then
5800                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5801                 onestripe=4
5802         else
5803                 onestripe=0
5804         fi
5805
5806         local expected=$(((NUMDIRS + 1) * NUMFILES))
5807         local cmd="$LFS find -stripe-index 0 -type f $dir"
5808         local nums=$($cmd | wc -l)
5809
5810         [ $nums -eq $expected ] ||
5811                 error "'$cmd' wrong: found $nums, expected $expected"
5812
5813         expected=$onestripe
5814         cmd="$LFS find -stripe-index 1 -type f $dir"
5815         nums=$($cmd | wc -l)
5816         [ $nums -eq $expected ] ||
5817                 error "'$cmd' wrong: found $nums, expected $expected"
5818
5819         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5820         nums=$($cmd | wc -l)
5821         [ $nums -eq $expected ] ||
5822                 error "'$cmd' wrong: found $nums, expected $expected"
5823
5824         expected=0
5825         # This should produce an error and not return any files
5826         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5827         nums=$($cmd 2>/dev/null | wc -l)
5828         [ $nums -eq $expected ] ||
5829                 error "'$cmd' wrong: found $nums, expected $expected"
5830
5831         if [[ $OSTCOUNT -gt 1 ]]; then
5832                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5833                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5834                 nums=$($cmd | wc -l)
5835                 [ $nums -eq $expected ] ||
5836                         error "'$cmd' wrong: found $nums, expected $expected"
5837         fi
5838 }
5839 run_test 56u "check lfs find -stripe-index works"
5840
5841 test_56v() {
5842         local mdt_idx=0
5843         local dir=$DIR/$tdir
5844
5845         setup_56 $dir $NUMFILES $NUMDIRS
5846
5847         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5848         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5849
5850         for file in $($LFS find -m $UUID $dir); do
5851                 file_midx=$($LFS getstripe -m $file)
5852                 [ $file_midx -eq $mdt_idx ] ||
5853                         error "lfs find -m $UUID != getstripe -m $file_midx"
5854         done
5855 }
5856 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5857
5858 test_56w() {
5859         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5861
5862         local dir=$DIR/$tdir
5863
5864         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5865
5866         local stripe_size=$($LFS getstripe -S -d $dir) ||
5867                 error "$LFS getstripe -S -d $dir failed"
5868         stripe_size=${stripe_size%% *}
5869
5870         local file_size=$((stripe_size * OSTCOUNT))
5871         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5872         local required_space=$((file_num * file_size))
5873         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5874                            head -n1)
5875         [[ $free_space -le $((required_space / 1024)) ]] &&
5876                 skip_env "need $required_space, have $free_space kbytes"
5877
5878         local dd_bs=65536
5879         local dd_count=$((file_size / dd_bs))
5880
5881         # write data into the files
5882         local i
5883         local j
5884         local file
5885
5886         for i in $(seq $NUMFILES); do
5887                 file=$dir/file$i
5888                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5889                         error "write data into $file failed"
5890         done
5891         for i in $(seq $NUMDIRS); do
5892                 for j in $(seq $NUMFILES); do
5893                         file=$dir/dir$i/file$j
5894                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5895                                 error "write data into $file failed"
5896                 done
5897         done
5898
5899         # $LFS_MIGRATE will fail if hard link migration is unsupported
5900         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5901                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5902                         error "creating links to $dir/dir1/file1 failed"
5903         fi
5904
5905         local expected=-1
5906
5907         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5908
5909         # lfs_migrate file
5910         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5911
5912         echo "$cmd"
5913         eval $cmd || error "$cmd failed"
5914
5915         check_stripe_count $dir/file1 $expected
5916
5917         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5918         then
5919                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5920                 # OST 1 if it is on OST 0. This file is small enough to
5921                 # be on only one stripe.
5922                 file=$dir/migr_1_ost
5923                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5924                         error "write data into $file failed"
5925                 local obdidx=$($LFS getstripe -i $file)
5926                 local oldmd5=$(md5sum $file)
5927                 local newobdidx=0
5928
5929                 [[ $obdidx -eq 0 ]] && newobdidx=1
5930                 cmd="$LFS migrate -i $newobdidx $file"
5931                 echo $cmd
5932                 eval $cmd || error "$cmd failed"
5933
5934                 local realobdix=$($LFS getstripe -i $file)
5935                 local newmd5=$(md5sum $file)
5936
5937                 [[ $newobdidx -ne $realobdix ]] &&
5938                         error "new OST is different (was=$obdidx, "\
5939                               "wanted=$newobdidx, got=$realobdix)"
5940                 [[ "$oldmd5" != "$newmd5" ]] &&
5941                         error "md5sum differ: $oldmd5, $newmd5"
5942         fi
5943
5944         # lfs_migrate dir
5945         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5946         echo "$cmd"
5947         eval $cmd || error "$cmd failed"
5948
5949         for j in $(seq $NUMFILES); do
5950                 check_stripe_count $dir/dir1/file$j $expected
5951         done
5952
5953         # lfs_migrate works with lfs find
5954         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5955              $LFS_MIGRATE -y -c $expected"
5956         echo "$cmd"
5957         eval $cmd || error "$cmd failed"
5958
5959         for i in $(seq 2 $NUMFILES); do
5960                 check_stripe_count $dir/file$i $expected
5961         done
5962         for i in $(seq 2 $NUMDIRS); do
5963                 for j in $(seq $NUMFILES); do
5964                 check_stripe_count $dir/dir$i/file$j $expected
5965                 done
5966         done
5967 }
5968 run_test 56w "check lfs_migrate -c stripe_count works"
5969
5970 test_56wb() {
5971         local file1=$DIR/$tdir/file1
5972         local create_pool=false
5973         local initial_pool=$($LFS getstripe -p $DIR)
5974         local pool_list=()
5975         local pool=""
5976
5977         echo -n "Creating test dir..."
5978         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5979         echo "done."
5980
5981         echo -n "Creating test file..."
5982         touch $file1 || error "cannot create file"
5983         echo "done."
5984
5985         echo -n "Detecting existing pools..."
5986         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
5987
5988         if [ ${#pool_list[@]} -gt 0 ]; then
5989                 echo "${pool_list[@]}"
5990                 for thispool in "${pool_list[@]}"; do
5991                         if [[ -z "$initial_pool" ||
5992                               "$initial_pool" != "$thispool" ]]; then
5993                                 pool="$thispool"
5994                                 echo "Using existing pool '$pool'"
5995                                 break
5996                         fi
5997                 done
5998         else
5999                 echo "none detected."
6000         fi
6001         if [ -z "$pool" ]; then
6002                 pool=${POOL:-testpool}
6003                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6004                 echo -n "Creating pool '$pool'..."
6005                 create_pool=true
6006                 pool_add $pool &> /dev/null ||
6007                         error "pool_add failed"
6008                 echo "done."
6009
6010                 echo -n "Adding target to pool..."
6011                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6012                         error "pool_add_targets failed"
6013                 echo "done."
6014         fi
6015
6016         echo -n "Setting pool using -p option..."
6017         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6018                 error "migrate failed rc = $?"
6019         echo "done."
6020
6021         echo -n "Verifying test file is in pool after migrating..."
6022         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6023                 error "file was not migrated to pool $pool"
6024         echo "done."
6025
6026         echo -n "Removing test file from pool '$pool'..."
6027         $LFS migrate $file1 &> /dev/null ||
6028                 error "cannot remove from pool"
6029         [ "$($LFS getstripe -p $file1)" ] &&
6030                 error "pool still set"
6031         echo "done."
6032
6033         echo -n "Setting pool using --pool option..."
6034         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6035                 error "migrate failed rc = $?"
6036         echo "done."
6037
6038         # Clean up
6039         rm -f $file1
6040         if $create_pool; then
6041                 destroy_test_pools 2> /dev/null ||
6042                         error "destroy test pools failed"
6043         fi
6044 }
6045 run_test 56wb "check lfs_migrate pool support"
6046
6047 test_56wc() {
6048         local file1="$DIR/$tdir/file1"
6049
6050         echo -n "Creating test dir..."
6051         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6052         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6053         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6054                 error "cannot set stripe"
6055         echo "done"
6056
6057         echo -n "Setting initial stripe for test file..."
6058         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6059                 error "cannot set stripe"
6060         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6061                 error "stripe size not set"
6062         echo "done."
6063
6064         # File currently set to -S 512K -c 1
6065
6066         # Ensure -c and -S options are rejected when -R is set
6067         echo -n "Verifying incompatible options are detected..."
6068         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6069                 error "incompatible -c and -R options not detected"
6070         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6071                 error "incompatible -S and -R options not detected"
6072         echo "done."
6073
6074         # Ensure unrecognized options are passed through to 'lfs migrate'
6075         echo -n "Verifying -S option is passed through to lfs migrate..."
6076         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6077                 error "migration failed"
6078         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
6079                 error "file was not restriped"
6080         echo "done."
6081
6082         # File currently set to -S 1M -c 1
6083
6084         # Ensure long options are supported
6085         echo -n "Verifying long options supported..."
6086         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6087                 error "long option without argument not supported"
6088         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6089                 error "long option with argument not supported"
6090         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6091                 error "file not restriped with --stripe-size option"
6092         echo "done."
6093
6094         # File currently set to -S 512K -c 1
6095
6096         if [ "$OSTCOUNT" -gt 1 ]; then
6097                 echo -n "Verifying explicit stripe count can be set..."
6098                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6099                         error "migrate failed"
6100                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
6101                         error "file not restriped to explicit count"
6102                 echo "done."
6103         fi
6104
6105         # File currently set to -S 512K -c 1 or -S 512K -c 2
6106
6107         # Ensure parent striping is used if -R is set, and no stripe
6108         # count or size is specified
6109         echo -n "Setting stripe for parent directory..."
6110         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6111                 error "cannot set stripe"
6112         echo "done."
6113
6114         echo -n "Verifying restripe option uses parent stripe settings..."
6115         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6116                 error "migrate failed"
6117         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
6118                 error "file not restriped to parent settings"
6119         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
6120                 error "file not restriped to parent settings"
6121         echo "done."
6122
6123         # File currently set to -S 1M -c 1
6124
6125         # Ensure striping is preserved if -R is not set, and no stripe
6126         # count or size is specified
6127         echo -n "Verifying striping size preserved when not specified..."
6128         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
6129         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6130                 error "cannot set stripe on parent directory"
6131         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6132                 error "migrate failed"
6133         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
6134                 error "file was restriped"
6135         echo "done."
6136
6137         # Ensure file name properly detected when final option has no argument
6138         echo -n "Verifying file name properly detected..."
6139         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6140                 error "file name interpreted as option argument"
6141         echo "done."
6142
6143         # Clean up
6144         rm -f "$file1"
6145 }
6146 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6147
6148 test_56wd() {
6149         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6150
6151         local file1=$DIR/$tdir/file1
6152
6153         echo -n "Creating test dir..."
6154         test_mkdir $DIR/$tdir || error "cannot create dir"
6155         echo "done."
6156
6157         echo -n "Creating test file..."
6158         touch $file1
6159         echo "done."
6160
6161         # Ensure 'lfs migrate' will fail by using a non-existent option,
6162         # and make sure rsync is not called to recover
6163         echo -n "Make sure --no-rsync option works..."
6164         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6165                 grep -q 'refusing to fall back to rsync' ||
6166                 error "rsync was called with --no-rsync set"
6167         echo "done."
6168
6169         # Ensure rsync is called without trying 'lfs migrate' first
6170         echo -n "Make sure --rsync option works..."
6171         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6172                 grep -q 'falling back to rsync' &&
6173                 error "lfs migrate was called with --rsync set"
6174         echo "done."
6175
6176         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6177         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6178                 grep -q 'at the same time' ||
6179                 error "--rsync and --no-rsync accepted concurrently"
6180         echo "done."
6181
6182         # Clean up
6183         rm -f $file1
6184 }
6185 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6186
6187 test_56x() {
6188         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6189         check_swap_layouts_support
6190
6191         local dir=$DIR/$tdir
6192         local ref1=/etc/passwd
6193         local file1=$dir/file1
6194
6195         test_mkdir $dir || error "creating dir $dir"
6196         $LFS setstripe -c 2 $file1
6197         cp $ref1 $file1
6198         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6199         stripe=$($LFS getstripe -c $file1)
6200         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6201         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6202
6203         # clean up
6204         rm -f $file1
6205 }
6206 run_test 56x "lfs migration support"
6207
6208 test_56xa() {
6209         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6210         check_swap_layouts_support
6211
6212         local dir=$DIR/$tdir/$testnum
6213
6214         test_mkdir -p $dir
6215
6216         local ref1=/etc/passwd
6217         local file1=$dir/file1
6218
6219         $LFS setstripe -c 2 $file1
6220         cp $ref1 $file1
6221         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6222
6223         local stripe=$($LFS getstripe -c $file1)
6224
6225         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6226         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6227
6228         # clean up
6229         rm -f $file1
6230 }
6231 run_test 56xa "lfs migration --block support"
6232
6233 check_migrate_links() {
6234         local dir="$1"
6235         local file1="$dir/file1"
6236         local begin="$2"
6237         local count="$3"
6238         local total_count=$(($begin + $count - 1))
6239         local symlink_count=10
6240         local uniq_count=10
6241
6242         if [ ! -f "$file1" ]; then
6243                 echo -n "creating initial file..."
6244                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6245                         error "cannot setstripe initial file"
6246                 echo "done"
6247
6248                 echo -n "creating symlinks..."
6249                 for s in $(seq 1 $symlink_count); do
6250                         ln -s "$file1" "$dir/slink$s" ||
6251                                 error "cannot create symlinks"
6252                 done
6253                 echo "done"
6254
6255                 echo -n "creating nonlinked files..."
6256                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6257                         error "cannot create nonlinked files"
6258                 echo "done"
6259         fi
6260
6261         # create hard links
6262         if [ ! -f "$dir/file$total_count" ]; then
6263                 echo -n "creating hard links $begin:$total_count..."
6264                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6265                         /dev/null || error "cannot create hard links"
6266                 echo "done"
6267         fi
6268
6269         echo -n "checking number of hard links listed in xattrs..."
6270         local fid=$($LFS getstripe -F "$file1")
6271         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6272
6273         echo "${#paths[*]}"
6274         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6275                         skip "hard link list has unexpected size, skipping test"
6276         fi
6277         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6278                         error "link names should exceed xattrs size"
6279         fi
6280
6281         echo -n "migrating files..."
6282         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
6283         local rc=$?
6284         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6285         echo "done"
6286
6287         # make sure all links have been properly migrated
6288         echo -n "verifying files..."
6289         fid=$($LFS getstripe -F "$file1") ||
6290                 error "cannot get fid for file $file1"
6291         for i in $(seq 2 $total_count); do
6292                 local fid2=$($LFS getstripe -F $dir/file$i)
6293
6294                 [ "$fid2" == "$fid" ] ||
6295                         error "migrated hard link has mismatched FID"
6296         done
6297
6298         # make sure hard links were properly detected, and migration was
6299         # performed only once for the entire link set; nonlinked files should
6300         # also be migrated
6301         local actual=$(grep -c 'done migrate' <<< "$migrate_out")
6302         local expected=$(($uniq_count + 1))
6303
6304         [ "$actual" -eq  "$expected" ] ||
6305                 error "hard links individually migrated ($actual != $expected)"
6306
6307         # make sure the correct number of hard links are present
6308         local hardlinks=$(stat -c '%h' "$file1")
6309
6310         [ $hardlinks -eq $total_count ] ||
6311                 error "num hard links $hardlinks != $total_count"
6312         echo "done"
6313
6314         return 0
6315 }
6316
6317 test_56xb() {
6318         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6319                 skip "Need MDS version at least 2.10.55"
6320
6321         local dir="$DIR/$tdir"
6322
6323         test_mkdir "$dir" || error "cannot create dir $dir"
6324
6325         echo "testing lfs migrate mode when all links fit within xattrs"
6326         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6327
6328         echo "testing rsync mode when all links fit within xattrs"
6329         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6330
6331         echo "testing lfs migrate mode when all links do not fit within xattrs"
6332         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6333
6334         echo "testing rsync mode when all links do not fit within xattrs"
6335         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6336
6337
6338         # clean up
6339         rm -rf $dir
6340 }
6341 run_test 56xb "lfs migration hard link support"
6342
6343 test_56xc() {
6344         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6345
6346         local dir="$DIR/$tdir"
6347
6348         test_mkdir "$dir" || error "cannot create dir $dir"
6349
6350         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6351         echo -n "Setting initial stripe for 20MB test file..."
6352         $LFS setstripe -c 2 -i 0 "$dir/20mb" || error "cannot setstripe"
6353         echo "done"
6354         echo -n "Sizing 20MB test file..."
6355         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6356         echo "done"
6357         echo -n "Verifying small file autostripe count is 1..."
6358         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" &> /dev/null ||
6359                 error "cannot migrate 20MB file"
6360         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6361                 error "cannot get stripe for $dir/20mb"
6362         [ $stripe_count -eq 1 ] ||
6363                 error "unexpected stripe count $stripe_count for 20MB file"
6364         rm -f "$dir/20mb"
6365         echo "done"
6366
6367         # Test 2: File is small enough to fit within the available space on
6368         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6369         # have at least an additional 1KB for each desired stripe for test 3
6370         echo -n "Setting stripe for 1GB test file..."
6371         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe"
6372         echo "done"
6373         echo -n "Sizing 1GB test file..."
6374         # File size is 1GB + 3KB
6375         truncate "$dir/1gb" 1073744896 &> /dev/null ||
6376                 error "cannot create 1GB test file"
6377         echo "done"
6378         echo -n "Migrating 1GB file..."
6379         $LFS_MIGRATE -y -A -C 1 "$dir/1gb" &> /dev/null ||
6380                 error "cannot migrate file"
6381         echo "done"
6382         echo -n "Verifying autostripe count is sqrt(n) + 1..."
6383         stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6384                 error "cannot get stripe for $dir/1gb"
6385         [ $stripe_count -eq 2 ] ||
6386                 error "unexpected stripe count $stripe_count (expected 2)"
6387         echo "done"
6388
6389         # Test 3: File is too large to fit within the available space on
6390         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6391         if [ $OSTCOUNT -ge 3 ]; then
6392                 # The required available space is calculated as
6393                 # file size (1GB + 3KB) / OST count (3).
6394                 local kb_per_ost=349526
6395
6396                 echo -n "Migrating 1GB file..."
6397                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" &>> \
6398                         /dev/null || error "cannot migrate file"
6399                 echo "done"
6400
6401                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6402                 echo -n "Verifying autostripe count with limited space..."
6403                 [ "$stripe_count" -a $stripe_count -eq 3 ] ||
6404                         error "unexpected stripe count $stripe_count (wanted 3)"
6405                 echo "done"
6406         fi
6407
6408         # clean up
6409         rm -rf $dir
6410 }
6411 run_test 56xc "lfs migration autostripe"
6412
6413 test_56y() {
6414         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
6415                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
6416
6417         local res=""
6418         local dir=$DIR/$tdir
6419         local f1=$dir/file1
6420         local f2=$dir/file2
6421
6422         test_mkdir -p $dir || error "creating dir $dir"
6423         touch $f1 || error "creating std file $f1"
6424         $MULTIOP $f2 H2c || error "creating released file $f2"
6425
6426         # a directory can be raid0, so ask only for files
6427         res=$($LFS find $dir -L raid0 -type f | wc -l)
6428         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6429
6430         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6431         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6432
6433         # only files can be released, so no need to force file search
6434         res=$($LFS find $dir -L released)
6435         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6436
6437         res=$($LFS find $dir -type f \! -L released)
6438         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6439 }
6440 run_test 56y "lfs find -L raid0|released"
6441
6442 test_56z() { # LU-4824
6443         # This checks to make sure 'lfs find' continues after errors
6444         # There are two classes of errors that should be caught:
6445         # - If multiple paths are provided, all should be searched even if one
6446         #   errors out
6447         # - If errors are encountered during the search, it should not terminate
6448         #   early
6449         local dir=$DIR/$tdir
6450         local i
6451
6452         test_mkdir $dir
6453         for i in d{0..9}; do
6454                 test_mkdir $dir/$i
6455         done
6456         touch $dir/d{0..9}/$tfile
6457         $LFS find $DIR/non_existent_dir $dir &&
6458                 error "$LFS find did not return an error"
6459         # Make a directory unsearchable. This should NOT be the last entry in
6460         # directory order.  Arbitrarily pick the 6th entry
6461         chmod 700 $($LFS find $dir -type d | sed '6!d')
6462
6463         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6464
6465         # The user should be able to see 10 directories and 9 files
6466         [ $count == 19 ] || error "$LFS find did not continue after error"
6467 }
6468 run_test 56z "lfs find should continue after an error"
6469
6470 test_56aa() { # LU-5937
6471         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6472
6473         local dir=$DIR/$tdir
6474
6475         mkdir $dir
6476         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6477
6478         createmany -o $dir/striped_dir/${tfile}- 1024
6479         local dirs=$($LFS find --size +8k $dir/)
6480
6481         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6482 }
6483 run_test 56aa "lfs find --size under striped dir"
6484
6485 test_56ab() { # LU-10705
6486         test_mkdir $DIR/$tdir
6487         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6488         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6489         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6490         # Flush writes to ensure valid blocks.  Need to be more thorough for
6491         # ZFS, since blocks are not allocated/returned to client immediately.
6492         sync_all_data
6493         wait_zfs_commit ost1 2
6494         cancel_lru_locks osc
6495         ls -ls $DIR/$tdir
6496
6497         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6498
6499         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6500
6501         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6502         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6503
6504         rm -f $DIR/$tdir/$tfile.[123]
6505 }
6506 run_test 56ab "lfs find --blocks"
6507
6508 test_56ba() {
6509         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6510                 skip "Need MDS version at least 2.10.50"
6511
6512         # Create composite files with one component
6513         local dir=$DIR/$tdir
6514
6515         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6516         # Create composite files with three components
6517         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6518         # Create non-composite files
6519         createmany -o $dir/${tfile}- 10
6520
6521         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6522
6523         [[ $nfiles == 10 ]] ||
6524                 error "lfs find -E 1M found $nfiles != 10 files"
6525
6526         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6527         [[ $nfiles == 25 ]] ||
6528                 error "lfs find ! -E 1M found $nfiles != 25 files"
6529
6530         # All files have a component that starts at 0
6531         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6532         [[ $nfiles == 35 ]] ||
6533                 error "lfs find --component-start 0 - $nfiles != 35 files"
6534
6535         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6536         [[ $nfiles == 15 ]] ||
6537                 error "lfs find --component-start 2M - $nfiles != 15 files"
6538
6539         # All files created here have a componenet that does not starts at 2M
6540         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6541         [[ $nfiles == 35 ]] ||
6542                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6543
6544         # Find files with a specified number of components
6545         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6546         [[ $nfiles == 15 ]] ||
6547                 error "lfs find --component-count 3 - $nfiles != 15 files"
6548
6549         # Remember non-composite files have a component count of zero
6550         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6551         [[ $nfiles == 10 ]] ||
6552                 error "lfs find --component-count 0 - $nfiles != 10 files"
6553
6554         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6555         [[ $nfiles == 20 ]] ||
6556                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6557
6558         # All files have a flag called "init"
6559         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6560         [[ $nfiles == 35 ]] ||
6561                 error "lfs find --component-flags init - $nfiles != 35 files"
6562
6563         # Multi-component files will have a component not initialized
6564         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6565         [[ $nfiles == 15 ]] ||
6566                 error "lfs find !--component-flags init - $nfiles != 15 files"
6567
6568         rm -rf $dir
6569
6570 }
6571 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6572
6573 test_56ca() {
6574         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6575                 skip "Need MDS version at least 2.10.57"
6576
6577         local td=$DIR/$tdir
6578         local tf=$td/$tfile
6579         local dir
6580         local nfiles
6581         local cmd
6582         local i
6583         local j
6584
6585         # create mirrored directories and mirrored files
6586         mkdir $td || error "mkdir $td failed"
6587         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6588         createmany -o $tf- 10 || error "create $tf- failed"
6589
6590         for i in $(seq 2); do
6591                 dir=$td/dir$i
6592                 mkdir $dir || error "mkdir $dir failed"
6593                 $LFS mirror create -N$((3 + i)) $dir ||
6594                         error "create mirrored dir $dir failed"
6595                 createmany -o $dir/$tfile- 10 ||
6596                         error "create $dir/$tfile- failed"
6597         done
6598
6599         # change the states of some mirrored files
6600         echo foo > $tf-6
6601         for i in $(seq 2); do
6602                 dir=$td/dir$i
6603                 for j in $(seq 4 9); do
6604                         echo foo > $dir/$tfile-$j
6605                 done
6606         done
6607
6608         # find mirrored files with specific mirror count
6609         cmd="$LFS find --mirror-count 3 --type f $td"
6610         nfiles=$($cmd | wc -l)
6611         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6612
6613         cmd="$LFS find ! --mirror-count 3 --type f $td"
6614         nfiles=$($cmd | wc -l)
6615         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6616
6617         cmd="$LFS find --mirror-count +2 --type f $td"
6618         nfiles=$($cmd | wc -l)
6619         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6620
6621         cmd="$LFS find --mirror-count -6 --type f $td"
6622         nfiles=$($cmd | wc -l)
6623         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6624
6625         # find mirrored files with specific file state
6626         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6627         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6628
6629         cmd="$LFS find --mirror-state=ro --type f $td"
6630         nfiles=$($cmd | wc -l)
6631         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6632
6633         cmd="$LFS find ! --mirror-state=ro --type f $td"
6634         nfiles=$($cmd | wc -l)
6635         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6636
6637         cmd="$LFS find --mirror-state=wp --type f $td"
6638         nfiles=$($cmd | wc -l)
6639         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6640
6641         cmd="$LFS find ! --mirror-state=sp --type f $td"
6642         nfiles=$($cmd | wc -l)
6643         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6644 }
6645 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6646
6647 test_57a() {
6648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6649         # note test will not do anything if MDS is not local
6650         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6651                 skip_env "ldiskfs only test"
6652         fi
6653         remote_mds_nodsh && skip "remote MDS with nodsh"
6654
6655         local MNTDEV="osd*.*MDT*.mntdev"
6656         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6657         [ -z "$DEV" ] && error "can't access $MNTDEV"
6658         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6659                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6660                         error "can't access $DEV"
6661                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6662                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6663                 rm $TMP/t57a.dump
6664         done
6665 }
6666 run_test 57a "verify MDS filesystem created with large inodes =="
6667
6668 test_57b() {
6669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6670         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6671                 skip_env "ldiskfs only test"
6672         fi
6673         remote_mds_nodsh && skip "remote MDS with nodsh"
6674
6675         local dir=$DIR/$tdir
6676         local filecount=100
6677         local file1=$dir/f1
6678         local fileN=$dir/f$filecount
6679
6680         rm -rf $dir || error "removing $dir"
6681         test_mkdir -c1 $dir
6682         local mdtidx=$($LFS getstripe -m $dir)
6683         local mdtname=MDT$(printf %04x $mdtidx)
6684         local facet=mds$((mdtidx + 1))
6685
6686         echo "mcreating $filecount files"
6687         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6688
6689         # verify that files do not have EAs yet
6690         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6691                 error "$file1 has an EA"
6692         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6693                 error "$fileN has an EA"
6694
6695         sync
6696         sleep 1
6697         df $dir  #make sure we get new statfs data
6698         local mdsfree=$(do_facet $facet \
6699                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6700         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6701         local file
6702
6703         echo "opening files to create objects/EAs"
6704         for file in $(seq -f $dir/f%g 1 $filecount); do
6705                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6706                         error "opening $file"
6707         done
6708
6709         # verify that files have EAs now
6710         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6711         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6712
6713         sleep 1  #make sure we get new statfs data
6714         df $dir
6715         local mdsfree2=$(do_facet $facet \
6716                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6717         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6718
6719         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6720                 if [ "$mdsfree" != "$mdsfree2" ]; then
6721                         error "MDC before $mdcfree != after $mdcfree2"
6722                 else
6723                         echo "MDC before $mdcfree != after $mdcfree2"
6724                         echo "unable to confirm if MDS has large inodes"
6725                 fi
6726         fi
6727         rm -rf $dir
6728 }
6729 run_test 57b "default LOV EAs are stored inside large inodes ==="
6730
6731 test_58() {
6732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6733         [ -z "$(which wiretest 2>/dev/null)" ] &&
6734                         skip_env "could not find wiretest"
6735
6736         wiretest
6737 }
6738 run_test 58 "verify cross-platform wire constants =============="
6739
6740 test_59() {
6741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6742
6743         echo "touch 130 files"
6744         createmany -o $DIR/f59- 130
6745         echo "rm 130 files"
6746         unlinkmany $DIR/f59- 130
6747         sync
6748         # wait for commitment of removal
6749         wait_delete_completed
6750 }
6751 run_test 59 "verify cancellation of llog records async ========="
6752
6753 TEST60_HEAD="test_60 run $RANDOM"
6754 test_60a() {
6755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6756         remote_mgs_nodsh && skip "remote MGS with nodsh"
6757         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6758                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6759                         skip_env "missing subtest run-llog.sh"
6760
6761         log "$TEST60_HEAD - from kernel mode"
6762         do_facet mgs "$LCTL dk > /dev/null"
6763         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6764         do_facet mgs $LCTL dk > $TMP/$tfile
6765
6766         # LU-6388: test llog_reader
6767         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6768         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6769         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6770                         skip_env "missing llog_reader"
6771         local fstype=$(facet_fstype mgs)
6772         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6773                 skip_env "Only for ldiskfs or zfs type mgs"
6774
6775         local mntpt=$(facet_mntpt mgs)
6776         local mgsdev=$(mgsdevname 1)
6777         local fid_list
6778         local fid
6779         local rec_list
6780         local rec
6781         local rec_type
6782         local obj_file
6783         local path
6784         local seq
6785         local oid
6786         local pass=true
6787
6788         #get fid and record list
6789         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
6790                 tail -n 4))
6791         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
6792                 tail -n 4))
6793         #remount mgs as ldiskfs or zfs type
6794         stop mgs || error "stop mgs failed"
6795         mount_fstype mgs || error "remount mgs failed"
6796         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6797                 fid=${fid_list[i]}
6798                 rec=${rec_list[i]}
6799                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6800                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6801                 oid=$((16#$oid))
6802
6803                 case $fstype in
6804                         ldiskfs )
6805                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6806                         zfs )
6807                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6808                 esac
6809                 echo "obj_file is $obj_file"
6810                 do_facet mgs $llog_reader $obj_file
6811
6812                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6813                         awk '{ print $3 }' | sed -e "s/^type=//g")
6814                 if [ $rec_type != $rec ]; then
6815                         echo "FAILED test_60a wrong record type $rec_type," \
6816                               "should be $rec"
6817                         pass=false
6818                         break
6819                 fi
6820
6821                 #check obj path if record type is LLOG_LOGID_MAGIC
6822                 if [ "$rec" == "1064553b" ]; then
6823                         path=$(do_facet mgs $llog_reader $obj_file |
6824                                 grep "path=" | awk '{ print $NF }' |
6825                                 sed -e "s/^path=//g")
6826                         if [ $obj_file != $mntpt/$path ]; then
6827                                 echo "FAILED test_60a wrong obj path" \
6828                                       "$montpt/$path, should be $obj_file"
6829                                 pass=false
6830                                 break
6831                         fi
6832                 fi
6833         done
6834         rm -f $TMP/$tfile
6835         #restart mgs before "error", otherwise it will block the next test
6836         stop mgs || error "stop mgs failed"
6837         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6838         $pass || error "test failed, see FAILED test_60a messages for specifics"
6839 }
6840 run_test 60a "llog_test run from kernel module and test llog_reader"
6841
6842 test_60b() { # bug 6411
6843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6844
6845         dmesg > $DIR/$tfile
6846         LLOG_COUNT=$(do_facet mgs dmesg |
6847                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6848                           /llog_[a-z]*.c:[0-9]/ {
6849                                 if (marker)
6850                                         from_marker++
6851                                 from_begin++
6852                           }
6853                           END {
6854                                 if (marker)
6855                                         print from_marker
6856                                 else
6857                                         print from_begin
6858                           }")
6859
6860         [[ $LLOG_COUNT -gt 120 ]] &&
6861                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6862 }
6863 run_test 60b "limit repeated messages from CERROR/CWARN"
6864
6865 test_60c() {
6866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6867
6868         echo "create 5000 files"
6869         createmany -o $DIR/f60c- 5000
6870 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6871         lctl set_param fail_loc=0x80000137
6872         unlinkmany $DIR/f60c- 5000
6873         lctl set_param fail_loc=0
6874 }
6875 run_test 60c "unlink file when mds full"
6876
6877 test_60d() {
6878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6879
6880         SAVEPRINTK=$(lctl get_param -n printk)
6881         # verify "lctl mark" is even working"
6882         MESSAGE="test message ID $RANDOM $$"
6883         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6884         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6885
6886         lctl set_param printk=0 || error "set lnet.printk failed"
6887         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6888         MESSAGE="new test message ID $RANDOM $$"
6889         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6890         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6891         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6892
6893         lctl set_param -n printk="$SAVEPRINTK"
6894 }
6895 run_test 60d "test printk console message masking"
6896
6897 test_60e() {
6898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6899         remote_mds_nodsh && skip "remote MDS with nodsh"
6900
6901         touch $DIR/$tfile
6902 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6903         do_facet mds1 lctl set_param fail_loc=0x15b
6904         rm $DIR/$tfile
6905 }
6906 run_test 60e "no space while new llog is being created"
6907
6908 test_60g() {
6909         local pid
6910
6911         test_mkdir -c $MDSCOUNT $DIR/$tdir
6912         $LFS setdirstripe -D -i -1 -c $MDSCOUNT $DIR/$tdir
6913
6914         (
6915                 local index=0
6916                 while true; do
6917                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6918                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6919                         index=$((index + 1))
6920                 done
6921         ) &
6922
6923         pid=$!
6924
6925         for i in $(seq 100); do 
6926                 # define OBD_FAIL_OSD_TXN_START    0x19a
6927                 do_facet mds1 lctl set_param fail_loc=0x8000019a
6928                 usleep 100
6929         done
6930
6931         kill -9 $pid
6932
6933         mkdir $DIR/$tdir/new || error "mkdir failed"
6934         rmdir $DIR/$tdir/new || error "rmdir failed"
6935 }
6936 run_test 60g "transaction abort won't cause MDT hung"
6937
6938 test_60h() {
6939         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
6940                 skip "Need MDS version at least 2.12.52"
6941         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
6942
6943         local f
6944
6945         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
6946         #define OBD_FAIL_MDS_STRIPE_FID          0x189
6947         for fail_loc in 0x80000188 0x80000189; do
6948                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
6949                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
6950                         error "mkdir $dir-$fail_loc failed"
6951                 for i in {0..10}; do
6952                         # create may fail on missing stripe
6953                         echo $i > $DIR/$tdir-$fail_loc/$i
6954                 done
6955                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
6956                         error "getdirstripe $tdir-$fail_loc failed"
6957                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
6958                         error "migrate $tdir-$fail_loc failed"
6959                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
6960                         error "getdirstripe $tdir-$fail_loc failed"
6961                 pushd $DIR/$tdir-$fail_loc
6962                 for f in *; do
6963                         echo $f | cmp $f - || error "$f data mismatch"
6964                 done
6965                 popd
6966                 rm -rf $DIR/$tdir-$fail_loc
6967         done
6968 }
6969 run_test 60h "striped directory with missing stripes can be accessed"
6970
6971 test_61a() {
6972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6973
6974         f="$DIR/f61"
6975         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
6976         cancel_lru_locks osc
6977         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
6978         sync
6979 }
6980 run_test 61a "mmap() writes don't make sync hang ================"
6981
6982 test_61b() {
6983         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
6984 }
6985 run_test 61b "mmap() of unstriped file is successful"
6986
6987 # bug 2330 - insufficient obd_match error checking causes LBUG
6988 test_62() {
6989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6990
6991         f="$DIR/f62"
6992         echo foo > $f
6993         cancel_lru_locks osc
6994         lctl set_param fail_loc=0x405
6995         cat $f && error "cat succeeded, expect -EIO"
6996         lctl set_param fail_loc=0
6997 }
6998 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
6999 # match every page all of the time.
7000 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7001
7002 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7003 # Though this test is irrelevant anymore, it helped to reveal some
7004 # other grant bugs (LU-4482), let's keep it.
7005 test_63a() {   # was test_63
7006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7007
7008         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7009
7010         for i in `seq 10` ; do
7011                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7012                 sleep 5
7013                 kill $!
7014                 sleep 1
7015         done
7016
7017         rm -f $DIR/f63 || true
7018 }
7019 run_test 63a "Verify oig_wait interruption does not crash ======="
7020
7021 # bug 2248 - async write errors didn't return to application on sync
7022 # bug 3677 - async write errors left page locked
7023 test_63b() {
7024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7025
7026         debugsave
7027         lctl set_param debug=-1
7028
7029         # ensure we have a grant to do async writes
7030         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7031         rm $DIR/$tfile
7032
7033         sync    # sync lest earlier test intercept the fail_loc
7034
7035         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7036         lctl set_param fail_loc=0x80000406
7037         $MULTIOP $DIR/$tfile Owy && \
7038                 error "sync didn't return ENOMEM"
7039         sync; sleep 2; sync     # do a real sync this time to flush page
7040         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7041                 error "locked page left in cache after async error" || true
7042         debugrestore
7043 }
7044 run_test 63b "async write errors should be returned to fsync ==="
7045
7046 test_64a () {
7047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7048
7049         df $DIR
7050         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
7051 }
7052 run_test 64a "verify filter grant calculations (in kernel) ====="
7053
7054 test_64b () {
7055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7056
7057         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7058 }
7059 run_test 64b "check out-of-space detection on client"
7060
7061 test_64c() {
7062         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7063 }
7064 run_test 64c "verify grant shrink"
7065
7066 # this does exactly what osc_request.c:osc_announce_cached() does in
7067 # order to calculate max amount of grants to ask from server
7068 want_grant() {
7069         local tgt=$1
7070
7071         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7072         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7073
7074         ((rpc_in_flight ++));
7075         nrpages=$((nrpages * rpc_in_flight))
7076
7077         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7078
7079         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7080
7081         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7082         local undirty=$((nrpages * PAGE_SIZE))
7083
7084         local max_extent_pages
7085         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7086             grep grant_max_extent_size | awk '{print $2}')
7087         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7088         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7089         local grant_extent_tax
7090         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7091             grep grant_extent_tax | awk '{print $2}')
7092
7093         undirty=$((undirty + nrextents * grant_extent_tax))
7094
7095         echo $undirty
7096 }
7097
7098 # this is size of unit for grant allocation. It should be equal to
7099 # what tgt_grant.c:tgt_grant_chunk() calculates
7100 grant_chunk() {
7101         local tgt=$1
7102         local max_brw_size
7103         local grant_extent_tax
7104
7105         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7106             grep max_brw_size | awk '{print $2}')
7107
7108         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7109             grep grant_extent_tax | awk '{print $2}')
7110
7111         echo $(((max_brw_size + grant_extent_tax) * 2))
7112 }
7113
7114 test_64d() {
7115         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7116                 skip "OST < 2.10.55 doesn't limit grants enough"
7117
7118         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7119         local file=$DIR/$tfile
7120
7121         [[ $($LCTL get_param osc.${tgt}.import |
7122              grep "connect_flags:.*grant_param") ]] ||
7123                 skip "no grant_param connect flag"
7124
7125         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7126
7127         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7128
7129         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7130         stack_trap "rm -f $file" EXIT
7131
7132         $LFS setstripe $file -i 0 -c 1
7133         dd if=/dev/zero of=$file bs=1M count=1000 &
7134         ddpid=$!
7135
7136         while true
7137         do
7138                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7139                 if [[ $cur_grant -gt $max_cur_granted ]]
7140                 then
7141                         kill $ddpid
7142                         error "cur_grant $cur_grant > $max_cur_granted"
7143                 fi
7144                 kill -0 $ddpid
7145                 [[ $? -ne 0 ]] && break;
7146                 sleep 2
7147         done
7148
7149         rm -f $DIR/$tfile
7150         wait_delete_completed
7151         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7152 }
7153 run_test 64d "check grant limit exceed"
7154
7155 # bug 1414 - set/get directories' stripe info
7156 test_65a() {
7157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7158
7159         test_mkdir $DIR/$tdir
7160         touch $DIR/$tdir/f1
7161         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7162 }
7163 run_test 65a "directory with no stripe info"
7164
7165 test_65b() {
7166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7167
7168         test_mkdir $DIR/$tdir
7169         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7170
7171         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7172                                                 error "setstripe"
7173         touch $DIR/$tdir/f2
7174         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7175 }
7176 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7177
7178 test_65c() {
7179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7180         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7181
7182         test_mkdir $DIR/$tdir
7183         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7184
7185         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7186                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7187         touch $DIR/$tdir/f3
7188         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7189 }
7190 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7191
7192 test_65d() {
7193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7194
7195         test_mkdir $DIR/$tdir
7196         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7197         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7198
7199         if [[ $STRIPECOUNT -le 0 ]]; then
7200                 sc=1
7201         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7202                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7203                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7204         else
7205                 sc=$(($STRIPECOUNT - 1))
7206         fi
7207         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7208         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7209         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7210                 error "lverify failed"
7211 }
7212 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7213
7214 test_65e() {
7215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7216
7217         test_mkdir $DIR/$tdir
7218
7219         $LFS setstripe $DIR/$tdir || error "setstripe"
7220         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7221                                         error "no stripe info failed"
7222         touch $DIR/$tdir/f6
7223         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7224 }
7225 run_test 65e "directory setstripe defaults"
7226
7227 test_65f() {
7228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7229
7230         test_mkdir $DIR/${tdir}f
7231         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7232                 error "setstripe succeeded" || true
7233 }
7234 run_test 65f "dir setstripe permission (should return error) ==="
7235
7236 test_65g() {
7237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7238
7239         test_mkdir $DIR/$tdir
7240         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7241
7242         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7243                 error "setstripe -S failed"
7244         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7245         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7246                 error "delete default stripe failed"
7247 }
7248 run_test 65g "directory setstripe -d"
7249
7250 test_65h() {
7251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7252
7253         test_mkdir $DIR/$tdir
7254         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7255
7256         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7257                 error "setstripe -S failed"
7258         test_mkdir $DIR/$tdir/dd1
7259         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7260                 error "stripe info inherit failed"
7261 }
7262 run_test 65h "directory stripe info inherit ===================="
7263
7264 test_65i() {
7265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7266
7267         save_layout_restore_at_exit $MOUNT
7268
7269         # bug6367: set non-default striping on root directory
7270         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7271
7272         # bug12836: getstripe on -1 default directory striping
7273         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7274
7275         # bug12836: getstripe -v on -1 default directory striping
7276         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7277
7278         # bug12836: new find on -1 default directory striping
7279         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7280 }
7281 run_test 65i "various tests to set root directory striping"
7282
7283 test_65j() { # bug6367
7284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7285
7286         sync; sleep 1
7287
7288         # if we aren't already remounting for each test, do so for this test
7289         if [ "$I_MOUNTED" = "yes" ]; then
7290                 cleanup || error "failed to unmount"
7291                 setup
7292         fi
7293
7294         save_layout_restore_at_exit $MOUNT
7295
7296         $LFS setstripe -d $MOUNT || error "setstripe failed"
7297 }
7298 run_test 65j "set default striping on root directory (bug 6367)="
7299
7300 cleanup_65k() {
7301         rm -rf $DIR/$tdir
7302         wait_delete_completed
7303         do_facet $SINGLEMDS "lctl set_param -n \
7304                 osp.$ost*MDT0000.max_create_count=$max_count"
7305         do_facet $SINGLEMDS "lctl set_param -n \
7306                 osp.$ost*MDT0000.create_count=$count"
7307         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7308         echo $INACTIVE_OSC "is Activate"
7309
7310         wait_osc_import_state mds ost$ostnum FULL
7311 }
7312
7313 test_65k() { # bug11679
7314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7315         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7316         remote_mds_nodsh && skip "remote MDS with nodsh"
7317
7318         local disable_precreate=true
7319         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7320                 disable_precreate=false
7321
7322         echo "Check OST status: "
7323         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7324                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7325
7326         for OSC in $MDS_OSCS; do
7327                 echo $OSC "is active"
7328                 do_facet $SINGLEMDS lctl --device %$OSC activate
7329         done
7330
7331         for INACTIVE_OSC in $MDS_OSCS; do
7332                 local ost=$(osc_to_ost $INACTIVE_OSC)
7333                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
7334                                lov.*md*.target_obd |
7335                                awk -F: /$ost/'{ print $1 }' | head -n 1)
7336
7337                 mkdir -p $DIR/$tdir
7338                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
7339                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
7340
7341                 echo "Deactivate: " $INACTIVE_OSC
7342                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
7343
7344                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
7345                               osp.$ost*MDT0000.create_count")
7346                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
7347                                   osp.$ost*MDT0000.max_create_count")
7348                 $disable_precreate &&
7349                         do_facet $SINGLEMDS "lctl set_param -n \
7350                                 osp.$ost*MDT0000.max_create_count=0"
7351
7352                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
7353                         [ -f $DIR/$tdir/$idx ] && continue
7354                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
7355                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
7356                                 { cleanup_65k;
7357                                   error "setstripe $idx should succeed"; }
7358                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
7359                 done
7360                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
7361                 rmdir $DIR/$tdir
7362
7363                 do_facet $SINGLEMDS "lctl set_param -n \
7364                         osp.$ost*MDT0000.max_create_count=$max_count"
7365                 do_facet $SINGLEMDS "lctl set_param -n \
7366                         osp.$ost*MDT0000.create_count=$count"
7367                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7368                 echo $INACTIVE_OSC "is Activate"
7369
7370                 wait_osc_import_state mds ost$ostnum FULL
7371         done
7372 }
7373 run_test 65k "validate manual striping works properly with deactivated OSCs"
7374
7375 test_65l() { # bug 12836
7376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7377
7378         test_mkdir -p $DIR/$tdir/test_dir
7379         $LFS setstripe -c -1 $DIR/$tdir/test_dir
7380         $LFS find -mtime -1 $DIR/$tdir >/dev/null
7381 }
7382 run_test 65l "lfs find on -1 stripe dir ========================"
7383
7384 test_65m() {
7385         local layout=$(save_layout $MOUNT)
7386         $RUNAS $LFS setstripe -c 2 $MOUNT && {
7387                 restore_layout $MOUNT $layout
7388                 error "setstripe should fail by non-root users"
7389         }
7390         true
7391 }
7392 run_test 65m "normal user can't set filesystem default stripe"
7393
7394 test_65n() {
7395         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
7396         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
7397                 skip "Need MDS version at least 2.12.50"
7398         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7399
7400         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7401         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
7402         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
7403
7404         local root_layout=$(save_layout $MOUNT)
7405         stack_trap "restore_layout $MOUNT $root_layout" EXIT
7406
7407         # new subdirectory under root directory should not inherit
7408         # the default layout from root
7409         local dir1=$MOUNT/$tdir-1
7410         mkdir $dir1 || error "mkdir $dir1 failed"
7411         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
7412                 error "$dir1 shouldn't have LOV EA"
7413
7414         # delete the default layout on root directory
7415         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
7416
7417         local dir2=$MOUNT/$tdir-2
7418         mkdir $dir2 || error "mkdir $dir2 failed"
7419         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
7420                 error "$dir2 shouldn't have LOV EA"
7421
7422         # set a new striping pattern on root directory
7423         local def_stripe_size=$($LFS getstripe -S $MOUNT)
7424         local new_def_stripe_size=$((def_stripe_size * 2))
7425         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
7426                 error "set stripe size on $MOUNT failed"
7427
7428         # new file created in $dir2 should inherit the new stripe size from
7429         # the filesystem default
7430         local file2=$dir2/$tfile-2
7431         touch $file2 || error "touch $file2 failed"
7432
7433         local file2_stripe_size=$($LFS getstripe -S $file2)
7434         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
7435                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
7436
7437         local dir3=$MOUNT/$tdir-3
7438         mkdir $dir3 || error "mkdir $dir3 failed"
7439         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
7440                 error "$dir3 shouldn't have LOV EA"
7441
7442         # set OST pool on root directory
7443         local pool=$TESTNAME
7444         pool_add $pool || error "add $pool failed"
7445         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
7446                 error "add targets to $pool failed"
7447
7448         $LFS setstripe -p $pool $MOUNT ||
7449                 error "set OST pool on $MOUNT failed"
7450
7451         # new file created in $dir3 should inherit the pool from
7452         # the filesystem default
7453         local file3=$dir3/$tfile-3
7454         touch $file3 || error "touch $file3 failed"
7455
7456         local file3_pool=$($LFS getstripe -p $file3)
7457         [[ "$file3_pool" = "$pool" ]] ||
7458                 error "$file3 didn't inherit OST pool $pool"
7459
7460         local dir4=$MOUNT/$tdir-4
7461         mkdir $dir4 || error "mkdir $dir4 failed"
7462         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7463                 error "$dir4 shouldn't have LOV EA"
7464
7465         # new file created in $dir4 should inherit the pool from
7466         # the filesystem default
7467         local file4=$dir4/$tfile-4
7468         touch $file4 || error "touch $file4 failed"
7469
7470         local file4_pool=$($LFS getstripe -p $file4)
7471         [[ "$file4_pool" = "$pool" ]] ||
7472                 error "$file4 didn't inherit OST pool $pool"
7473
7474         # new subdirectory under non-root directory should inherit
7475         # the default layout from its parent directory
7476         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7477                 error "set directory layout on $dir4 failed"
7478
7479         local dir5=$dir4/$tdir-5
7480         mkdir $dir5 || error "mkdir $dir5 failed"
7481
7482         local dir4_layout=$(get_layout_param $dir4)
7483         local dir5_layout=$(get_layout_param $dir5)
7484         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7485                 error "$dir5 should inherit the default layout from $dir4"
7486 }
7487 run_test 65n "don't inherit default layout from root for new subdirectories"
7488
7489 # bug 2543 - update blocks count on client
7490 test_66() {
7491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7492
7493         COUNT=${COUNT:-8}
7494         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7495         sync; sync_all_data; sync; sync_all_data
7496         cancel_lru_locks osc
7497         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7498         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7499 }
7500 run_test 66 "update inode blocks count on client ==============="
7501
7502 meminfo() {
7503         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7504 }
7505
7506 swap_used() {
7507         swapon -s | awk '($1 == "'$1'") { print $4 }'
7508 }
7509
7510 # bug5265, obdfilter oa2dentry return -ENOENT
7511 # #define OBD_FAIL_SRV_ENOENT 0x217
7512 test_69() {
7513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7514         remote_ost_nodsh && skip "remote OST with nodsh"
7515
7516         f="$DIR/$tfile"
7517         $LFS setstripe -c 1 -i 0 $f
7518
7519         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7520
7521         do_facet ost1 lctl set_param fail_loc=0x217
7522         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7523         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7524
7525         do_facet ost1 lctl set_param fail_loc=0
7526         $DIRECTIO write $f 0 2 || error "write error"
7527
7528         cancel_lru_locks osc
7529         $DIRECTIO read $f 0 1 || error "read error"
7530
7531         do_facet ost1 lctl set_param fail_loc=0x217
7532         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7533
7534         do_facet ost1 lctl set_param fail_loc=0
7535         rm -f $f
7536 }
7537 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7538
7539 test_71() {
7540         test_mkdir $DIR/$tdir
7541         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7542         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7543 }
7544 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7545
7546 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7548         [ "$RUNAS_ID" = "$UID" ] &&
7549                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7550         # Check that testing environment is properly set up. Skip if not
7551         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7552                 skip_env "User $RUNAS_ID does not exist - skipping"
7553
7554         touch $DIR/$tfile
7555         chmod 777 $DIR/$tfile
7556         chmod ug+s $DIR/$tfile
7557         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7558                 error "$RUNAS dd $DIR/$tfile failed"
7559         # See if we are still setuid/sgid
7560         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7561                 error "S/gid is not dropped on write"
7562         # Now test that MDS is updated too
7563         cancel_lru_locks mdc
7564         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7565                 error "S/gid is not dropped on MDS"
7566         rm -f $DIR/$tfile
7567 }
7568 run_test 72a "Test that remove suid works properly (bug5695) ===="
7569
7570 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7571         local perm
7572
7573         [ "$RUNAS_ID" = "$UID" ] &&
7574                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7575         [ "$RUNAS_ID" -eq 0 ] &&
7576                 skip_env "RUNAS_ID = 0 -- skipping"
7577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7578         # Check that testing environment is properly set up. Skip if not
7579         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7580                 skip_env "User $RUNAS_ID does not exist - skipping"
7581
7582         touch $DIR/${tfile}-f{g,u}
7583         test_mkdir $DIR/${tfile}-dg
7584         test_mkdir $DIR/${tfile}-du
7585         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7586         chmod g+s $DIR/${tfile}-{f,d}g
7587         chmod u+s $DIR/${tfile}-{f,d}u
7588         for perm in 777 2777 4777; do
7589                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7590                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7591                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7592                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7593         done
7594         true
7595 }
7596 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7597
7598 # bug 3462 - multiple simultaneous MDC requests
7599 test_73() {
7600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7601
7602         test_mkdir $DIR/d73-1
7603         test_mkdir $DIR/d73-2
7604         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7605         pid1=$!
7606
7607         lctl set_param fail_loc=0x80000129
7608         $MULTIOP $DIR/d73-1/f73-2 Oc &
7609         sleep 1
7610         lctl set_param fail_loc=0
7611
7612         $MULTIOP $DIR/d73-2/f73-3 Oc &
7613         pid3=$!
7614
7615         kill -USR1 $pid1
7616         wait $pid1 || return 1
7617
7618         sleep 25
7619
7620         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7621         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7622         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7623
7624         rm -rf $DIR/d73-*
7625 }
7626 run_test 73 "multiple MDC requests (should not deadlock)"
7627
7628 test_74a() { # bug 6149, 6184
7629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7630
7631         touch $DIR/f74a
7632         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7633         #
7634         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7635         # will spin in a tight reconnection loop
7636         $LCTL set_param fail_loc=0x8000030e
7637         # get any lock that won't be difficult - lookup works.
7638         ls $DIR/f74a
7639         $LCTL set_param fail_loc=0
7640         rm -f $DIR/f74a
7641         true
7642 }
7643 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7644
7645 test_74b() { # bug 13310
7646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7647
7648         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7649         #
7650         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7651         # will spin in a tight reconnection loop
7652         $LCTL set_param fail_loc=0x8000030e
7653         # get a "difficult" lock
7654         touch $DIR/f74b
7655         $LCTL set_param fail_loc=0
7656         rm -f $DIR/f74b
7657         true
7658 }
7659 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7660
7661 test_74c() {
7662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7663
7664         #define OBD_FAIL_LDLM_NEW_LOCK
7665         $LCTL set_param fail_loc=0x319
7666         touch $DIR/$tfile && error "touch successful"
7667         $LCTL set_param fail_loc=0
7668         true
7669 }
7670 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7671
7672 num_inodes() {
7673         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7674 }
7675
7676 test_76() { # Now for bug 20433, added originally in bug 1443
7677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7678
7679         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7680
7681         cancel_lru_locks osc
7682         BEFORE_INODES=$(num_inodes)
7683         echo "before inodes: $BEFORE_INODES"
7684         local COUNT=1000
7685         [ "$SLOW" = "no" ] && COUNT=100
7686         for i in $(seq $COUNT); do
7687                 touch $DIR/$tfile
7688                 rm -f $DIR/$tfile
7689         done
7690         cancel_lru_locks osc
7691         AFTER_INODES=$(num_inodes)
7692         echo "after inodes: $AFTER_INODES"
7693         local wait=0
7694         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7695                 sleep 2
7696                 AFTER_INODES=$(num_inodes)
7697                 wait=$((wait+2))
7698                 echo "wait $wait seconds inodes: $AFTER_INODES"
7699                 if [ $wait -gt 30 ]; then
7700                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7701                 fi
7702         done
7703 }
7704 run_test 76 "confirm clients recycle inodes properly ===="
7705
7706
7707 export ORIG_CSUM=""
7708 set_checksums()
7709 {
7710         # Note: in sptlrpc modes which enable its own bulk checksum, the
7711         # original crc32_le bulk checksum will be automatically disabled,
7712         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7713         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7714         # In this case set_checksums() will not be no-op, because sptlrpc
7715         # bulk checksum will be enabled all through the test.
7716
7717         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7718         lctl set_param -n osc.*.checksums $1
7719         return 0
7720 }
7721
7722 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7723                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7724 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7725                              tr -d [] | head -n1)}
7726 set_checksum_type()
7727 {
7728         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7729         log "set checksum type to $1"
7730         return 0
7731 }
7732 F77_TMP=$TMP/f77-temp
7733 F77SZ=8
7734 setup_f77() {
7735         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7736                 error "error writing to $F77_TMP"
7737 }
7738
7739 test_77a() { # bug 10889
7740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7741         $GSS && skip_env "could not run with gss"
7742
7743         [ ! -f $F77_TMP ] && setup_f77
7744         set_checksums 1
7745         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7746         set_checksums 0
7747         rm -f $DIR/$tfile
7748 }
7749 run_test 77a "normal checksum read/write operation"
7750
7751 test_77b() { # bug 10889
7752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7753         $GSS && skip_env "could not run with gss"
7754
7755         [ ! -f $F77_TMP ] && setup_f77
7756         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7757         $LCTL set_param fail_loc=0x80000409
7758         set_checksums 1
7759
7760         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7761                 error "dd error: $?"
7762         $LCTL set_param fail_loc=0
7763
7764         for algo in $CKSUM_TYPES; do
7765                 cancel_lru_locks osc
7766                 set_checksum_type $algo
7767                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7768                 $LCTL set_param fail_loc=0x80000408
7769                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7770                 $LCTL set_param fail_loc=0
7771         done
7772         set_checksums 0
7773         set_checksum_type $ORIG_CSUM_TYPE
7774         rm -f $DIR/$tfile
7775 }
7776 run_test 77b "checksum error on client write, read"
7777
7778 cleanup_77c() {
7779         trap 0
7780         set_checksums 0
7781         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7782         $check_ost &&
7783                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7784         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7785         $check_ost && [ -n "$ost_file_prefix" ] &&
7786                 do_facet ost1 rm -f ${ost_file_prefix}\*
7787 }
7788
7789 test_77c() {
7790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7791         $GSS && skip_env "could not run with gss"
7792         remote_ost_nodsh && skip "remote OST with nodsh"
7793
7794         local bad1
7795         local osc_file_prefix
7796         local osc_file
7797         local check_ost=false
7798         local ost_file_prefix
7799         local ost_file
7800         local orig_cksum
7801         local dump_cksum
7802         local fid
7803
7804         # ensure corruption will occur on first OSS/OST
7805         $LFS setstripe -i 0 $DIR/$tfile
7806
7807         [ ! -f $F77_TMP ] && setup_f77
7808         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7809                 error "dd write error: $?"
7810         fid=$($LFS path2fid $DIR/$tfile)
7811
7812         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7813         then
7814                 check_ost=true
7815                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7816                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7817         else
7818                 echo "OSS do not support bulk pages dump upon error"
7819         fi
7820
7821         osc_file_prefix=$($LCTL get_param -n debug_path)
7822         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7823
7824         trap cleanup_77c EXIT
7825
7826         set_checksums 1
7827         # enable bulk pages dump upon error on Client
7828         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7829         # enable bulk pages dump upon error on OSS
7830         $check_ost &&
7831                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7832
7833         # flush Client cache to allow next read to reach OSS
7834         cancel_lru_locks osc
7835
7836         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7837         $LCTL set_param fail_loc=0x80000408
7838         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7839         $LCTL set_param fail_loc=0
7840
7841         rm -f $DIR/$tfile
7842
7843         # check cksum dump on Client
7844         osc_file=$(ls ${osc_file_prefix}*)
7845         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7846         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7847         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7848         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7849         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7850                      cksum)
7851         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7852         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7853                 error "dump content does not match on Client"
7854
7855         $check_ost || skip "No need to check cksum dump on OSS"
7856
7857         # check cksum dump on OSS
7858         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7859         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7860         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7861         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7862         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7863                 error "dump content does not match on OSS"
7864
7865         cleanup_77c
7866 }
7867 run_test 77c "checksum error on client read with debug"
7868
7869 test_77d() { # bug 10889
7870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7871         $GSS && skip_env "could not run with gss"
7872
7873         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7874         $LCTL set_param fail_loc=0x80000409
7875         set_checksums 1
7876         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7877                 error "direct write: rc=$?"
7878         $LCTL set_param fail_loc=0
7879         set_checksums 0
7880
7881         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7882         $LCTL set_param fail_loc=0x80000408
7883         set_checksums 1
7884         cancel_lru_locks osc
7885         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7886                 error "direct read: rc=$?"
7887         $LCTL set_param fail_loc=0
7888         set_checksums 0
7889 }
7890 run_test 77d "checksum error on OST direct write, read"
7891
7892 test_77f() { # bug 10889
7893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7894         $GSS && skip_env "could not run with gss"
7895
7896         set_checksums 1
7897         for algo in $CKSUM_TYPES; do
7898                 cancel_lru_locks osc
7899                 set_checksum_type $algo
7900                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7901                 $LCTL set_param fail_loc=0x409
7902                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7903                         error "direct write succeeded"
7904                 $LCTL set_param fail_loc=0
7905         done
7906         set_checksum_type $ORIG_CSUM_TYPE
7907         set_checksums 0
7908 }
7909 run_test 77f "repeat checksum error on write (expect error)"
7910
7911 test_77g() { # bug 10889
7912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7913         $GSS && skip_env "could not run with gss"
7914         remote_ost_nodsh && skip "remote OST with nodsh"
7915
7916         [ ! -f $F77_TMP ] && setup_f77
7917
7918         local file=$DIR/$tfile
7919         stack_trap "rm -f $file" EXIT
7920
7921         $LFS setstripe -c 1 -i 0 $file
7922         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7923         do_facet ost1 lctl set_param fail_loc=0x8000021a
7924         set_checksums 1
7925         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7926                 error "write error: rc=$?"
7927         do_facet ost1 lctl set_param fail_loc=0
7928         set_checksums 0
7929
7930         cancel_lru_locks osc
7931         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7932         do_facet ost1 lctl set_param fail_loc=0x8000021b
7933         set_checksums 1
7934         cmp $F77_TMP $file || error "file compare failed"
7935         do_facet ost1 lctl set_param fail_loc=0
7936         set_checksums 0
7937 }
7938 run_test 77g "checksum error on OST write, read"
7939
7940 test_77k() { # LU-10906
7941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7942         $GSS && skip_env "could not run with gss"
7943
7944         local cksum_param="osc.$FSNAME*.checksums"
7945         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
7946         local checksum
7947         local i
7948
7949         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
7950         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
7951         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
7952                 EXIT
7953
7954         for i in 0 1; do
7955                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
7956                         error "failed to set checksum=$i on MGS"
7957                 wait_update $HOSTNAME "$get_checksum" $i
7958                 #remount
7959                 echo "remount client, checksum should be $i"
7960                 remount_client $MOUNT || "failed to remount client"
7961                 checksum=$(eval $get_checksum)
7962                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7963         done
7964         # remove persistent param to avoid races with checksum mountopt below
7965         do_facet mgs $LCTL set_param -P -d $cksum_param ||
7966                 error "failed to delete checksum on MGS"
7967
7968         for opt in "checksum" "nochecksum"; do
7969                 #remount with mount option
7970                 echo "remount client with option $opt, checksum should be $i"
7971                 umount_client $MOUNT || "failed to umount client"
7972                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
7973                         "failed to mount client with option '$opt'"
7974                 checksum=$(eval $get_checksum)
7975                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7976                 i=$((i - 1))
7977         done
7978
7979         remount_client $MOUNT || "failed to remount client"
7980 }
7981 run_test 77k "enable/disable checksum correctly"
7982
7983 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
7984 rm -f $F77_TMP
7985 unset F77_TMP
7986
7987 cleanup_test_78() {
7988         trap 0
7989         rm -f $DIR/$tfile
7990 }
7991
7992 test_78() { # bug 10901
7993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7994         remote_ost || skip_env "local OST"
7995
7996         NSEQ=5
7997         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
7998         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
7999         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8000         echo "MemTotal: $MEMTOTAL"
8001
8002         # reserve 256MB of memory for the kernel and other running processes,
8003         # and then take 1/2 of the remaining memory for the read/write buffers.
8004         if [ $MEMTOTAL -gt 512 ] ;then
8005                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8006         else
8007                 # for those poor memory-starved high-end clusters...
8008                 MEMTOTAL=$((MEMTOTAL / 2))
8009         fi
8010         echo "Mem to use for directio: $MEMTOTAL"
8011
8012         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8013         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8014         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8015         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8016                 head -n1)
8017         echo "Smallest OST: $SMALLESTOST"
8018         [[ $SMALLESTOST -lt 10240 ]] &&
8019                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8020
8021         trap cleanup_test_78 EXIT
8022
8023         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8024                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8025
8026         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8027         echo "File size: $F78SIZE"
8028         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8029         for i in $(seq 1 $NSEQ); do
8030                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8031                 echo directIO rdwr round $i of $NSEQ
8032                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8033         done
8034
8035         cleanup_test_78
8036 }
8037 run_test 78 "handle large O_DIRECT writes correctly ============"
8038
8039 test_79() { # bug 12743
8040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8041
8042         wait_delete_completed
8043
8044         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8045         BKFREE=$(calc_osc_kbytes kbytesfree)
8046         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8047
8048         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8049         DFTOTAL=`echo $STRING | cut -d, -f1`
8050         DFUSED=`echo $STRING  | cut -d, -f2`
8051         DFAVAIL=`echo $STRING | cut -d, -f3`
8052         DFFREE=$(($DFTOTAL - $DFUSED))
8053
8054         ALLOWANCE=$((64 * $OSTCOUNT))
8055
8056         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8057            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8058                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8059         fi
8060         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8061            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8062                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8063         fi
8064         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8065            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8066                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8067         fi
8068 }
8069 run_test 79 "df report consistency check ======================="
8070
8071 test_80() { # bug 10718
8072         remote_ost_nodsh && skip "remote OST with nodsh"
8073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8074
8075         # relax strong synchronous semantics for slow backends like ZFS
8076         local soc="obdfilter.*.sync_on_lock_cancel"
8077         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
8078         local hosts=
8079         if [ "$soc_old" != "never" ] &&
8080                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8081                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
8082                                 facet_active_host $host; done | sort -u)
8083                         do_nodes $hosts lctl set_param $soc=never
8084         fi
8085
8086         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8087         sync; sleep 1; sync
8088         local BEFORE=`date +%s`
8089         cancel_lru_locks osc
8090         local AFTER=`date +%s`
8091         local DIFF=$((AFTER-BEFORE))
8092         if [ $DIFF -gt 1 ] ; then
8093                 error "elapsed for 1M@1T = $DIFF"
8094         fi
8095
8096         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
8097
8098         rm -f $DIR/$tfile
8099 }
8100 run_test 80 "Page eviction is equally fast at high offsets too  ===="
8101
8102 test_81a() { # LU-456
8103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8104         remote_ost_nodsh && skip "remote OST with nodsh"
8105
8106         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8107         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8108         do_facet ost1 lctl set_param fail_loc=0x80000228
8109
8110         # write should trigger a retry and success
8111         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8112         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8113         RC=$?
8114         if [ $RC -ne 0 ] ; then
8115                 error "write should success, but failed for $RC"
8116         fi
8117 }
8118 run_test 81a "OST should retry write when get -ENOSPC ==============="
8119
8120 test_81b() { # LU-456
8121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8122         remote_ost_nodsh && skip "remote OST with nodsh"
8123
8124         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8125         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8126         do_facet ost1 lctl set_param fail_loc=0x228
8127
8128         # write should retry several times and return -ENOSPC finally
8129         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8130         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8131         RC=$?
8132         ENOSPC=28
8133         if [ $RC -ne $ENOSPC ] ; then
8134                 error "dd should fail for -ENOSPC, but succeed."
8135         fi
8136 }
8137 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8138
8139 test_82() { # LU-1031
8140         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8141         local gid1=14091995
8142         local gid2=16022000
8143
8144         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8145         local MULTIPID1=$!
8146         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8147         local MULTIPID2=$!
8148         kill -USR1 $MULTIPID2
8149         sleep 2
8150         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8151                 error "First grouplock does not block second one"
8152         else
8153                 echo "Second grouplock blocks first one"
8154         fi
8155         kill -USR1 $MULTIPID1
8156         wait $MULTIPID1
8157         wait $MULTIPID2
8158 }
8159 run_test 82 "Basic grouplock test"
8160
8161 test_99() {
8162         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8163
8164         test_mkdir $DIR/$tdir.cvsroot
8165         chown $RUNAS_ID $DIR/$tdir.cvsroot
8166
8167         cd $TMP
8168         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8169
8170         cd /etc/init.d
8171         # some versions of cvs import exit(1) when asked to import links or
8172         # files they can't read.  ignore those files.
8173         local toignore=$(find . -type l -printf '-I %f\n' -o \
8174                          ! -perm /4 -printf '-I %f\n')
8175         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8176                 $tdir.reposname vtag rtag
8177
8178         cd $DIR
8179         test_mkdir $DIR/$tdir.reposname
8180         chown $RUNAS_ID $DIR/$tdir.reposname
8181         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8182
8183         cd $DIR/$tdir.reposname
8184         $RUNAS touch foo99
8185         $RUNAS cvs add -m 'addmsg' foo99
8186         $RUNAS cvs update
8187         $RUNAS cvs commit -m 'nomsg' foo99
8188         rm -fr $DIR/$tdir.cvsroot
8189 }
8190 run_test 99 "cvs strange file/directory operations"
8191
8192 test_100() {
8193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8194         [[ "$NETTYPE" =~ tcp ]] ||
8195                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8196         remote_ost_nodsh && skip "remote OST with nodsh"
8197         remote_mds_nodsh && skip "remote MDS with nodsh"
8198         remote_servers ||
8199                 skip "useless for local single node setup"
8200
8201         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8202                 [ "$PROT" != "tcp" ] && continue
8203                 RPORT=$(echo $REMOTE | cut -d: -f2)
8204                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8205
8206                 rc=0
8207                 LPORT=`echo $LOCAL | cut -d: -f2`
8208                 if [ $LPORT -ge 1024 ]; then
8209                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8210                         netstat -tna
8211                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8212                 fi
8213         done
8214         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8215 }
8216 run_test 100 "check local port using privileged port ==========="
8217
8218 function get_named_value()
8219 {
8220     local tag
8221
8222     tag=$1
8223     while read ;do
8224         line=$REPLY
8225         case $line in
8226         $tag*)
8227             echo $line | sed "s/^$tag[ ]*//"
8228             break
8229             ;;
8230         esac
8231     done
8232 }
8233
8234 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8235                    awk '/^max_cached_mb/ { print $2 }')
8236
8237 cleanup_101a() {
8238         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8239         trap 0
8240 }
8241
8242 test_101a() {
8243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8244         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
8245
8246         local s
8247         local discard
8248         local nreads=10000
8249         local cache_limit=32
8250
8251         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8252         trap cleanup_101a EXIT
8253         $LCTL set_param -n llite.*.read_ahead_stats 0
8254         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8255
8256         #
8257         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8258         #
8259         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8260         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8261
8262         discard=0
8263         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8264                 get_named_value 'read but discarded' | cut -d" " -f1); do
8265                         discard=$(($discard + $s))
8266         done
8267         cleanup_101a
8268
8269         if [[ $(($discard * 10)) -gt $nreads ]]; then
8270                 $LCTL get_param osc.*-osc*.rpc_stats
8271                 $LCTL get_param llite.*.read_ahead_stats
8272                 error "too many ($discard) discarded pages"
8273         fi
8274         rm -f $DIR/$tfile || true
8275 }
8276 run_test 101a "check read-ahead for random reads"
8277
8278 setup_test101bc() {
8279         test_mkdir $DIR/$tdir
8280         local ssize=$1
8281         local FILE_LENGTH=$2
8282         STRIPE_OFFSET=0
8283
8284         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
8285
8286         local list=$(comma_list $(osts_nodes))
8287         set_osd_param $list '' read_cache_enable 0
8288         set_osd_param $list '' writethrough_cache_enable 0
8289
8290         trap cleanup_test101bc EXIT
8291         # prepare the read-ahead file
8292         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
8293
8294         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
8295                                 count=$FILE_SIZE_MB 2> /dev/null
8296
8297 }
8298
8299 cleanup_test101bc() {
8300         trap 0
8301         rm -rf $DIR/$tdir
8302         rm -f $DIR/$tfile
8303
8304         local list=$(comma_list $(osts_nodes))
8305         set_osd_param $list '' read_cache_enable 1
8306         set_osd_param $list '' writethrough_cache_enable 1
8307 }
8308
8309 calc_total() {
8310         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
8311 }
8312
8313 ra_check_101() {
8314         local READ_SIZE=$1
8315         local STRIPE_SIZE=$2
8316         local FILE_LENGTH=$3
8317         local RA_INC=1048576
8318         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
8319         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
8320                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
8321         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
8322                         get_named_value 'read but discarded' |
8323                         cut -d" " -f1 | calc_total)
8324         if [[ $DISCARD -gt $discard_limit ]]; then
8325                 $LCTL get_param llite.*.read_ahead_stats
8326                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
8327         else
8328                 echo "Read-ahead success for size ${READ_SIZE}"
8329         fi
8330 }
8331
8332 test_101b() {
8333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8334         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8335
8336         local STRIPE_SIZE=1048576
8337         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
8338
8339         if [ $SLOW == "yes" ]; then
8340                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
8341         else
8342                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
8343         fi
8344
8345         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
8346
8347         # prepare the read-ahead file
8348         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8349         cancel_lru_locks osc
8350         for BIDX in 2 4 8 16 32 64 128 256
8351         do
8352                 local BSIZE=$((BIDX*4096))
8353                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
8354                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
8355                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
8356                 $LCTL set_param -n llite.*.read_ahead_stats 0
8357                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
8358                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
8359                 cancel_lru_locks osc
8360                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
8361         done
8362         cleanup_test101bc
8363         true
8364 }
8365 run_test 101b "check stride-io mode read-ahead ================="
8366
8367 test_101c() {
8368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8369
8370         local STRIPE_SIZE=1048576
8371         local FILE_LENGTH=$((STRIPE_SIZE*100))
8372         local nreads=10000
8373         local rsize=65536
8374         local osc_rpc_stats
8375
8376         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8377
8378         cancel_lru_locks osc
8379         $LCTL set_param osc.*.rpc_stats 0
8380         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
8381         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
8382                 local stats=$($LCTL get_param -n $osc_rpc_stats)
8383                 local lines=$(echo "$stats" | awk 'END {print NR;}')
8384                 local size
8385
8386                 if [ $lines -le 20 ]; then
8387                         continue
8388                 fi
8389                 for size in 1 2 4 8; do
8390                         local rpc=$(echo "$stats" |
8391                                     awk '($1 == "'$size':") {print $2; exit; }')
8392                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
8393                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
8394                 done
8395                 echo "$osc_rpc_stats check passed!"
8396         done
8397         cleanup_test101bc
8398         true
8399 }
8400 run_test 101c "check stripe_size aligned read-ahead ================="
8401
8402 set_read_ahead() {
8403         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
8404         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
8405 }
8406
8407 test_101d() {
8408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8409
8410         local file=$DIR/$tfile
8411         local sz_MB=${FILESIZE_101d:-500}
8412         local ra_MB=${READAHEAD_MB:-40}
8413
8414         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
8415         [ $free_MB -lt $sz_MB ] &&
8416                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
8417
8418         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
8419         $LFS setstripe -c -1 $file || error "setstripe failed"
8420
8421         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
8422         echo Cancel LRU locks on lustre client to flush the client cache
8423         cancel_lru_locks osc
8424
8425         echo Disable read-ahead
8426         local old_READAHEAD=$(set_read_ahead 0)
8427
8428         echo Reading the test file $file with read-ahead disabled
8429         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8430
8431         echo Cancel LRU locks on lustre client to flush the client cache
8432         cancel_lru_locks osc
8433         echo Enable read-ahead with ${ra_MB}MB
8434         set_read_ahead $ra_MB
8435
8436         echo Reading the test file $file with read-ahead enabled
8437         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8438
8439         echo "read-ahead disabled time read $raOFF"
8440         echo "read-ahead enabled  time read $raON"
8441
8442         set_read_ahead $old_READAHEAD
8443         rm -f $file
8444         wait_delete_completed
8445
8446         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
8447                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
8448 }
8449 run_test 101d "file read with and without read-ahead enabled"
8450
8451 test_101e() {
8452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8453
8454         local file=$DIR/$tfile
8455         local size_KB=500  #KB
8456         local count=100
8457         local bsize=1024
8458
8459         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8460         local need_KB=$((count * size_KB))
8461         [[ $free_KB -le $need_KB ]] &&
8462                 skip_env "Need free space $need_KB, have $free_KB"
8463
8464         echo "Creating $count ${size_KB}K test files"
8465         for ((i = 0; i < $count; i++)); do
8466                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8467         done
8468
8469         echo "Cancel LRU locks on lustre client to flush the client cache"
8470         cancel_lru_locks $OSC
8471
8472         echo "Reset readahead stats"
8473         $LCTL set_param -n llite.*.read_ahead_stats 0
8474
8475         for ((i = 0; i < $count; i++)); do
8476                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8477         done
8478
8479         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8480                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8481
8482         for ((i = 0; i < $count; i++)); do
8483                 rm -rf $file.$i 2>/dev/null
8484         done
8485
8486         #10000 means 20% reads are missing in readahead
8487         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8488 }
8489 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8490
8491 test_101f() {
8492         which iozone || skip_env "no iozone installed"
8493
8494         local old_debug=$($LCTL get_param debug)
8495         old_debug=${old_debug#*=}
8496         $LCTL set_param debug="reada mmap"
8497
8498         # create a test file
8499         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8500
8501         echo Cancel LRU locks on lustre client to flush the client cache
8502         cancel_lru_locks osc
8503
8504         echo Reset readahead stats
8505         $LCTL set_param -n llite.*.read_ahead_stats 0
8506
8507         echo mmap read the file with small block size
8508         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8509                 > /dev/null 2>&1
8510
8511         echo checking missing pages
8512         $LCTL get_param llite.*.read_ahead_stats
8513         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8514                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8515
8516         $LCTL set_param debug="$old_debug"
8517         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8518         rm -f $DIR/$tfile
8519 }
8520 run_test 101f "check mmap read performance"
8521
8522 test_101g_brw_size_test() {
8523         local mb=$1
8524         local pages=$((mb * 1048576 / PAGE_SIZE))
8525         local file=$DIR/$tfile
8526
8527         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8528                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8529         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8530                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8531                         return 2
8532         done
8533
8534         stack_trap "rm -f $file" EXIT
8535         $LCTL set_param -n osc.*.rpc_stats=0
8536
8537         # 10 RPCs should be enough for the test
8538         local count=10
8539         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8540                 { error "dd write ${mb} MB blocks failed"; return 3; }
8541         cancel_lru_locks osc
8542         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8543                 { error "dd write ${mb} MB blocks failed"; return 4; }
8544
8545         # calculate number of full-sized read and write RPCs
8546         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8547                 sed -n '/pages per rpc/,/^$/p' |
8548                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8549                 END { print reads,writes }'))
8550         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8551                 return 5
8552         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8553                 return 6
8554
8555         return 0
8556 }
8557
8558 test_101g() {
8559         remote_ost_nodsh && skip "remote OST with nodsh"
8560
8561         local rpcs
8562         local osts=$(get_facets OST)
8563         local list=$(comma_list $(osts_nodes))
8564         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8565         local brw_size="obdfilter.*.brw_size"
8566
8567         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8568
8569         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8570
8571         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
8572                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
8573                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
8574            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
8575                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
8576                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
8577
8578                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
8579                         suffix="M"
8580
8581                 if [[ $orig_mb -lt 16 ]]; then
8582                         save_lustre_params $osts "$brw_size" > $p
8583                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8584                                 error "set 16MB RPC size failed"
8585
8586                         echo "remount client to enable new RPC size"
8587                         remount_client $MOUNT || error "remount_client failed"
8588                 fi
8589
8590                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8591                 # should be able to set brw_size=12, but no rpc_stats for that
8592                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8593         fi
8594
8595         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8596
8597         if [[ $orig_mb -lt 16 ]]; then
8598                 restore_lustre_params < $p
8599                 remount_client $MOUNT || error "remount_client restore failed"
8600         fi
8601
8602         rm -f $p $DIR/$tfile
8603 }
8604 run_test 101g "Big bulk(4/16 MiB) readahead"
8605
8606 setup_test102() {
8607         test_mkdir $DIR/$tdir
8608         chown $RUNAS_ID $DIR/$tdir
8609         STRIPE_SIZE=65536
8610         STRIPE_OFFSET=1
8611         STRIPE_COUNT=$OSTCOUNT
8612         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8613
8614         trap cleanup_test102 EXIT
8615         cd $DIR
8616         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8617         cd $DIR/$tdir
8618         for num in 1 2 3 4; do
8619                 for count in $(seq 1 $STRIPE_COUNT); do
8620                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8621                                 local size=`expr $STRIPE_SIZE \* $num`
8622                                 local file=file"$num-$idx-$count"
8623                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8624                         done
8625                 done
8626         done
8627
8628         cd $DIR
8629         $1 tar cf $TMP/f102.tar $tdir --xattrs
8630 }
8631
8632 cleanup_test102() {
8633         trap 0
8634         rm -f $TMP/f102.tar
8635         rm -rf $DIR/d0.sanity/d102
8636 }
8637
8638 test_102a() {
8639         [ "$UID" != 0 ] && skip "must run as root"
8640         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8641                 skip_env "must have user_xattr"
8642
8643         [ -z "$(which setfattr 2>/dev/null)" ] &&
8644                 skip_env "could not find setfattr"
8645
8646         local testfile=$DIR/$tfile
8647
8648         touch $testfile
8649         echo "set/get xattr..."
8650         setfattr -n trusted.name1 -v value1 $testfile ||
8651                 error "setfattr -n trusted.name1=value1 $testfile failed"
8652         getfattr -n trusted.name1 $testfile 2> /dev/null |
8653           grep "trusted.name1=.value1" ||
8654                 error "$testfile missing trusted.name1=value1"
8655
8656         setfattr -n user.author1 -v author1 $testfile ||
8657                 error "setfattr -n user.author1=author1 $testfile failed"
8658         getfattr -n user.author1 $testfile 2> /dev/null |
8659           grep "user.author1=.author1" ||
8660                 error "$testfile missing trusted.author1=author1"
8661
8662         echo "listxattr..."
8663         setfattr -n trusted.name2 -v value2 $testfile ||
8664                 error "$testfile unable to set trusted.name2"
8665         setfattr -n trusted.name3 -v value3 $testfile ||
8666                 error "$testfile unable to set trusted.name3"
8667         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8668             grep "trusted.name" | wc -l) -eq 3 ] ||
8669                 error "$testfile missing 3 trusted.name xattrs"
8670
8671         setfattr -n user.author2 -v author2 $testfile ||
8672                 error "$testfile unable to set user.author2"
8673         setfattr -n user.author3 -v author3 $testfile ||
8674                 error "$testfile unable to set user.author3"
8675         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8676             grep "user.author" | wc -l) -eq 3 ] ||
8677                 error "$testfile missing 3 user.author xattrs"
8678
8679         echo "remove xattr..."
8680         setfattr -x trusted.name1 $testfile ||
8681                 error "$testfile error deleting trusted.name1"
8682         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8683                 error "$testfile did not delete trusted.name1 xattr"
8684
8685         setfattr -x user.author1 $testfile ||
8686                 error "$testfile error deleting user.author1"
8687         echo "set lustre special xattr ..."
8688         $LFS setstripe -c1 $testfile
8689         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8690                 awk -F "=" '/trusted.lov/ { print $2 }' )
8691         setfattr -n "trusted.lov" -v $lovea $testfile ||
8692                 error "$testfile doesn't ignore setting trusted.lov again"
8693         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8694                 error "$testfile allow setting invalid trusted.lov"
8695         rm -f $testfile
8696 }
8697 run_test 102a "user xattr test =================================="
8698
8699 test_102b() {
8700         [ -z "$(which setfattr 2>/dev/null)" ] &&
8701                 skip_env "could not find setfattr"
8702         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8703
8704         # b10930: get/set/list trusted.lov xattr
8705         echo "get/set/list trusted.lov xattr ..."
8706         local testfile=$DIR/$tfile
8707         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8708                 error "setstripe failed"
8709         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8710                 error "getstripe failed"
8711         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8712                 error "can't get trusted.lov from $testfile"
8713
8714         local testfile2=${testfile}2
8715         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8716                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8717
8718         $MCREATE $testfile2
8719         setfattr -n trusted.lov -v $value $testfile2
8720         local stripe_size=$($LFS getstripe -S $testfile2)
8721         local stripe_count=$($LFS getstripe -c $testfile2)
8722         [[ $stripe_size -eq 65536 ]] ||
8723                 error "stripe size $stripe_size != 65536"
8724         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8725                 error "stripe count $stripe_count != $STRIPECOUNT"
8726         rm -f $DIR/$tfile
8727 }
8728 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8729
8730 test_102c() {
8731         [ -z "$(which setfattr 2>/dev/null)" ] &&
8732                 skip_env "could not find setfattr"
8733         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8734
8735         # b10930: get/set/list lustre.lov xattr
8736         echo "get/set/list lustre.lov xattr ..."
8737         test_mkdir $DIR/$tdir
8738         chown $RUNAS_ID $DIR/$tdir
8739         local testfile=$DIR/$tdir/$tfile
8740         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8741                 error "setstripe failed"
8742         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8743                 error "getstripe failed"
8744         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8745         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8746
8747         local testfile2=${testfile}2
8748         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8749                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8750
8751         $RUNAS $MCREATE $testfile2
8752         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8753         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8754         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8755         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8756         [ $stripe_count -eq $STRIPECOUNT ] ||
8757                 error "stripe count $stripe_count != $STRIPECOUNT"
8758 }
8759 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8760
8761 compare_stripe_info1() {
8762         local stripe_index_all_zero=true
8763
8764         for num in 1 2 3 4; do
8765                 for count in $(seq 1 $STRIPE_COUNT); do
8766                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8767                                 local size=$((STRIPE_SIZE * num))
8768                                 local file=file"$num-$offset-$count"
8769                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8770                                 [[ $stripe_size -ne $size ]] &&
8771                                     error "$file: size $stripe_size != $size"
8772                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8773                                 # allow fewer stripes to be created, ORI-601
8774                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8775                                     error "$file: count $stripe_count != $count"
8776                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8777                                 [[ $stripe_index -ne 0 ]] &&
8778                                         stripe_index_all_zero=false
8779                         done
8780                 done
8781         done
8782         $stripe_index_all_zero &&
8783                 error "all files are being extracted starting from OST index 0"
8784         return 0
8785 }
8786
8787 have_xattrs_include() {
8788         tar --help | grep -q xattrs-include &&
8789                 echo --xattrs-include="lustre.*"
8790 }
8791
8792 test_102d() {
8793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8794         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8795
8796         XINC=$(have_xattrs_include)
8797         setup_test102
8798         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8799         cd $DIR/$tdir/$tdir
8800         compare_stripe_info1
8801 }
8802 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8803
8804 test_102f() {
8805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8806         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8807
8808         XINC=$(have_xattrs_include)
8809         setup_test102
8810         test_mkdir $DIR/$tdir.restore
8811         cd $DIR
8812         tar cf - --xattrs $tdir | tar xf - \
8813                 -C $DIR/$tdir.restore --xattrs $XINC
8814         cd $DIR/$tdir.restore/$tdir
8815         compare_stripe_info1
8816 }
8817 run_test 102f "tar copy files, not keep osts"
8818
8819 grow_xattr() {
8820         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8821                 skip "must have user_xattr"
8822         [ -z "$(which setfattr 2>/dev/null)" ] &&
8823                 skip_env "could not find setfattr"
8824         [ -z "$(which getfattr 2>/dev/null)" ] &&
8825                 skip_env "could not find getfattr"
8826
8827         local xsize=${1:-1024}  # in bytes
8828         local file=$DIR/$tfile
8829         local value="$(generate_string $xsize)"
8830         local xbig=trusted.big
8831         local toobig=$2
8832
8833         touch $file
8834         log "save $xbig on $file"
8835         if [ -z "$toobig" ]
8836         then
8837                 setfattr -n $xbig -v $value $file ||
8838                         error "saving $xbig on $file failed"
8839         else
8840                 setfattr -n $xbig -v $value $file &&
8841                         error "saving $xbig on $file succeeded"
8842                 return 0
8843         fi
8844
8845         local orig=$(get_xattr_value $xbig $file)
8846         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8847
8848         local xsml=trusted.sml
8849         log "save $xsml on $file"
8850         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8851
8852         local new=$(get_xattr_value $xbig $file)
8853         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8854
8855         log "grow $xsml on $file"
8856         setfattr -n $xsml -v "$value" $file ||
8857                 error "growing $xsml on $file failed"
8858
8859         new=$(get_xattr_value $xbig $file)
8860         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8861         log "$xbig still valid after growing $xsml"
8862
8863         rm -f $file
8864 }
8865
8866 test_102h() { # bug 15777
8867         grow_xattr 1024
8868 }
8869 run_test 102h "grow xattr from inside inode to external block"
8870
8871 test_102ha() {
8872         large_xattr_enabled || skip_env "ea_inode feature disabled"
8873
8874         echo "setting xattr of max xattr size: $(max_xattr_size)"
8875         grow_xattr $(max_xattr_size)
8876
8877         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
8878         echo "This should fail:"
8879         grow_xattr $(($(max_xattr_size) + 10)) 1
8880 }
8881 run_test 102ha "grow xattr from inside inode to external inode"
8882
8883 test_102i() { # bug 17038
8884         [ -z "$(which getfattr 2>/dev/null)" ] &&
8885                 skip "could not find getfattr"
8886
8887         touch $DIR/$tfile
8888         ln -s $DIR/$tfile $DIR/${tfile}link
8889         getfattr -n trusted.lov $DIR/$tfile ||
8890                 error "lgetxattr on $DIR/$tfile failed"
8891         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
8892                 grep -i "no such attr" ||
8893                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
8894         rm -f $DIR/$tfile $DIR/${tfile}link
8895 }
8896 run_test 102i "lgetxattr test on symbolic link ============"
8897
8898 test_102j() {
8899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8900         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8901
8902         XINC=$(have_xattrs_include)
8903         setup_test102 "$RUNAS"
8904         chown $RUNAS_ID $DIR/$tdir
8905         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8906         cd $DIR/$tdir/$tdir
8907         compare_stripe_info1 "$RUNAS"
8908 }
8909 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
8910
8911 test_102k() {
8912         [ -z "$(which setfattr 2>/dev/null)" ] &&
8913                 skip "could not find setfattr"
8914
8915         touch $DIR/$tfile
8916         # b22187 just check that does not crash for regular file.
8917         setfattr -n trusted.lov $DIR/$tfile
8918         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
8919         local test_kdir=$DIR/$tdir
8920         test_mkdir $test_kdir
8921         local default_size=$($LFS getstripe -S $test_kdir)
8922         local default_count=$($LFS getstripe -c $test_kdir)
8923         local default_offset=$($LFS getstripe -i $test_kdir)
8924         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
8925                 error 'dir setstripe failed'
8926         setfattr -n trusted.lov $test_kdir
8927         local stripe_size=$($LFS getstripe -S $test_kdir)
8928         local stripe_count=$($LFS getstripe -c $test_kdir)
8929         local stripe_offset=$($LFS getstripe -i $test_kdir)
8930         [ $stripe_size -eq $default_size ] ||
8931                 error "stripe size $stripe_size != $default_size"
8932         [ $stripe_count -eq $default_count ] ||
8933                 error "stripe count $stripe_count != $default_count"
8934         [ $stripe_offset -eq $default_offset ] ||
8935                 error "stripe offset $stripe_offset != $default_offset"
8936         rm -rf $DIR/$tfile $test_kdir
8937 }
8938 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
8939
8940 test_102l() {
8941         [ -z "$(which getfattr 2>/dev/null)" ] &&
8942                 skip "could not find getfattr"
8943
8944         # LU-532 trusted. xattr is invisible to non-root
8945         local testfile=$DIR/$tfile
8946
8947         touch $testfile
8948
8949         echo "listxattr as user..."
8950         chown $RUNAS_ID $testfile
8951         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
8952             grep -q "trusted" &&
8953                 error "$testfile trusted xattrs are user visible"
8954
8955         return 0;
8956 }
8957 run_test 102l "listxattr size test =================================="
8958
8959 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
8960         local path=$DIR/$tfile
8961         touch $path
8962
8963         listxattr_size_check $path || error "listattr_size_check $path failed"
8964 }
8965 run_test 102m "Ensure listxattr fails on small bufffer ========"
8966
8967 cleanup_test102
8968
8969 getxattr() { # getxattr path name
8970         # Return the base64 encoding of the value of xattr name on path.
8971         local path=$1
8972         local name=$2
8973
8974         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
8975         # file: $path
8976         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8977         #
8978         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8979
8980         getfattr --absolute-names --encoding=base64 --name=$name $path |
8981                 awk -F= -v name=$name '$1 == name {
8982                         print substr($0, index($0, "=") + 1);
8983         }'
8984 }
8985
8986 test_102n() { # LU-4101 mdt: protect internal xattrs
8987         [ -z "$(which setfattr 2>/dev/null)" ] &&
8988                 skip "could not find setfattr"
8989         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
8990         then
8991                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
8992         fi
8993
8994         local file0=$DIR/$tfile.0
8995         local file1=$DIR/$tfile.1
8996         local xattr0=$TMP/$tfile.0
8997         local xattr1=$TMP/$tfile.1
8998         local namelist="lov lma lmv link fid version som hsm"
8999         local name
9000         local value
9001
9002         rm -rf $file0 $file1 $xattr0 $xattr1
9003         touch $file0 $file1
9004
9005         # Get 'before' xattrs of $file1.
9006         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9007
9008         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9009                 namelist+=" lfsck_namespace"
9010         for name in $namelist; do
9011                 # Try to copy xattr from $file0 to $file1.
9012                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9013
9014                 setfattr --name=trusted.$name --value="$value" $file1 ||
9015                         error "setxattr 'trusted.$name' failed"
9016
9017                 # Try to set a garbage xattr.
9018                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9019
9020                 if [[ x$name == "xlov" ]]; then
9021                         setfattr --name=trusted.lov --value="$value" $file1 &&
9022                         error "setxattr invalid 'trusted.lov' success"
9023                 else
9024                         setfattr --name=trusted.$name --value="$value" $file1 ||
9025                                 error "setxattr invalid 'trusted.$name' failed"
9026                 fi
9027
9028                 # Try to remove the xattr from $file1. We don't care if this
9029                 # appears to succeed or fail, we just don't want there to be
9030                 # any changes or crashes.
9031                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9032         done
9033
9034         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9035         then
9036                 name="lfsck_ns"
9037                 # Try to copy xattr from $file0 to $file1.
9038                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9039
9040                 setfattr --name=trusted.$name --value="$value" $file1 ||
9041                         error "setxattr 'trusted.$name' failed"
9042
9043                 # Try to set a garbage xattr.
9044                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9045
9046                 setfattr --name=trusted.$name --value="$value" $file1 ||
9047                         error "setxattr 'trusted.$name' failed"
9048
9049                 # Try to remove the xattr from $file1. We don't care if this
9050                 # appears to succeed or fail, we just don't want there to be
9051                 # any changes or crashes.
9052                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9053         fi
9054
9055         # Get 'after' xattrs of file1.
9056         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9057
9058         if ! diff $xattr0 $xattr1; then
9059                 error "before and after xattrs of '$file1' differ"
9060         fi
9061
9062         rm -rf $file0 $file1 $xattr0 $xattr1
9063
9064         return 0
9065 }
9066 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9067
9068 test_102p() { # LU-4703 setxattr did not check ownership
9069         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9070                 skip "MDS needs to be at least 2.5.56"
9071
9072         local testfile=$DIR/$tfile
9073
9074         touch $testfile
9075
9076         echo "setfacl as user..."
9077         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9078         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9079
9080         echo "setfattr as user..."
9081         setfacl -m "u:$RUNAS_ID:---" $testfile
9082         $RUNAS setfattr -x system.posix_acl_access $testfile
9083         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9084 }
9085 run_test 102p "check setxattr(2) correctly fails without permission"
9086
9087 test_102q() {
9088         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9089                 skip "MDS needs to be at least 2.6.92"
9090
9091         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9092 }
9093 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9094
9095 test_102r() {
9096         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9097                 skip "MDS needs to be at least 2.6.93"
9098
9099         touch $DIR/$tfile || error "touch"
9100         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9101         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9102         rm $DIR/$tfile || error "rm"
9103
9104         #normal directory
9105         mkdir -p $DIR/$tdir || error "mkdir"
9106         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9107         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9108         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9109                 error "$testfile error deleting user.author1"
9110         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9111                 grep "user.$(basename $tdir)" &&
9112                 error "$tdir did not delete user.$(basename $tdir)"
9113         rmdir $DIR/$tdir || error "rmdir"
9114
9115         #striped directory
9116         test_mkdir $DIR/$tdir
9117         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9118         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9119         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9120                 error "$testfile error deleting user.author1"
9121         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9122                 grep "user.$(basename $tdir)" &&
9123                 error "$tdir did not delete user.$(basename $tdir)"
9124         rmdir $DIR/$tdir || error "rm striped dir"
9125 }
9126 run_test 102r "set EAs with empty values"
9127
9128 test_102s() {
9129         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9130                 skip "MDS needs to be at least 2.11.52"
9131
9132         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9133
9134         save_lustre_params client "llite.*.xattr_cache" > $save
9135
9136         for cache in 0 1; do
9137                 lctl set_param llite.*.xattr_cache=$cache
9138
9139                 rm -f $DIR/$tfile
9140                 touch $DIR/$tfile || error "touch"
9141                 for prefix in lustre security system trusted user; do
9142                         # Note getxattr() may fail with 'Operation not
9143                         # supported' or 'No such attribute' depending
9144                         # on prefix and cache.
9145                         getfattr -n $prefix.n102s $DIR/$tfile &&
9146                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9147                 done
9148         done
9149
9150         restore_lustre_params < $save
9151 }
9152 run_test 102s "getting nonexistent xattrs should fail"
9153
9154 test_102t() {
9155         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9156                 skip "MDS needs to be at least 2.11.52"
9157
9158         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9159
9160         save_lustre_params client "llite.*.xattr_cache" > $save
9161
9162         for cache in 0 1; do
9163                 lctl set_param llite.*.xattr_cache=$cache
9164
9165                 for buf_size in 0 256; do
9166                         rm -f $DIR/$tfile
9167                         touch $DIR/$tfile || error "touch"
9168                         setfattr -n user.multiop $DIR/$tfile
9169                         $MULTIOP $DIR/$tfile oa$buf_size ||
9170                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9171                 done
9172         done
9173
9174         restore_lustre_params < $save
9175 }
9176 run_test 102t "zero length xattr values handled correctly"
9177
9178 run_acl_subtest()
9179 {
9180     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9181     return $?
9182 }
9183
9184 test_103a() {
9185         [ "$UID" != 0 ] && skip "must run as root"
9186         $GSS && skip_env "could not run under gss"
9187         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9188                 skip_env "must have acl enabled"
9189         [ -z "$(which setfacl 2>/dev/null)" ] &&
9190                 skip_env "could not find setfacl"
9191         remote_mds_nodsh && skip "remote MDS with nodsh"
9192
9193         gpasswd -a daemon bin                           # LU-5641
9194         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
9195
9196         declare -a identity_old
9197
9198         for num in $(seq $MDSCOUNT); do
9199                 switch_identity $num true || identity_old[$num]=$?
9200         done
9201
9202         SAVE_UMASK=$(umask)
9203         umask 0022
9204         mkdir -p $DIR/$tdir
9205         cd $DIR/$tdir
9206
9207         echo "performing cp ..."
9208         run_acl_subtest cp || error "run_acl_subtest cp failed"
9209         echo "performing getfacl-noacl..."
9210         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
9211         echo "performing misc..."
9212         run_acl_subtest misc || error  "misc test failed"
9213         echo "performing permissions..."
9214         run_acl_subtest permissions || error "permissions failed"
9215         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
9216         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
9217                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
9218                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
9219         then
9220                 echo "performing permissions xattr..."
9221                 run_acl_subtest permissions_xattr ||
9222                         error "permissions_xattr failed"
9223         fi
9224         echo "performing setfacl..."
9225         run_acl_subtest setfacl || error  "setfacl test failed"
9226
9227         # inheritance test got from HP
9228         echo "performing inheritance..."
9229         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
9230         chmod +x make-tree || error "chmod +x failed"
9231         run_acl_subtest inheritance || error "inheritance test failed"
9232         rm -f make-tree
9233
9234         echo "LU-974 ignore umask when acl is enabled..."
9235         run_acl_subtest 974 || error "LU-974 umask test failed"
9236         if [ $MDSCOUNT -ge 2 ]; then
9237                 run_acl_subtest 974_remote ||
9238                         error "LU-974 umask test failed under remote dir"
9239         fi
9240
9241         echo "LU-2561 newly created file is same size as directory..."
9242         if [ "$mds1_FSTYPE" != "zfs" ]; then
9243                 run_acl_subtest 2561 || error "LU-2561 test failed"
9244         else
9245                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
9246         fi
9247
9248         run_acl_subtest 4924 || error "LU-4924 test failed"
9249
9250         cd $SAVE_PWD
9251         umask $SAVE_UMASK
9252
9253         for num in $(seq $MDSCOUNT); do
9254                 if [ "${identity_old[$num]}" = 1 ]; then
9255                         switch_identity $num false || identity_old[$num]=$?
9256                 fi
9257         done
9258 }
9259 run_test 103a "acl test"
9260
9261 test_103b() {
9262         declare -a pids
9263         local U
9264
9265         for U in {0..511}; do
9266                 {
9267                 local O=$(printf "%04o" $U)
9268
9269                 umask $(printf "%04o" $((511 ^ $O)))
9270                 $LFS setstripe -c 1 $DIR/$tfile.s$O
9271                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
9272
9273                 (( $S == ($O & 0666) )) ||
9274                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
9275
9276                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
9277                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
9278                 (( $S == ($O & 0666) )) ||
9279                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
9280
9281                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
9282                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
9283                 (( $S == ($O & 0666) )) ||
9284                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
9285                 rm -f $DIR/$tfile.[smp]$0
9286                 } &
9287                 local pid=$!
9288
9289                 # limit the concurrently running threads to 64. LU-11878
9290                 local idx=$((U % 64))
9291                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
9292                 pids[idx]=$pid
9293         done
9294         wait
9295 }
9296 run_test 103b "umask lfs setstripe"
9297
9298 test_103c() {
9299         mkdir -p $DIR/$tdir
9300         cp -rp $DIR/$tdir $DIR/$tdir.bak
9301
9302         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
9303                 error "$DIR/$tdir shouldn't contain default ACL"
9304         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
9305                 error "$DIR/$tdir.bak shouldn't contain default ACL"
9306         true
9307 }
9308 run_test 103c "'cp -rp' won't set empty acl"
9309
9310 test_104a() {
9311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9312
9313         touch $DIR/$tfile
9314         lfs df || error "lfs df failed"
9315         lfs df -ih || error "lfs df -ih failed"
9316         lfs df -h $DIR || error "lfs df -h $DIR failed"
9317         lfs df -i $DIR || error "lfs df -i $DIR failed"
9318         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
9319         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
9320
9321         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
9322         lctl --device %$OSC deactivate
9323         lfs df || error "lfs df with deactivated OSC failed"
9324         lctl --device %$OSC activate
9325         # wait the osc back to normal
9326         wait_osc_import_ready client ost
9327
9328         lfs df || error "lfs df with reactivated OSC failed"
9329         rm -f $DIR/$tfile
9330 }
9331 run_test 104a "lfs df [-ih] [path] test ========================="
9332
9333 test_104b() {
9334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9335         [ $RUNAS_ID -eq $UID ] &&
9336                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9337
9338         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
9339                         grep "Permission denied" | wc -l)))
9340         if [ $denied_cnt -ne 0 ]; then
9341                 error "lfs check servers test failed"
9342         fi
9343 }
9344 run_test 104b "$RUNAS lfs check servers test ===================="
9345
9346 test_105a() {
9347         # doesn't work on 2.4 kernels
9348         touch $DIR/$tfile
9349         if $(flock_is_enabled); then
9350                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
9351         else
9352                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
9353         fi
9354         rm -f $DIR/$tfile
9355 }
9356 run_test 105a "flock when mounted without -o flock test ========"
9357
9358 test_105b() {
9359         touch $DIR/$tfile
9360         if $(flock_is_enabled); then
9361                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
9362         else
9363                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
9364         fi
9365         rm -f $DIR/$tfile
9366 }
9367 run_test 105b "fcntl when mounted without -o flock test ========"
9368
9369 test_105c() {
9370         touch $DIR/$tfile
9371         if $(flock_is_enabled); then
9372                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
9373         else
9374                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
9375         fi
9376         rm -f $DIR/$tfile
9377 }
9378 run_test 105c "lockf when mounted without -o flock test"
9379
9380 test_105d() { # bug 15924
9381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9382
9383         test_mkdir $DIR/$tdir
9384         flock_is_enabled || skip_env "mount w/o flock enabled"
9385         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
9386         $LCTL set_param fail_loc=0x80000315
9387         flocks_test 2 $DIR/$tdir
9388 }
9389 run_test 105d "flock race (should not freeze) ========"
9390
9391 test_105e() { # bug 22660 && 22040
9392         flock_is_enabled || skip_env "mount w/o flock enabled"
9393
9394         touch $DIR/$tfile
9395         flocks_test 3 $DIR/$tfile
9396 }
9397 run_test 105e "Two conflicting flocks from same process"
9398
9399 test_106() { #bug 10921
9400         test_mkdir $DIR/$tdir
9401         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
9402         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
9403 }
9404 run_test 106 "attempt exec of dir followed by chown of that dir"
9405
9406 test_107() {
9407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9408
9409         CDIR=`pwd`
9410         local file=core
9411
9412         cd $DIR
9413         rm -f $file
9414
9415         local save_pattern=$(sysctl -n kernel.core_pattern)
9416         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
9417         sysctl -w kernel.core_pattern=$file
9418         sysctl -w kernel.core_uses_pid=0
9419
9420         ulimit -c unlimited
9421         sleep 60 &
9422         SLEEPPID=$!
9423
9424         sleep 1
9425
9426         kill -s 11 $SLEEPPID
9427         wait $SLEEPPID
9428         if [ -e $file ]; then
9429                 size=`stat -c%s $file`
9430                 [ $size -eq 0 ] && error "Fail to create core file $file"
9431         else
9432                 error "Fail to create core file $file"
9433         fi
9434         rm -f $file
9435         sysctl -w kernel.core_pattern=$save_pattern
9436         sysctl -w kernel.core_uses_pid=$save_uses_pid
9437         cd $CDIR
9438 }
9439 run_test 107 "Coredump on SIG"
9440
9441 test_110() {
9442         test_mkdir $DIR/$tdir
9443         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
9444         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
9445                 error "mkdir with 256 char should fail, but did not"
9446         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
9447                 error "create with 255 char failed"
9448         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
9449                 error "create with 256 char should fail, but did not"
9450
9451         ls -l $DIR/$tdir
9452         rm -rf $DIR/$tdir
9453 }
9454 run_test 110 "filename length checking"
9455
9456 #
9457 # Purpose: To verify dynamic thread (OSS) creation.
9458 #
9459 test_115() {
9460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9461         remote_ost_nodsh && skip "remote OST with nodsh"
9462
9463         # Lustre does not stop service threads once they are started.
9464         # Reset number of running threads to default.
9465         stopall
9466         setupall
9467
9468         local OSTIO_pre
9469         local save_params="$TMP/sanity-$TESTNAME.parameters"
9470
9471         # Get ll_ost_io count before I/O
9472         OSTIO_pre=$(do_facet ost1 \
9473                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9474         # Exit if lustre is not running (ll_ost_io not running).
9475         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9476
9477         echo "Starting with $OSTIO_pre threads"
9478         local thread_max=$((OSTIO_pre * 2))
9479         local rpc_in_flight=$((thread_max * 2))
9480         # Number of I/O Process proposed to be started.
9481         local nfiles
9482         local facets=$(get_facets OST)
9483
9484         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9485         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9486
9487         # Set in_flight to $rpc_in_flight
9488         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9489                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9490         nfiles=${rpc_in_flight}
9491         # Set ost thread_max to $thread_max
9492         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9493
9494         # 5 Minutes should be sufficient for max number of OSS
9495         # threads(thread_max) to be created.
9496         local timeout=300
9497
9498         # Start I/O.
9499         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9500         test_mkdir $DIR/$tdir
9501         for i in $(seq $nfiles); do
9502                 local file=$DIR/$tdir/${tfile}-$i
9503                 $LFS setstripe -c -1 -i 0 $file
9504                 ($WTL $file $timeout)&
9505         done
9506
9507         # I/O Started - Wait for thread_started to reach thread_max or report
9508         # error if thread_started is more than thread_max.
9509         echo "Waiting for thread_started to reach thread_max"
9510         local thread_started=0
9511         local end_time=$((SECONDS + timeout))
9512
9513         while [ $SECONDS -le $end_time ] ; do
9514                 echo -n "."
9515                 # Get ost i/o thread_started count.
9516                 thread_started=$(do_facet ost1 \
9517                         "$LCTL get_param \
9518                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9519                 # Break out if thread_started is equal/greater than thread_max
9520                 if [[ $thread_started -ge $thread_max ]]; then
9521                         echo ll_ost_io thread_started $thread_started, \
9522                                 equal/greater than thread_max $thread_max
9523                         break
9524                 fi
9525                 sleep 1
9526         done
9527
9528         # Cleanup - We have the numbers, Kill i/o jobs if running.
9529         jobcount=($(jobs -p))
9530         for i in $(seq 0 $((${#jobcount[@]}-1)))
9531         do
9532                 kill -9 ${jobcount[$i]}
9533                 if [ $? -ne 0 ] ; then
9534                         echo Warning: \
9535                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9536                 fi
9537         done
9538
9539         # Cleanup files left by WTL binary.
9540         for i in $(seq $nfiles); do
9541                 local file=$DIR/$tdir/${tfile}-$i
9542                 rm -rf $file
9543                 if [ $? -ne 0 ] ; then
9544                         echo "Warning: Failed to delete file $file"
9545                 fi
9546         done
9547
9548         restore_lustre_params <$save_params
9549         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9550
9551         # Error out if no new thread has started or Thread started is greater
9552         # than thread max.
9553         if [[ $thread_started -le $OSTIO_pre ||
9554                         $thread_started -gt $thread_max ]]; then
9555                 error "ll_ost_io: thread_started $thread_started" \
9556                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9557                       "No new thread started or thread started greater " \
9558                       "than thread_max."
9559         fi
9560 }
9561 run_test 115 "verify dynamic thread creation===================="
9562
9563 free_min_max () {
9564         wait_delete_completed
9565         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9566         echo "OST kbytes available: ${AVAIL[@]}"
9567         MAXV=${AVAIL[0]}
9568         MAXI=0
9569         MINV=${AVAIL[0]}
9570         MINI=0
9571         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9572                 #echo OST $i: ${AVAIL[i]}kb
9573                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9574                         MAXV=${AVAIL[i]}
9575                         MAXI=$i
9576                 fi
9577                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9578                         MINV=${AVAIL[i]}
9579                         MINI=$i
9580                 fi
9581         done
9582         echo "Min free space: OST $MINI: $MINV"
9583         echo "Max free space: OST $MAXI: $MAXV"
9584 }
9585
9586 test_116a() { # was previously test_116()
9587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9588         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9589         remote_mds_nodsh && skip "remote MDS with nodsh"
9590
9591         echo -n "Free space priority "
9592         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
9593                 head -n1
9594         declare -a AVAIL
9595         free_min_max
9596
9597         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9598         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9599         trap simple_cleanup_common EXIT
9600
9601         # Check if we need to generate uneven OSTs
9602         test_mkdir -p $DIR/$tdir/OST${MINI}
9603         local FILL=$((MINV / 4))
9604         local DIFF=$((MAXV - MINV))
9605         local DIFF2=$((DIFF * 100 / MINV))
9606
9607         local threshold=$(do_facet $SINGLEMDS \
9608                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9609         threshold=${threshold%%%}
9610         echo -n "Check for uneven OSTs: "
9611         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9612
9613         if [[ $DIFF2 -gt $threshold ]]; then
9614                 echo "ok"
9615                 echo "Don't need to fill OST$MINI"
9616         else
9617                 # generate uneven OSTs. Write 2% over the QOS threshold value
9618                 echo "no"
9619                 DIFF=$((threshold - DIFF2 + 2))
9620                 DIFF2=$((MINV * DIFF / 100))
9621                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9622                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9623                         error "setstripe failed"
9624                 DIFF=$((DIFF2 / 2048))
9625                 i=0
9626                 while [ $i -lt $DIFF ]; do
9627                         i=$((i + 1))
9628                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9629                                 bs=2M count=1 2>/dev/null
9630                         echo -n .
9631                 done
9632                 echo .
9633                 sync
9634                 sleep_maxage
9635                 free_min_max
9636         fi
9637
9638         DIFF=$((MAXV - MINV))
9639         DIFF2=$((DIFF * 100 / MINV))
9640         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9641         if [ $DIFF2 -gt $threshold ]; then
9642                 echo "ok"
9643         else
9644                 echo "failed - QOS mode won't be used"
9645                 simple_cleanup_common
9646                 skip "QOS imbalance criteria not met"
9647         fi
9648
9649         MINI1=$MINI
9650         MINV1=$MINV
9651         MAXI1=$MAXI
9652         MAXV1=$MAXV
9653
9654         # now fill using QOS
9655         $LFS setstripe -c 1 $DIR/$tdir
9656         FILL=$((FILL / 200))
9657         if [ $FILL -gt 600 ]; then
9658                 FILL=600
9659         fi
9660         echo "writing $FILL files to QOS-assigned OSTs"
9661         i=0
9662         while [ $i -lt $FILL ]; do
9663                 i=$((i + 1))
9664                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9665                         count=1 2>/dev/null
9666                 echo -n .
9667         done
9668         echo "wrote $i 200k files"
9669         sync
9670         sleep_maxage
9671
9672         echo "Note: free space may not be updated, so measurements might be off"
9673         free_min_max
9674         DIFF2=$((MAXV - MINV))
9675         echo "free space delta: orig $DIFF final $DIFF2"
9676         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9677         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9678         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9679         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9680         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9681         if [[ $DIFF -gt 0 ]]; then
9682                 FILL=$((DIFF2 * 100 / DIFF - 100))
9683                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9684         fi
9685
9686         # Figure out which files were written where
9687         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9688                awk '/'$MINI1': / {print $2; exit}')
9689         echo $UUID
9690         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9691         echo "$MINC files created on smaller OST $MINI1"
9692         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9693                awk '/'$MAXI1': / {print $2; exit}')
9694         echo $UUID
9695         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9696         echo "$MAXC files created on larger OST $MAXI1"
9697         if [[ $MINC -gt 0 ]]; then
9698                 FILL=$((MAXC * 100 / MINC - 100))
9699                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9700         fi
9701         [[ $MAXC -gt $MINC ]] ||
9702                 error_ignore LU-9 "stripe QOS didn't balance free space"
9703         simple_cleanup_common
9704 }
9705 run_test 116a "stripe QOS: free space balance ==================="
9706
9707 test_116b() { # LU-2093
9708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9709         remote_mds_nodsh && skip "remote MDS with nodsh"
9710
9711 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9712         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9713                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9714         [ -z "$old_rr" ] && skip "no QOS"
9715         do_facet $SINGLEMDS lctl set_param \
9716                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9717         mkdir -p $DIR/$tdir
9718         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9719         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9720         do_facet $SINGLEMDS lctl set_param fail_loc=0
9721         rm -rf $DIR/$tdir
9722         do_facet $SINGLEMDS lctl set_param \
9723                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9724 }
9725 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9726
9727 test_117() # bug 10891
9728 {
9729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9730
9731         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9732         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9733         lctl set_param fail_loc=0x21e
9734         > $DIR/$tfile || error "truncate failed"
9735         lctl set_param fail_loc=0
9736         echo "Truncate succeeded."
9737         rm -f $DIR/$tfile
9738 }
9739 run_test 117 "verify osd extend =========="
9740
9741 NO_SLOW_RESENDCOUNT=4
9742 export OLD_RESENDCOUNT=""
9743 set_resend_count () {
9744         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9745         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9746         lctl set_param -n $PROC_RESENDCOUNT $1
9747         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9748 }
9749
9750 # for reduce test_118* time (b=14842)
9751 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9752
9753 # Reset async IO behavior after error case
9754 reset_async() {
9755         FILE=$DIR/reset_async
9756
9757         # Ensure all OSCs are cleared
9758         $LFS setstripe -c -1 $FILE
9759         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9760         sync
9761         rm $FILE
9762 }
9763
9764 test_118a() #bug 11710
9765 {
9766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9767
9768         reset_async
9769
9770         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9771         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9772         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9773
9774         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9775                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9776                 return 1;
9777         fi
9778         rm -f $DIR/$tfile
9779 }
9780 run_test 118a "verify O_SYNC works =========="
9781
9782 test_118b()
9783 {
9784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9785         remote_ost_nodsh && skip "remote OST with nodsh"
9786
9787         reset_async
9788
9789         #define OBD_FAIL_SRV_ENOENT 0x217
9790         set_nodes_failloc "$(osts_nodes)" 0x217
9791         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9792         RC=$?
9793         set_nodes_failloc "$(osts_nodes)" 0
9794         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9795         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9796                     grep -c writeback)
9797
9798         if [[ $RC -eq 0 ]]; then
9799                 error "Must return error due to dropped pages, rc=$RC"
9800                 return 1;
9801         fi
9802
9803         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9804                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9805                 return 1;
9806         fi
9807
9808         echo "Dirty pages not leaked on ENOENT"
9809
9810         # Due to the above error the OSC will issue all RPCs syncronously
9811         # until a subsequent RPC completes successfully without error.
9812         $MULTIOP $DIR/$tfile Ow4096yc
9813         rm -f $DIR/$tfile
9814
9815         return 0
9816 }
9817 run_test 118b "Reclaim dirty pages on fatal error =========="
9818
9819 test_118c()
9820 {
9821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9822
9823         # for 118c, restore the original resend count, LU-1940
9824         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9825                                 set_resend_count $OLD_RESENDCOUNT
9826         remote_ost_nodsh && skip "remote OST with nodsh"
9827
9828         reset_async
9829
9830         #define OBD_FAIL_OST_EROFS               0x216
9831         set_nodes_failloc "$(osts_nodes)" 0x216
9832
9833         # multiop should block due to fsync until pages are written
9834         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9835         MULTIPID=$!
9836         sleep 1
9837
9838         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9839                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9840         fi
9841
9842         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9843                     grep -c writeback)
9844         if [[ $WRITEBACK -eq 0 ]]; then
9845                 error "No page in writeback, writeback=$WRITEBACK"
9846         fi
9847
9848         set_nodes_failloc "$(osts_nodes)" 0
9849         wait $MULTIPID
9850         RC=$?
9851         if [[ $RC -ne 0 ]]; then
9852                 error "Multiop fsync failed, rc=$RC"
9853         fi
9854
9855         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9856         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9857                     grep -c writeback)
9858         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9859                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9860         fi
9861
9862         rm -f $DIR/$tfile
9863         echo "Dirty pages flushed via fsync on EROFS"
9864         return 0
9865 }
9866 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9867
9868 # continue to use small resend count to reduce test_118* time (b=14842)
9869 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9870
9871 test_118d()
9872 {
9873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9874         remote_ost_nodsh && skip "remote OST with nodsh"
9875
9876         reset_async
9877
9878         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9879         set_nodes_failloc "$(osts_nodes)" 0x214
9880         # multiop should block due to fsync until pages are written
9881         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9882         MULTIPID=$!
9883         sleep 1
9884
9885         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9886                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9887         fi
9888
9889         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9890                     grep -c writeback)
9891         if [[ $WRITEBACK -eq 0 ]]; then
9892                 error "No page in writeback, writeback=$WRITEBACK"
9893         fi
9894
9895         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
9896         set_nodes_failloc "$(osts_nodes)" 0
9897
9898         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9899         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9900                     grep -c writeback)
9901         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9902                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9903         fi
9904
9905         rm -f $DIR/$tfile
9906         echo "Dirty pages gaurenteed flushed via fsync"
9907         return 0
9908 }
9909 run_test 118d "Fsync validation inject a delay of the bulk =========="
9910
9911 test_118f() {
9912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9913
9914         reset_async
9915
9916         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
9917         lctl set_param fail_loc=0x8000040a
9918
9919         # Should simulate EINVAL error which is fatal
9920         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9921         RC=$?
9922         if [[ $RC -eq 0 ]]; then
9923                 error "Must return error due to dropped pages, rc=$RC"
9924         fi
9925
9926         lctl set_param fail_loc=0x0
9927
9928         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9929         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9930         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9931                     grep -c writeback)
9932         if [[ $LOCKED -ne 0 ]]; then
9933                 error "Locked pages remain in cache, locked=$LOCKED"
9934         fi
9935
9936         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9937                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9938         fi
9939
9940         rm -f $DIR/$tfile
9941         echo "No pages locked after fsync"
9942
9943         reset_async
9944         return 0
9945 }
9946 run_test 118f "Simulate unrecoverable OSC side error =========="
9947
9948 test_118g() {
9949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9950
9951         reset_async
9952
9953         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9954         lctl set_param fail_loc=0x406
9955
9956         # simulate local -ENOMEM
9957         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9958         RC=$?
9959
9960         lctl set_param fail_loc=0
9961         if [[ $RC -eq 0 ]]; then
9962                 error "Must return error due to dropped pages, rc=$RC"
9963         fi
9964
9965         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9966         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9967         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9968                         grep -c writeback)
9969         if [[ $LOCKED -ne 0 ]]; then
9970                 error "Locked pages remain in cache, locked=$LOCKED"
9971         fi
9972
9973         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9974                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9975         fi
9976
9977         rm -f $DIR/$tfile
9978         echo "No pages locked after fsync"
9979
9980         reset_async
9981         return 0
9982 }
9983 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
9984
9985 test_118h() {
9986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9987         remote_ost_nodsh && skip "remote OST with nodsh"
9988
9989         reset_async
9990
9991         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9992         set_nodes_failloc "$(osts_nodes)" 0x20e
9993         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9994         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9995         RC=$?
9996
9997         set_nodes_failloc "$(osts_nodes)" 0
9998         if [[ $RC -eq 0 ]]; then
9999                 error "Must return error due to dropped pages, rc=$RC"
10000         fi
10001
10002         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10003         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10004         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10005                     grep -c writeback)
10006         if [[ $LOCKED -ne 0 ]]; then
10007                 error "Locked pages remain in cache, locked=$LOCKED"
10008         fi
10009
10010         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10011                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10012         fi
10013
10014         rm -f $DIR/$tfile
10015         echo "No pages locked after fsync"
10016
10017         return 0
10018 }
10019 run_test 118h "Verify timeout in handling recoverables errors  =========="
10020
10021 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10022
10023 test_118i() {
10024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10025         remote_ost_nodsh && skip "remote OST with nodsh"
10026
10027         reset_async
10028
10029         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10030         set_nodes_failloc "$(osts_nodes)" 0x20e
10031
10032         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10033         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10034         PID=$!
10035         sleep 5
10036         set_nodes_failloc "$(osts_nodes)" 0
10037
10038         wait $PID
10039         RC=$?
10040         if [[ $RC -ne 0 ]]; then
10041                 error "got error, but should be not, rc=$RC"
10042         fi
10043
10044         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10045         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10046         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10047         if [[ $LOCKED -ne 0 ]]; then
10048                 error "Locked pages remain in cache, locked=$LOCKED"
10049         fi
10050
10051         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10052                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10053         fi
10054
10055         rm -f $DIR/$tfile
10056         echo "No pages locked after fsync"
10057
10058         return 0
10059 }
10060 run_test 118i "Fix error before timeout in recoverable error  =========="
10061
10062 [ "$SLOW" = "no" ] && set_resend_count 4
10063
10064 test_118j() {
10065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10066         remote_ost_nodsh && skip "remote OST with nodsh"
10067
10068         reset_async
10069
10070         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10071         set_nodes_failloc "$(osts_nodes)" 0x220
10072
10073         # return -EIO from OST
10074         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10075         RC=$?
10076         set_nodes_failloc "$(osts_nodes)" 0x0
10077         if [[ $RC -eq 0 ]]; then
10078                 error "Must return error due to dropped pages, rc=$RC"
10079         fi
10080
10081         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10082         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10083         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10084         if [[ $LOCKED -ne 0 ]]; then
10085                 error "Locked pages remain in cache, locked=$LOCKED"
10086         fi
10087
10088         # in recoverable error on OST we want resend and stay until it finished
10089         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10090                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10091         fi
10092
10093         rm -f $DIR/$tfile
10094         echo "No pages locked after fsync"
10095
10096         return 0
10097 }
10098 run_test 118j "Simulate unrecoverable OST side error =========="
10099
10100 test_118k()
10101 {
10102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10103         remote_ost_nodsh && skip "remote OSTs with nodsh"
10104
10105         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10106         set_nodes_failloc "$(osts_nodes)" 0x20e
10107         test_mkdir $DIR/$tdir
10108
10109         for ((i=0;i<10;i++)); do
10110                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10111                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10112                 SLEEPPID=$!
10113                 sleep 0.500s
10114                 kill $SLEEPPID
10115                 wait $SLEEPPID
10116         done
10117
10118         set_nodes_failloc "$(osts_nodes)" 0
10119         rm -rf $DIR/$tdir
10120 }
10121 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10122
10123 test_118l() # LU-646
10124 {
10125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10126
10127         test_mkdir $DIR/$tdir
10128         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10129         rm -rf $DIR/$tdir
10130 }
10131 run_test 118l "fsync dir"
10132
10133 test_118m() # LU-3066
10134 {
10135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10136
10137         test_mkdir $DIR/$tdir
10138         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10139         rm -rf $DIR/$tdir
10140 }
10141 run_test 118m "fdatasync dir ========="
10142
10143 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10144
10145 test_118n()
10146 {
10147         local begin
10148         local end
10149
10150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10151         remote_ost_nodsh && skip "remote OSTs with nodsh"
10152
10153         # Sleep to avoid a cached response.
10154         #define OBD_STATFS_CACHE_SECONDS 1
10155         sleep 2
10156
10157         # Inject a 10 second delay in the OST_STATFS handler.
10158         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10159         set_nodes_failloc "$(osts_nodes)" 0x242
10160
10161         begin=$SECONDS
10162         stat --file-system $MOUNT > /dev/null
10163         end=$SECONDS
10164
10165         set_nodes_failloc "$(osts_nodes)" 0
10166
10167         if ((end - begin > 20)); then
10168             error "statfs took $((end - begin)) seconds, expected 10"
10169         fi
10170 }
10171 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10172
10173 test_119a() # bug 11737
10174 {
10175         BSIZE=$((512 * 1024))
10176         directio write $DIR/$tfile 0 1 $BSIZE
10177         # We ask to read two blocks, which is more than a file size.
10178         # directio will indicate an error when requested and actual
10179         # sizes aren't equeal (a normal situation in this case) and
10180         # print actual read amount.
10181         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10182         if [ "$NOB" != "$BSIZE" ]; then
10183                 error "read $NOB bytes instead of $BSIZE"
10184         fi
10185         rm -f $DIR/$tfile
10186 }
10187 run_test 119a "Short directIO read must return actual read amount"
10188
10189 test_119b() # bug 11737
10190 {
10191         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10192
10193         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
10194         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
10195         sync
10196         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
10197                 error "direct read failed"
10198         rm -f $DIR/$tfile
10199 }
10200 run_test 119b "Sparse directIO read must return actual read amount"
10201
10202 test_119c() # bug 13099
10203 {
10204         BSIZE=1048576
10205         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
10206         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
10207         rm -f $DIR/$tfile
10208 }
10209 run_test 119c "Testing for direct read hitting hole"
10210
10211 test_119d() # bug 15950
10212 {
10213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10214
10215         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
10216         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
10217         BSIZE=1048576
10218         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
10219         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
10220         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
10221         lctl set_param fail_loc=0x40d
10222         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
10223         pid_dio=$!
10224         sleep 1
10225         cat $DIR/$tfile > /dev/null &
10226         lctl set_param fail_loc=0
10227         pid_reads=$!
10228         wait $pid_dio
10229         log "the DIO writes have completed, now wait for the reads (should not block very long)"
10230         sleep 2
10231         [ -n "`ps h -p $pid_reads -o comm`" ] && \
10232         error "the read rpcs have not completed in 2s"
10233         rm -f $DIR/$tfile
10234         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
10235 }
10236 run_test 119d "The DIO path should try to send a new rpc once one is completed"
10237
10238 test_120a() {
10239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10240         remote_mds_nodsh && skip "remote MDS with nodsh"
10241         test_mkdir -i0 -c1 $DIR/$tdir
10242         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10243                 skip_env "no early lock cancel on server"
10244
10245         lru_resize_disable mdc
10246         lru_resize_disable osc
10247         cancel_lru_locks mdc
10248         # asynchronous object destroy at MDT could cause bl ast to client
10249         cancel_lru_locks osc
10250
10251         stat $DIR/$tdir > /dev/null
10252         can1=$(do_facet mds1 \
10253                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10254                awk '/ldlm_cancel/ {print $2}')
10255         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10256                awk '/ldlm_bl_callback/ {print $2}')
10257         test_mkdir -i0 -c1 $DIR/$tdir/d1
10258         can2=$(do_facet mds1 \
10259                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10260                awk '/ldlm_cancel/ {print $2}')
10261         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10262                awk '/ldlm_bl_callback/ {print $2}')
10263         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10264         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10265         lru_resize_enable mdc
10266         lru_resize_enable osc
10267 }
10268 run_test 120a "Early Lock Cancel: mkdir test"
10269
10270 test_120b() {
10271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10272         remote_mds_nodsh && skip "remote MDS with nodsh"
10273         test_mkdir $DIR/$tdir
10274         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10275                 skip_env "no early lock cancel on server"
10276
10277         lru_resize_disable mdc
10278         lru_resize_disable osc
10279         cancel_lru_locks mdc
10280         stat $DIR/$tdir > /dev/null
10281         can1=$(do_facet $SINGLEMDS \
10282                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10283                awk '/ldlm_cancel/ {print $2}')
10284         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10285                awk '/ldlm_bl_callback/ {print $2}')
10286         touch $DIR/$tdir/f1
10287         can2=$(do_facet $SINGLEMDS \
10288                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10289                awk '/ldlm_cancel/ {print $2}')
10290         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10291                awk '/ldlm_bl_callback/ {print $2}')
10292         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10293         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10294         lru_resize_enable mdc
10295         lru_resize_enable osc
10296 }
10297 run_test 120b "Early Lock Cancel: create test"
10298
10299 test_120c() {
10300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10301         remote_mds_nodsh && skip "remote MDS with nodsh"
10302         test_mkdir -i0 -c1 $DIR/$tdir
10303         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10304                 skip "no early lock cancel on server"
10305
10306         lru_resize_disable mdc
10307         lru_resize_disable osc
10308         test_mkdir -i0 -c1 $DIR/$tdir/d1
10309         test_mkdir -i0 -c1 $DIR/$tdir/d2
10310         touch $DIR/$tdir/d1/f1
10311         cancel_lru_locks mdc
10312         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
10313         can1=$(do_facet mds1 \
10314                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10315                awk '/ldlm_cancel/ {print $2}')
10316         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10317                awk '/ldlm_bl_callback/ {print $2}')
10318         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10319         can2=$(do_facet mds1 \
10320                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10321                awk '/ldlm_cancel/ {print $2}')
10322         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10323                awk '/ldlm_bl_callback/ {print $2}')
10324         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10325         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10326         lru_resize_enable mdc
10327         lru_resize_enable osc
10328 }
10329 run_test 120c "Early Lock Cancel: link test"
10330
10331 test_120d() {
10332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10333         remote_mds_nodsh && skip "remote MDS with nodsh"
10334         test_mkdir -i0 -c1 $DIR/$tdir
10335         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10336                 skip_env "no early lock cancel on server"
10337
10338         lru_resize_disable mdc
10339         lru_resize_disable osc
10340         touch $DIR/$tdir
10341         cancel_lru_locks mdc
10342         stat $DIR/$tdir > /dev/null
10343         can1=$(do_facet mds1 \
10344                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10345                awk '/ldlm_cancel/ {print $2}')
10346         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10347                awk '/ldlm_bl_callback/ {print $2}')
10348         chmod a+x $DIR/$tdir
10349         can2=$(do_facet mds1 \
10350                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10351                awk '/ldlm_cancel/ {print $2}')
10352         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10353                awk '/ldlm_bl_callback/ {print $2}')
10354         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10355         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10356         lru_resize_enable mdc
10357         lru_resize_enable osc
10358 }
10359 run_test 120d "Early Lock Cancel: setattr test"
10360
10361 test_120e() {
10362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10363         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10364                 skip_env "no early lock cancel on server"
10365         remote_mds_nodsh && skip "remote MDS with nodsh"
10366
10367         local dlmtrace_set=false
10368
10369         test_mkdir -i0 -c1 $DIR/$tdir
10370         lru_resize_disable mdc
10371         lru_resize_disable osc
10372         ! $LCTL get_param debug | grep -q dlmtrace &&
10373                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
10374         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
10375         cancel_lru_locks mdc
10376         cancel_lru_locks osc
10377         dd if=$DIR/$tdir/f1 of=/dev/null
10378         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
10379         # XXX client can not do early lock cancel of OST lock
10380         # during unlink (LU-4206), so cancel osc lock now.
10381         sleep 2
10382         cancel_lru_locks osc
10383         can1=$(do_facet mds1 \
10384                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10385                awk '/ldlm_cancel/ {print $2}')
10386         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10387                awk '/ldlm_bl_callback/ {print $2}')
10388         unlink $DIR/$tdir/f1
10389         sleep 5
10390         can2=$(do_facet mds1 \
10391                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10392                awk '/ldlm_cancel/ {print $2}')
10393         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10394                awk '/ldlm_bl_callback/ {print $2}')
10395         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
10396                 $LCTL dk $TMP/cancel.debug.txt
10397         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
10398                 $LCTL dk $TMP/blocking.debug.txt
10399         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
10400         lru_resize_enable mdc
10401         lru_resize_enable osc
10402 }
10403 run_test 120e "Early Lock Cancel: unlink test"
10404
10405 test_120f() {
10406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10407         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10408                 skip_env "no early lock cancel on server"
10409         remote_mds_nodsh && skip "remote MDS with nodsh"
10410
10411         test_mkdir -i0 -c1 $DIR/$tdir
10412         lru_resize_disable mdc
10413         lru_resize_disable osc
10414         test_mkdir -i0 -c1 $DIR/$tdir/d1
10415         test_mkdir -i0 -c1 $DIR/$tdir/d2
10416         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
10417         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
10418         cancel_lru_locks mdc
10419         cancel_lru_locks osc
10420         dd if=$DIR/$tdir/d1/f1 of=/dev/null
10421         dd if=$DIR/$tdir/d2/f2 of=/dev/null
10422         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
10423         # XXX client can not do early lock cancel of OST lock
10424         # during rename (LU-4206), so cancel osc lock now.
10425         sleep 2
10426         cancel_lru_locks osc
10427         can1=$(do_facet mds1 \
10428                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10429                awk '/ldlm_cancel/ {print $2}')
10430         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10431                awk '/ldlm_bl_callback/ {print $2}')
10432         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10433         sleep 5
10434         can2=$(do_facet mds1 \
10435                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10436                awk '/ldlm_cancel/ {print $2}')
10437         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10438                awk '/ldlm_bl_callback/ {print $2}')
10439         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10440         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10441         lru_resize_enable mdc
10442         lru_resize_enable osc
10443 }
10444 run_test 120f "Early Lock Cancel: rename test"
10445
10446 test_120g() {
10447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10448         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10449                 skip_env "no early lock cancel on server"
10450         remote_mds_nodsh && skip "remote MDS with nodsh"
10451
10452         lru_resize_disable mdc
10453         lru_resize_disable osc
10454         count=10000
10455         echo create $count files
10456         test_mkdir $DIR/$tdir
10457         cancel_lru_locks mdc
10458         cancel_lru_locks osc
10459         t0=$(date +%s)
10460
10461         can0=$(do_facet $SINGLEMDS \
10462                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10463                awk '/ldlm_cancel/ {print $2}')
10464         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10465                awk '/ldlm_bl_callback/ {print $2}')
10466         createmany -o $DIR/$tdir/f $count
10467         sync
10468         can1=$(do_facet $SINGLEMDS \
10469                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10470                awk '/ldlm_cancel/ {print $2}')
10471         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10472                awk '/ldlm_bl_callback/ {print $2}')
10473         t1=$(date +%s)
10474         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10475         echo rm $count files
10476         rm -r $DIR/$tdir
10477         sync
10478         can2=$(do_facet $SINGLEMDS \
10479                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10480                awk '/ldlm_cancel/ {print $2}')
10481         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10482                awk '/ldlm_bl_callback/ {print $2}')
10483         t2=$(date +%s)
10484         echo total: $count removes in $((t2-t1))
10485         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10486         sleep 2
10487         # wait for commitment of removal
10488         lru_resize_enable mdc
10489         lru_resize_enable osc
10490 }
10491 run_test 120g "Early Lock Cancel: performance test"
10492
10493 test_121() { #bug #10589
10494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10495
10496         rm -rf $DIR/$tfile
10497         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10498 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10499         lctl set_param fail_loc=0x310
10500         cancel_lru_locks osc > /dev/null
10501         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10502         lctl set_param fail_loc=0
10503         [[ $reads -eq $writes ]] ||
10504                 error "read $reads blocks, must be $writes blocks"
10505 }
10506 run_test 121 "read cancel race ========="
10507
10508 test_123a() { # was test 123, statahead(bug 11401)
10509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10510
10511         SLOWOK=0
10512         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10513                 log "testing UP system. Performance may be lower than expected."
10514                 SLOWOK=1
10515         fi
10516
10517         rm -rf $DIR/$tdir
10518         test_mkdir $DIR/$tdir
10519         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10520         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10521         MULT=10
10522         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10523                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10524
10525                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10526                 lctl set_param -n llite.*.statahead_max 0
10527                 lctl get_param llite.*.statahead_max
10528                 cancel_lru_locks mdc
10529                 cancel_lru_locks osc
10530                 stime=`date +%s`
10531                 time ls -l $DIR/$tdir | wc -l
10532                 etime=`date +%s`
10533                 delta=$((etime - stime))
10534                 log "ls $i files without statahead: $delta sec"
10535                 lctl set_param llite.*.statahead_max=$max
10536
10537                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10538                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10539                 cancel_lru_locks mdc
10540                 cancel_lru_locks osc
10541                 stime=`date +%s`
10542                 time ls -l $DIR/$tdir | wc -l
10543                 etime=`date +%s`
10544                 delta_sa=$((etime - stime))
10545                 log "ls $i files with statahead: $delta_sa sec"
10546                 lctl get_param -n llite.*.statahead_stats
10547                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10548
10549                 [[ $swrong -lt $ewrong ]] &&
10550                         log "statahead was stopped, maybe too many locks held!"
10551                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10552
10553                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10554                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10555                     lctl set_param -n llite.*.statahead_max 0
10556                     lctl get_param llite.*.statahead_max
10557                     cancel_lru_locks mdc
10558                     cancel_lru_locks osc
10559                     stime=`date +%s`
10560                     time ls -l $DIR/$tdir | wc -l
10561                     etime=`date +%s`
10562                     delta=$((etime - stime))
10563                     log "ls $i files again without statahead: $delta sec"
10564                     lctl set_param llite.*.statahead_max=$max
10565                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10566                         if [  $SLOWOK -eq 0 ]; then
10567                                 error "ls $i files is slower with statahead!"
10568                         else
10569                                 log "ls $i files is slower with statahead!"
10570                         fi
10571                         break
10572                     fi
10573                 fi
10574
10575                 [ $delta -gt 20 ] && break
10576                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10577                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10578         done
10579         log "ls done"
10580
10581         stime=`date +%s`
10582         rm -r $DIR/$tdir
10583         sync
10584         etime=`date +%s`
10585         delta=$((etime - stime))
10586         log "rm -r $DIR/$tdir/: $delta seconds"
10587         log "rm done"
10588         lctl get_param -n llite.*.statahead_stats
10589 }
10590 run_test 123a "verify statahead work"
10591
10592 test_123b () { # statahead(bug 15027)
10593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10594
10595         test_mkdir $DIR/$tdir
10596         createmany -o $DIR/$tdir/$tfile-%d 1000
10597
10598         cancel_lru_locks mdc
10599         cancel_lru_locks osc
10600
10601 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10602         lctl set_param fail_loc=0x80000803
10603         ls -lR $DIR/$tdir > /dev/null
10604         log "ls done"
10605         lctl set_param fail_loc=0x0
10606         lctl get_param -n llite.*.statahead_stats
10607         rm -r $DIR/$tdir
10608         sync
10609
10610 }
10611 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10612
10613 test_124a() {
10614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10615         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10616                 skip_env "no lru resize on server"
10617
10618         local NR=2000
10619
10620         test_mkdir $DIR/$tdir
10621
10622         log "create $NR files at $DIR/$tdir"
10623         createmany -o $DIR/$tdir/f $NR ||
10624                 error "failed to create $NR files in $DIR/$tdir"
10625
10626         cancel_lru_locks mdc
10627         ls -l $DIR/$tdir > /dev/null
10628
10629         local NSDIR=""
10630         local LRU_SIZE=0
10631         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10632                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10633                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10634                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10635                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10636                         log "NSDIR=$NSDIR"
10637                         log "NS=$(basename $NSDIR)"
10638                         break
10639                 fi
10640         done
10641
10642         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10643                 skip "Not enough cached locks created!"
10644         fi
10645         log "LRU=$LRU_SIZE"
10646
10647         local SLEEP=30
10648
10649         # We know that lru resize allows one client to hold $LIMIT locks
10650         # for 10h. After that locks begin to be killed by client.
10651         local MAX_HRS=10
10652         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10653         log "LIMIT=$LIMIT"
10654         if [ $LIMIT -lt $LRU_SIZE ]; then
10655                 skip "Limit is too small $LIMIT"
10656         fi
10657
10658         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10659         # killing locks. Some time was spent for creating locks. This means
10660         # that up to the moment of sleep finish we must have killed some of
10661         # them (10-100 locks). This depends on how fast ther were created.
10662         # Many of them were touched in almost the same moment and thus will
10663         # be killed in groups.
10664         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10665
10666         # Use $LRU_SIZE_B here to take into account real number of locks
10667         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10668         local LRU_SIZE_B=$LRU_SIZE
10669         log "LVF=$LVF"
10670         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10671         log "OLD_LVF=$OLD_LVF"
10672         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10673
10674         # Let's make sure that we really have some margin. Client checks
10675         # cached locks every 10 sec.
10676         SLEEP=$((SLEEP+20))
10677         log "Sleep ${SLEEP} sec"
10678         local SEC=0
10679         while ((SEC<$SLEEP)); do
10680                 echo -n "..."
10681                 sleep 5
10682                 SEC=$((SEC+5))
10683                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10684                 echo -n "$LRU_SIZE"
10685         done
10686         echo ""
10687         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10688         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10689
10690         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10691                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10692                 unlinkmany $DIR/$tdir/f $NR
10693                 return
10694         }
10695
10696         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10697         log "unlink $NR files at $DIR/$tdir"
10698         unlinkmany $DIR/$tdir/f $NR
10699 }
10700 run_test 124a "lru resize ======================================="
10701
10702 get_max_pool_limit()
10703 {
10704         local limit=$($LCTL get_param \
10705                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10706         local max=0
10707         for l in $limit; do
10708                 if [[ $l -gt $max ]]; then
10709                         max=$l
10710                 fi
10711         done
10712         echo $max
10713 }
10714
10715 test_124b() {
10716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10717         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10718                 skip_env "no lru resize on server"
10719
10720         LIMIT=$(get_max_pool_limit)
10721
10722         NR=$(($(default_lru_size)*20))
10723         if [[ $NR -gt $LIMIT ]]; then
10724                 log "Limit lock number by $LIMIT locks"
10725                 NR=$LIMIT
10726         fi
10727
10728         IFree=$(mdsrate_inodes_available)
10729         if [ $IFree -lt $NR ]; then
10730                 log "Limit lock number by $IFree inodes"
10731                 NR=$IFree
10732         fi
10733
10734         lru_resize_disable mdc
10735         test_mkdir -p $DIR/$tdir/disable_lru_resize
10736
10737         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10738         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10739         cancel_lru_locks mdc
10740         stime=`date +%s`
10741         PID=""
10742         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10743         PID="$PID $!"
10744         sleep 2
10745         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10746         PID="$PID $!"
10747         sleep 2
10748         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10749         PID="$PID $!"
10750         wait $PID
10751         etime=`date +%s`
10752         nolruresize_delta=$((etime-stime))
10753         log "ls -la time: $nolruresize_delta seconds"
10754         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10755         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10756
10757         lru_resize_enable mdc
10758         test_mkdir -p $DIR/$tdir/enable_lru_resize
10759
10760         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10761         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10762         cancel_lru_locks mdc
10763         stime=`date +%s`
10764         PID=""
10765         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10766         PID="$PID $!"
10767         sleep 2
10768         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10769         PID="$PID $!"
10770         sleep 2
10771         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10772         PID="$PID $!"
10773         wait $PID
10774         etime=`date +%s`
10775         lruresize_delta=$((etime-stime))
10776         log "ls -la time: $lruresize_delta seconds"
10777         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10778
10779         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10780                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10781         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10782                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10783         else
10784                 log "lru resize performs the same with no lru resize"
10785         fi
10786         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10787 }
10788 run_test 124b "lru resize (performance test) ======================="
10789
10790 test_124c() {
10791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10792         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10793                 skip_env "no lru resize on server"
10794
10795         # cache ununsed locks on client
10796         local nr=100
10797         cancel_lru_locks mdc
10798         test_mkdir $DIR/$tdir
10799         createmany -o $DIR/$tdir/f $nr ||
10800                 error "failed to create $nr files in $DIR/$tdir"
10801         ls -l $DIR/$tdir > /dev/null
10802
10803         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10804         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10805         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10806         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10807         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10808
10809         # set lru_max_age to 1 sec
10810         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10811         echo "sleep $((recalc_p * 2)) seconds..."
10812         sleep $((recalc_p * 2))
10813
10814         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10815         # restore lru_max_age
10816         $LCTL set_param -n $nsdir.lru_max_age $max_age
10817         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10818         unlinkmany $DIR/$tdir/f $nr
10819 }
10820 run_test 124c "LRUR cancel very aged locks"
10821
10822 test_125() { # 13358
10823         $LCTL get_param -n llite.*.client_type | grep -q local ||
10824                 skip "must run as local client"
10825         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10826                 skip_env "must have acl enabled"
10827         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10828
10829         test_mkdir $DIR/$tdir
10830         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10831         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10832         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10833 }
10834 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10835
10836 test_126() { # bug 12829/13455
10837         $GSS && skip_env "must run as gss disabled"
10838         $LCTL get_param -n llite.*.client_type | grep -q local ||
10839                 skip "must run as local client"
10840         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10841
10842         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10843         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10844         rm -f $DIR/$tfile
10845         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10846 }
10847 run_test 126 "check that the fsgid provided by the client is taken into account"
10848
10849 test_127a() { # bug 15521
10850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10851
10852         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
10853         $LCTL set_param osc.*.stats=0
10854         FSIZE=$((2048 * 1024))
10855         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
10856         cancel_lru_locks osc
10857         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
10858
10859         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
10860         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
10861                 echo "got $COUNT $NAME"
10862                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
10863                 eval $NAME=$COUNT || error "Wrong proc format"
10864
10865                 case $NAME in
10866                         read_bytes|write_bytes)
10867                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
10868                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
10869                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
10870                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
10871                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
10872                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
10873                                 error "sumsquare is too small: $SUMSQ"
10874                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
10875                                 error "sumsquare is too big: $SUMSQ"
10876                         ;;
10877                         *) ;;
10878                 esac
10879         done < $DIR/${tfile}.tmp
10880
10881         #check that we actually got some stats
10882         [ "$read_bytes" ] || error "Missing read_bytes stats"
10883         [ "$write_bytes" ] || error "Missing write_bytes stats"
10884         [ "$read_bytes" != 0 ] || error "no read done"
10885         [ "$write_bytes" != 0 ] || error "no write done"
10886 }
10887 run_test 127a "verify the client stats are sane"
10888
10889 test_127b() { # bug LU-333
10890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10891         local name count samp unit min max sum sumsq
10892
10893         $LCTL set_param llite.*.stats=0
10894
10895         # perform 2 reads and writes so MAX is different from SUM.
10896         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10897         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10898         cancel_lru_locks osc
10899         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10900         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10901
10902         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
10903         while read name count samp unit min max sum sumsq; do
10904                 echo "got $count $name"
10905                 eval $name=$count || error "Wrong proc format"
10906
10907                 case $name in
10908                 read_bytes)
10909                         [ $count -ne 2 ] && error "count is not 2: $count"
10910                         [ $min -ne $PAGE_SIZE ] &&
10911                                 error "min is not $PAGE_SIZE: $min"
10912                         [ $max -ne $PAGE_SIZE ] &&
10913                                 error "max is incorrect: $max"
10914                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10915                                 error "sum is wrong: $sum"
10916                         ;;
10917                 write_bytes)
10918                         [ $count -ne 2 ] && error "count is not 2: $count"
10919                         [ $min -ne $PAGE_SIZE ] &&
10920                                 error "min is not $PAGE_SIZE: $min"
10921                         [ $max -ne $PAGE_SIZE ] &&
10922                                 error "max is incorrect: $max"
10923                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10924                                 error "sum is wrong: $sum"
10925                         ;;
10926                 *) ;;
10927                 esac
10928         done < $TMP/$tfile.tmp
10929
10930         #check that we actually got some stats
10931         [ "$read_bytes" ] || error "Missing read_bytes stats"
10932         [ "$write_bytes" ] || error "Missing write_bytes stats"
10933         [ "$read_bytes" != 0 ] || error "no read done"
10934         [ "$write_bytes" != 0 ] || error "no write done"
10935
10936         rm -f $TMP/${tfile}.tmp
10937 }
10938 run_test 127b "verify the llite client stats are sane"
10939
10940 test_128() { # bug 15212
10941         touch $DIR/$tfile
10942         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
10943                 find $DIR/$tfile
10944                 find $DIR/$tfile
10945         EOF
10946
10947         result=$(grep error $TMP/$tfile.log)
10948         rm -f $DIR/$tfile $TMP/$tfile.log
10949         [ -z "$result" ] ||
10950                 error "consecutive find's under interactive lfs failed"
10951 }
10952 run_test 128 "interactive lfs for 2 consecutive find's"
10953
10954 set_dir_limits () {
10955         local mntdev
10956         local canondev
10957         local node
10958
10959         local ldproc=/proc/fs/ldiskfs
10960         local facets=$(get_facets MDS)
10961
10962         for facet in ${facets//,/ }; do
10963                 canondev=$(ldiskfs_canon \
10964                            *.$(convert_facet2label $facet).mntdev $facet)
10965                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
10966                         ldproc=/sys/fs/ldiskfs
10967                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
10968                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
10969         done
10970 }
10971
10972 check_mds_dmesg() {
10973         local facets=$(get_facets MDS)
10974         for facet in ${facets//,/ }; do
10975                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
10976         done
10977         return 1
10978 }
10979
10980 test_129() {
10981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10982         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
10983                 skip "Need MDS version with at least 2.5.56"
10984         if [ "$mds1_FSTYPE" != ldiskfs ]; then
10985                 skip_env "ldiskfs only test"
10986         fi
10987         remote_mds_nodsh && skip "remote MDS with nodsh"
10988
10989         local ENOSPC=28
10990         local EFBIG=27
10991         local has_warning=false
10992
10993         rm -rf $DIR/$tdir
10994         mkdir -p $DIR/$tdir
10995
10996         # block size of mds1
10997         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
10998         set_dir_limits $maxsize $maxsize
10999         local dirsize=$(stat -c%s "$DIR/$tdir")
11000         local nfiles=0
11001         while [[ $dirsize -le $maxsize ]]; do
11002                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
11003                 rc=$?
11004                 if ! $has_warning; then
11005                         check_mds_dmesg '"is approaching"' && has_warning=true
11006                 fi
11007                 # check two errors:
11008                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11009                 # EFBIG for previous versions included in ldiskfs series
11010                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11011                         set_dir_limits 0 0
11012                         echo "return code $rc received as expected"
11013
11014                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11015                                 error_exit "create failed w/o dir size limit"
11016
11017                         check_mds_dmesg '"has reached"' ||
11018                                 error_exit "reached message should be output"
11019
11020                         [ $has_warning = "false" ] &&
11021                                 error_exit "warning message should be output"
11022
11023                         dirsize=$(stat -c%s "$DIR/$tdir")
11024
11025                         [[ $dirsize -ge $maxsize ]] && return 0
11026                         error_exit "current dir size $dirsize, " \
11027                                    "previous limit $maxsize"
11028                 elif [ $rc -ne 0 ]; then
11029                         set_dir_limits 0 0
11030                         error_exit "return $rc received instead of expected " \
11031                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11032                 fi
11033                 nfiles=$((nfiles + 1))
11034                 dirsize=$(stat -c%s "$DIR/$tdir")
11035         done
11036
11037         set_dir_limits 0 0
11038         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11039 }
11040 run_test 129 "test directory size limit ========================"
11041
11042 OLDIFS="$IFS"
11043 cleanup_130() {
11044         trap 0
11045         IFS="$OLDIFS"
11046 }
11047
11048 test_130a() {
11049         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11050         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11051
11052         trap cleanup_130 EXIT RETURN
11053
11054         local fm_file=$DIR/$tfile
11055         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
11056         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
11057                 error "dd failed for $fm_file"
11058
11059         # LU-1795: test filefrag/FIEMAP once, even if unsupported
11060         filefrag -ves $fm_file
11061         RC=$?
11062         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11063                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11064         [ $RC != 0 ] && error "filefrag $fm_file failed"
11065
11066         filefrag_op=$(filefrag -ve -k $fm_file |
11067                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11068         lun=$($LFS getstripe -i $fm_file)
11069
11070         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
11071         IFS=$'\n'
11072         tot_len=0
11073         for line in $filefrag_op
11074         do
11075                 frag_lun=`echo $line | cut -d: -f5`
11076                 ext_len=`echo $line | cut -d: -f4`
11077                 if (( $frag_lun != $lun )); then
11078                         cleanup_130
11079                         error "FIEMAP on 1-stripe file($fm_file) failed"
11080                         return
11081                 fi
11082                 (( tot_len += ext_len ))
11083         done
11084
11085         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
11086                 cleanup_130
11087                 error "FIEMAP on 1-stripe file($fm_file) failed;"
11088                 return
11089         fi
11090
11091         cleanup_130
11092
11093         echo "FIEMAP on single striped file succeeded"
11094 }
11095 run_test 130a "FIEMAP (1-stripe file)"
11096
11097 test_130b() {
11098         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11099
11100         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11101         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11102
11103         trap cleanup_130 EXIT RETURN
11104
11105         local fm_file=$DIR/$tfile
11106         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11107                         error "setstripe on $fm_file"
11108         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11109                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11110
11111         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
11112                 error "dd failed on $fm_file"
11113
11114         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11115         filefrag_op=$(filefrag -ve -k $fm_file |
11116                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11117
11118         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11119                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11120
11121         IFS=$'\n'
11122         tot_len=0
11123         num_luns=1
11124         for line in $filefrag_op
11125         do
11126                 frag_lun=$(echo $line | cut -d: -f5 |
11127                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11128                 ext_len=$(echo $line | cut -d: -f4)
11129                 if (( $frag_lun != $last_lun )); then
11130                         if (( tot_len != 1024 )); then
11131                                 cleanup_130
11132                                 error "FIEMAP on $fm_file failed; returned " \
11133                                 "len $tot_len for OST $last_lun instead of 1024"
11134                                 return
11135                         else
11136                                 (( num_luns += 1 ))
11137                                 tot_len=0
11138                         fi
11139                 fi
11140                 (( tot_len += ext_len ))
11141                 last_lun=$frag_lun
11142         done
11143         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
11144                 cleanup_130
11145                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11146                         "luns or wrong len for OST $last_lun"
11147                 return
11148         fi
11149
11150         cleanup_130
11151
11152         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
11153 }
11154 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
11155
11156 test_130c() {
11157         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11158
11159         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11160         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11161
11162         trap cleanup_130 EXIT RETURN
11163
11164         local fm_file=$DIR/$tfile
11165         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
11166         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11167                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11168
11169         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
11170                         error "dd failed on $fm_file"
11171
11172         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11173         filefrag_op=$(filefrag -ve -k $fm_file |
11174                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11175
11176         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11177                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11178
11179         IFS=$'\n'
11180         tot_len=0
11181         num_luns=1
11182         for line in $filefrag_op
11183         do
11184                 frag_lun=$(echo $line | cut -d: -f5 |
11185                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11186                 ext_len=$(echo $line | cut -d: -f4)
11187                 if (( $frag_lun != $last_lun )); then
11188                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
11189                         if (( logical != 512 )); then
11190                                 cleanup_130
11191                                 error "FIEMAP on $fm_file failed; returned " \
11192                                 "logical start for lun $logical instead of 512"
11193                                 return
11194                         fi
11195                         if (( tot_len != 512 )); then
11196                                 cleanup_130
11197                                 error "FIEMAP on $fm_file failed; returned " \
11198                                 "len $tot_len for OST $last_lun instead of 1024"
11199                                 return
11200                         else
11201                                 (( num_luns += 1 ))
11202                                 tot_len=0
11203                         fi
11204                 fi
11205                 (( tot_len += ext_len ))
11206                 last_lun=$frag_lun
11207         done
11208         if (( num_luns != 2 || tot_len != 512 )); then
11209                 cleanup_130
11210                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11211                         "luns or wrong len for OST $last_lun"
11212                 return
11213         fi
11214
11215         cleanup_130
11216
11217         echo "FIEMAP on 2-stripe file with hole succeeded"
11218 }
11219 run_test 130c "FIEMAP (2-stripe file with hole)"
11220
11221 test_130d() {
11222         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
11223
11224         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11225         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11226
11227         trap cleanup_130 EXIT RETURN
11228
11229         local fm_file=$DIR/$tfile
11230         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11231                         error "setstripe on $fm_file"
11232         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11233                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11234
11235         local actual_stripe_count=$($LFS getstripe -c $fm_file)
11236         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
11237                 error "dd failed on $fm_file"
11238
11239         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11240         filefrag_op=$(filefrag -ve -k $fm_file |
11241                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11242
11243         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11244                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11245
11246         IFS=$'\n'
11247         tot_len=0
11248         num_luns=1
11249         for line in $filefrag_op
11250         do
11251                 frag_lun=$(echo $line | cut -d: -f5 |
11252                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11253                 ext_len=$(echo $line | cut -d: -f4)
11254                 if (( $frag_lun != $last_lun )); then
11255                         if (( tot_len != 1024 )); then
11256                                 cleanup_130
11257                                 error "FIEMAP on $fm_file failed; returned " \
11258                                 "len $tot_len for OST $last_lun instead of 1024"
11259                                 return
11260                         else
11261                                 (( num_luns += 1 ))
11262                                 tot_len=0
11263                         fi
11264                 fi
11265                 (( tot_len += ext_len ))
11266                 last_lun=$frag_lun
11267         done
11268         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
11269                 cleanup_130
11270                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11271                         "luns or wrong len for OST $last_lun"
11272                 return
11273         fi
11274
11275         cleanup_130
11276
11277         echo "FIEMAP on N-stripe file succeeded"
11278 }
11279 run_test 130d "FIEMAP (N-stripe file)"
11280
11281 test_130e() {
11282         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11283
11284         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11285         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11286
11287         trap cleanup_130 EXIT RETURN
11288
11289         local fm_file=$DIR/$tfile
11290         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
11291         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11292                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11293
11294         NUM_BLKS=512
11295         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
11296         for ((i = 0; i < $NUM_BLKS; i++))
11297         do
11298                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
11299         done
11300
11301         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11302         filefrag_op=$(filefrag -ve -k $fm_file |
11303                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11304
11305         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11306                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11307
11308         IFS=$'\n'
11309         tot_len=0
11310         num_luns=1
11311         for line in $filefrag_op
11312         do
11313                 frag_lun=$(echo $line | cut -d: -f5 |
11314                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11315                 ext_len=$(echo $line | cut -d: -f4)
11316                 if (( $frag_lun != $last_lun )); then
11317                         if (( tot_len != $EXPECTED_LEN )); then
11318                                 cleanup_130
11319                                 error "FIEMAP on $fm_file failed; returned " \
11320                                 "len $tot_len for OST $last_lun instead " \
11321                                 "of $EXPECTED_LEN"
11322                                 return
11323                         else
11324                                 (( num_luns += 1 ))
11325                                 tot_len=0
11326                         fi
11327                 fi
11328                 (( tot_len += ext_len ))
11329                 last_lun=$frag_lun
11330         done
11331         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
11332                 cleanup_130
11333                 error "FIEMAP on $fm_file failed; returned wrong number " \
11334                         "of luns or wrong len for OST $last_lun"
11335                 return
11336         fi
11337
11338         cleanup_130
11339
11340         echo "FIEMAP with continuation calls succeeded"
11341 }
11342 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
11343
11344 test_130f() {
11345         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11346         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11347
11348         local fm_file=$DIR/$tfile
11349         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
11350                 error "multiop create with lov_delay_create on $fm_file"
11351
11352         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11353         filefrag_extents=$(filefrag -vek $fm_file |
11354                            awk '/extents? found/ { print $2 }')
11355         if [[ "$filefrag_extents" != "0" ]]; then
11356                 error "FIEMAP on $fm_file failed; " \
11357                       "returned $filefrag_extents expected 0"
11358         fi
11359
11360         rm -f $fm_file
11361 }
11362 run_test 130f "FIEMAP (unstriped file)"
11363
11364 # Test for writev/readv
11365 test_131a() {
11366         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
11367                 error "writev test failed"
11368         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
11369                 error "readv failed"
11370         rm -f $DIR/$tfile
11371 }
11372 run_test 131a "test iov's crossing stripe boundary for writev/readv"
11373
11374 test_131b() {
11375         local fsize=$((524288 + 1048576 + 1572864))
11376         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
11377                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11378                         error "append writev test failed"
11379
11380         ((fsize += 1572864 + 1048576))
11381         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
11382                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11383                         error "append writev test failed"
11384         rm -f $DIR/$tfile
11385 }
11386 run_test 131b "test append writev"
11387
11388 test_131c() {
11389         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
11390         error "NOT PASS"
11391 }
11392 run_test 131c "test read/write on file w/o objects"
11393
11394 test_131d() {
11395         rwv -f $DIR/$tfile -w -n 1 1572864
11396         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
11397         if [ "$NOB" != 1572864 ]; then
11398                 error "Short read filed: read $NOB bytes instead of 1572864"
11399         fi
11400         rm -f $DIR/$tfile
11401 }
11402 run_test 131d "test short read"
11403
11404 test_131e() {
11405         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
11406         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
11407         error "read hitting hole failed"
11408         rm -f $DIR/$tfile
11409 }
11410 run_test 131e "test read hitting hole"
11411
11412 check_stats() {
11413         local facet=$1
11414         local op=$2
11415         local want=${3:-0}
11416         local res
11417
11418         case $facet in
11419         mds*) res=$(do_facet $facet \
11420                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
11421                  ;;
11422         ost*) res=$(do_facet $facet \
11423                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
11424                  ;;
11425         *) error "Wrong facet '$facet'" ;;
11426         esac
11427         [ "$res" ] || error "The counter for $op on $facet was not incremented"
11428         # if the argument $3 is zero, it means any stat increment is ok.
11429         if [[ $want -gt 0 ]]; then
11430                 local count=$(echo $res | awk '{ print $2 }')
11431                 [[ $count -ne $want ]] &&
11432                         error "The $op counter on $facet is $count, not $want"
11433         fi
11434 }
11435
11436 test_133a() {
11437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11438         remote_ost_nodsh && skip "remote OST with nodsh"
11439         remote_mds_nodsh && skip "remote MDS with nodsh"
11440         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11441                 skip_env "MDS doesn't support rename stats"
11442
11443         local testdir=$DIR/${tdir}/stats_testdir
11444
11445         mkdir -p $DIR/${tdir}
11446
11447         # clear stats.
11448         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11449         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11450
11451         # verify mdt stats first.
11452         mkdir ${testdir} || error "mkdir failed"
11453         check_stats $SINGLEMDS "mkdir" 1
11454         touch ${testdir}/${tfile} || error "touch failed"
11455         check_stats $SINGLEMDS "open" 1
11456         check_stats $SINGLEMDS "close" 1
11457         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
11458                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
11459                 check_stats $SINGLEMDS "mknod" 2
11460         }
11461         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
11462         check_stats $SINGLEMDS "unlink" 1
11463         rm -f ${testdir}/${tfile} || error "file remove failed"
11464         check_stats $SINGLEMDS "unlink" 2
11465
11466         # remove working dir and check mdt stats again.
11467         rmdir ${testdir} || error "rmdir failed"
11468         check_stats $SINGLEMDS "rmdir" 1
11469
11470         local testdir1=$DIR/${tdir}/stats_testdir1
11471         mkdir -p ${testdir}
11472         mkdir -p ${testdir1}
11473         touch ${testdir1}/test1
11474         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
11475         check_stats $SINGLEMDS "crossdir_rename" 1
11476
11477         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
11478         check_stats $SINGLEMDS "samedir_rename" 1
11479
11480         rm -rf $DIR/${tdir}
11481 }
11482 run_test 133a "Verifying MDT stats ========================================"
11483
11484 test_133b() {
11485         local res
11486
11487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11488         remote_ost_nodsh && skip "remote OST with nodsh"
11489         remote_mds_nodsh && skip "remote MDS with nodsh"
11490
11491         local testdir=$DIR/${tdir}/stats_testdir
11492
11493         mkdir -p ${testdir} || error "mkdir failed"
11494         touch ${testdir}/${tfile} || error "touch failed"
11495         cancel_lru_locks mdc
11496
11497         # clear stats.
11498         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11499         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11500
11501         # extra mdt stats verification.
11502         chmod 444 ${testdir}/${tfile} || error "chmod failed"
11503         check_stats $SINGLEMDS "setattr" 1
11504         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11505         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
11506         then            # LU-1740
11507                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
11508                 check_stats $SINGLEMDS "getattr" 1
11509         fi
11510         rm -rf $DIR/${tdir}
11511
11512         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
11513         # so the check below is not reliable
11514         [ $MDSCOUNT -eq 1 ] || return 0
11515
11516         # Sleep to avoid a cached response.
11517         #define OBD_STATFS_CACHE_SECONDS 1
11518         sleep 2
11519         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11520         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11521         $LFS df || error "lfs failed"
11522         check_stats $SINGLEMDS "statfs" 1
11523
11524         # check aggregated statfs (LU-10018)
11525         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
11526                 return 0
11527         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
11528                 return 0
11529         sleep 2
11530         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11531         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11532         df $DIR
11533         check_stats $SINGLEMDS "statfs" 1
11534
11535         # We want to check that the client didn't send OST_STATFS to
11536         # ost1 but the MDT also uses OST_STATFS for precreate. So some
11537         # extra care is needed here.
11538         if remote_mds; then
11539                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
11540                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
11541
11542                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
11543                 [ "$res" ] && error "OST got STATFS"
11544         fi
11545
11546         return 0
11547 }
11548 run_test 133b "Verifying extra MDT stats =================================="
11549
11550 test_133c() {
11551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11552         remote_ost_nodsh && skip "remote OST with nodsh"
11553         remote_mds_nodsh && skip "remote MDS with nodsh"
11554
11555         local testdir=$DIR/$tdir/stats_testdir
11556
11557         test_mkdir -p $testdir
11558
11559         # verify obdfilter stats.
11560         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11561         sync
11562         cancel_lru_locks osc
11563         wait_delete_completed
11564
11565         # clear stats.
11566         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11567         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11568
11569         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11570                 error "dd failed"
11571         sync
11572         cancel_lru_locks osc
11573         check_stats ost1 "write" 1
11574
11575         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11576         check_stats ost1 "read" 1
11577
11578         > $testdir/$tfile || error "truncate failed"
11579         check_stats ost1 "punch" 1
11580
11581         rm -f $testdir/$tfile || error "file remove failed"
11582         wait_delete_completed
11583         check_stats ost1 "destroy" 1
11584
11585         rm -rf $DIR/$tdir
11586 }
11587 run_test 133c "Verifying OST stats ========================================"
11588
11589 order_2() {
11590         local value=$1
11591         local orig=$value
11592         local order=1
11593
11594         while [ $value -ge 2 ]; do
11595                 order=$((order*2))
11596                 value=$((value/2))
11597         done
11598
11599         if [ $orig -gt $order ]; then
11600                 order=$((order*2))
11601         fi
11602         echo $order
11603 }
11604
11605 size_in_KMGT() {
11606     local value=$1
11607     local size=('K' 'M' 'G' 'T');
11608     local i=0
11609     local size_string=$value
11610
11611     while [ $value -ge 1024 ]; do
11612         if [ $i -gt 3 ]; then
11613             #T is the biggest unit we get here, if that is bigger,
11614             #just return XXXT
11615             size_string=${value}T
11616             break
11617         fi
11618         value=$((value >> 10))
11619         if [ $value -lt 1024 ]; then
11620             size_string=${value}${size[$i]}
11621             break
11622         fi
11623         i=$((i + 1))
11624     done
11625
11626     echo $size_string
11627 }
11628
11629 get_rename_size() {
11630         local size=$1
11631         local context=${2:-.}
11632         local sample=$(do_facet $SINGLEMDS $LCTL \
11633                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11634                 grep -A1 $context |
11635                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11636         echo $sample
11637 }
11638
11639 test_133d() {
11640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11641         remote_ost_nodsh && skip "remote OST with nodsh"
11642         remote_mds_nodsh && skip "remote MDS with nodsh"
11643         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11644                 skip_env "MDS doesn't support rename stats"
11645
11646         local testdir1=$DIR/${tdir}/stats_testdir1
11647         local testdir2=$DIR/${tdir}/stats_testdir2
11648         mkdir -p $DIR/${tdir}
11649
11650         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11651
11652         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11653         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11654
11655         createmany -o $testdir1/test 512 || error "createmany failed"
11656
11657         # check samedir rename size
11658         mv ${testdir1}/test0 ${testdir1}/test_0
11659
11660         local testdir1_size=$(ls -l $DIR/${tdir} |
11661                 awk '/stats_testdir1/ {print $5}')
11662         local testdir2_size=$(ls -l $DIR/${tdir} |
11663                 awk '/stats_testdir2/ {print $5}')
11664
11665         testdir1_size=$(order_2 $testdir1_size)
11666         testdir2_size=$(order_2 $testdir2_size)
11667
11668         testdir1_size=$(size_in_KMGT $testdir1_size)
11669         testdir2_size=$(size_in_KMGT $testdir2_size)
11670
11671         echo "source rename dir size: ${testdir1_size}"
11672         echo "target rename dir size: ${testdir2_size}"
11673
11674         local cmd="do_facet $SINGLEMDS $LCTL "
11675         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11676
11677         eval $cmd || error "$cmd failed"
11678         local samedir=$($cmd | grep 'same_dir')
11679         local same_sample=$(get_rename_size $testdir1_size)
11680         [ -z "$samedir" ] && error "samedir_rename_size count error"
11681         [[ $same_sample -eq 1 ]] ||
11682                 error "samedir_rename_size error $same_sample"
11683         echo "Check same dir rename stats success"
11684
11685         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11686
11687         # check crossdir rename size
11688         mv ${testdir1}/test_0 ${testdir2}/test_0
11689
11690         testdir1_size=$(ls -l $DIR/${tdir} |
11691                 awk '/stats_testdir1/ {print $5}')
11692         testdir2_size=$(ls -l $DIR/${tdir} |
11693                 awk '/stats_testdir2/ {print $5}')
11694
11695         testdir1_size=$(order_2 $testdir1_size)
11696         testdir2_size=$(order_2 $testdir2_size)
11697
11698         testdir1_size=$(size_in_KMGT $testdir1_size)
11699         testdir2_size=$(size_in_KMGT $testdir2_size)
11700
11701         echo "source rename dir size: ${testdir1_size}"
11702         echo "target rename dir size: ${testdir2_size}"
11703
11704         eval $cmd || error "$cmd failed"
11705         local crossdir=$($cmd | grep 'crossdir')
11706         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11707         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11708         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11709         [[ $src_sample -eq 1 ]] ||
11710                 error "crossdir_rename_size error $src_sample"
11711         [[ $tgt_sample -eq 1 ]] ||
11712                 error "crossdir_rename_size error $tgt_sample"
11713         echo "Check cross dir rename stats success"
11714         rm -rf $DIR/${tdir}
11715 }
11716 run_test 133d "Verifying rename_stats ========================================"
11717
11718 test_133e() {
11719         remote_mds_nodsh && skip "remote MDS with nodsh"
11720         remote_ost_nodsh && skip "remote OST with nodsh"
11721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11722
11723         local testdir=$DIR/${tdir}/stats_testdir
11724         local ctr f0 f1 bs=32768 count=42 sum
11725
11726         mkdir -p ${testdir} || error "mkdir failed"
11727
11728         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11729
11730         for ctr in {write,read}_bytes; do
11731                 sync
11732                 cancel_lru_locks osc
11733
11734                 do_facet ost1 $LCTL set_param -n \
11735                         "obdfilter.*.exports.clear=clear"
11736
11737                 if [ $ctr = write_bytes ]; then
11738                         f0=/dev/zero
11739                         f1=${testdir}/${tfile}
11740                 else
11741                         f0=${testdir}/${tfile}
11742                         f1=/dev/null
11743                 fi
11744
11745                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11746                         error "dd failed"
11747                 sync
11748                 cancel_lru_locks osc
11749
11750                 sum=$(do_facet ost1 $LCTL get_param \
11751                         "obdfilter.*.exports.*.stats" |
11752                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11753                                 $1 == ctr { sum += $7 }
11754                                 END { printf("%0.0f", sum) }')
11755
11756                 if ((sum != bs * count)); then
11757                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11758                 fi
11759         done
11760
11761         rm -rf $DIR/${tdir}
11762 }
11763 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11764
11765 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11766
11767 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11768 # not honor the -ignore_readdir_race option correctly. So we call
11769 # error_ignore() rather than error() in these cases. See LU-11152.
11770 error_133() {
11771         if (find --version; do_facet mds1 find --version) |
11772                 grep -q '\b4\.5\.1[1-4]\b'; then
11773                 error_ignore LU-11152 "$@"
11774         else
11775                 error "$@"
11776         fi
11777 }
11778
11779 test_133f() {
11780         # First without trusting modes.
11781         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
11782         echo "proc_dirs='$proc_dirs'"
11783         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
11784         find $proc_dirs -exec cat '{}' \; &> /dev/null
11785
11786         # Second verifying readability.
11787         $LCTL get_param -R '*' &> /dev/null
11788
11789         # Verifing writability with badarea_io.
11790         find $proc_dirs \
11791                 -ignore_readdir_race \
11792                 -type f \
11793                 -not -name force_lbug \
11794                 -not -name changelog_mask \
11795                 -exec badarea_io '{}' \; ||
11796                         error_133 "find $proc_dirs failed"
11797 }
11798 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
11799
11800 test_133g() {
11801         remote_mds_nodsh && skip "remote MDS with nodsh"
11802         remote_ost_nodsh && skip "remote OST with nodsh"
11803
11804         # eventually, this can also be replaced with "lctl get_param -R",
11805         # but not until that option is always available on the server
11806         local facet
11807         for facet in mds1 ost1; do
11808                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
11809                         skip_noexit "Too old lustre on $facet"
11810                 local facet_proc_dirs=$(do_facet $facet \
11811                                         \\\ls -d $proc_regexp 2>/dev/null)
11812                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11813                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11814                 do_facet $facet find $facet_proc_dirs \
11815                         ! -name req_history \
11816                         -exec cat '{}' \\\; &> /dev/null
11817
11818                 do_facet $facet find $facet_proc_dirs \
11819                         ! -name req_history \
11820                         -type f \
11821                         -exec cat '{}' \\\; &> /dev/null ||
11822                                 error "proc file read failed"
11823
11824                 do_facet $facet find $facet_proc_dirs \
11825                         -ignore_readdir_race \
11826                         -type f \
11827                         -not -name force_lbug \
11828                         -not -name changelog_mask \
11829                         -exec badarea_io '{}' \\\; ||
11830                                 error_133 "$facet find $facet_proc_dirs failed"
11831         done
11832
11833         # remount the FS in case writes/reads /proc break the FS
11834         cleanup || error "failed to unmount"
11835         setup || error "failed to setup"
11836         true
11837 }
11838 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
11839
11840 test_133h() {
11841         remote_mds_nodsh && skip "remote MDS with nodsh"
11842         remote_ost_nodsh && skip "remote OST with nodsh"
11843         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
11844                 skip "Need MDS version at least 2.9.54"
11845
11846         local facet
11847
11848         for facet in client mds1 ost1; do
11849                 local facet_proc_dirs=$(do_facet $facet \
11850                                         \\\ls -d $proc_regexp 2> /dev/null)
11851                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11852                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11853                 # Get the list of files that are missing the terminating newline
11854                 local missing=($(do_facet $facet \
11855                         find ${facet_proc_dirs} -type f \|              \
11856                                 while read F\; do                       \
11857                                         awk -v FS='\v' -v RS='\v\v'     \
11858                                         "'END { if(NR>0 &&              \
11859                                         \\\$NF !~ /.*\\\n\$/)           \
11860                                                 print FILENAME}'"       \
11861                                         '\$F'\;                         \
11862                                 done 2>/dev/null))
11863                 [ ${#missing[*]} -eq 0 ] ||
11864                         error "files do not end with newline: ${missing[*]}"
11865         done
11866 }
11867 run_test 133h "Proc files should end with newlines"
11868
11869 test_134a() {
11870         remote_mds_nodsh && skip "remote MDS with nodsh"
11871         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11872                 skip "Need MDS version at least 2.7.54"
11873
11874         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11875         cancel_lru_locks mdc
11876
11877         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11878         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11879         [ $unused -eq 0 ] || error "$unused locks are not cleared"
11880
11881         local nr=1000
11882         createmany -o $DIR/$tdir/f $nr ||
11883                 error "failed to create $nr files in $DIR/$tdir"
11884         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11885
11886         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
11887         do_facet mds1 $LCTL set_param fail_loc=0x327
11888         do_facet mds1 $LCTL set_param fail_val=500
11889         touch $DIR/$tdir/m
11890
11891         echo "sleep 10 seconds ..."
11892         sleep 10
11893         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
11894
11895         do_facet mds1 $LCTL set_param fail_loc=0
11896         do_facet mds1 $LCTL set_param fail_val=0
11897         [ $lck_cnt -lt $unused ] ||
11898                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
11899
11900         rm $DIR/$tdir/m
11901         unlinkmany $DIR/$tdir/f $nr
11902 }
11903 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
11904
11905 test_134b() {
11906         remote_mds_nodsh && skip "remote MDS with nodsh"
11907         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11908                 skip "Need MDS version at least 2.7.54"
11909
11910         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11911         cancel_lru_locks mdc
11912
11913         local low_wm=$(do_facet mds1 $LCTL get_param -n \
11914                         ldlm.lock_reclaim_threshold_mb)
11915         # disable reclaim temporarily
11916         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
11917
11918         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
11919         do_facet mds1 $LCTL set_param fail_loc=0x328
11920         do_facet mds1 $LCTL set_param fail_val=500
11921
11922         $LCTL set_param debug=+trace
11923
11924         local nr=600
11925         createmany -o $DIR/$tdir/f $nr &
11926         local create_pid=$!
11927
11928         echo "Sleep $TIMEOUT seconds ..."
11929         sleep $TIMEOUT
11930         if ! ps -p $create_pid  > /dev/null 2>&1; then
11931                 do_facet mds1 $LCTL set_param fail_loc=0
11932                 do_facet mds1 $LCTL set_param fail_val=0
11933                 do_facet mds1 $LCTL set_param \
11934                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
11935                 error "createmany finished incorrectly!"
11936         fi
11937         do_facet mds1 $LCTL set_param fail_loc=0
11938         do_facet mds1 $LCTL set_param fail_val=0
11939         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
11940         wait $create_pid || return 1
11941
11942         unlinkmany $DIR/$tdir/f $nr
11943 }
11944 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
11945
11946 test_140() { #bug-17379
11947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11948
11949         test_mkdir $DIR/$tdir
11950         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
11951         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
11952
11953         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
11954         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
11955         local i=0
11956         while i=$((i + 1)); do
11957                 test_mkdir $i
11958                 cd $i || error "Changing to $i"
11959                 ln -s ../stat stat || error "Creating stat symlink"
11960                 # Read the symlink until ELOOP present,
11961                 # not LBUGing the system is considered success,
11962                 # we didn't overrun the stack.
11963                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
11964                 if [ $ret -ne 0 ]; then
11965                         if [ $ret -eq 40 ]; then
11966                                 break  # -ELOOP
11967                         else
11968                                 error "Open stat symlink"
11969                                         return
11970                         fi
11971                 fi
11972         done
11973         i=$((i - 1))
11974         echo "The symlink depth = $i"
11975         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
11976                 error "Invalid symlink depth"
11977
11978         # Test recursive symlink
11979         ln -s symlink_self symlink_self
11980         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
11981         echo "open symlink_self returns $ret"
11982         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
11983 }
11984 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
11985
11986 test_150() {
11987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11988
11989         local TF="$TMP/$tfile"
11990
11991         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11992         cp $TF $DIR/$tfile
11993         cancel_lru_locks $OSC
11994         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
11995         remount_client $MOUNT
11996         df -P $MOUNT
11997         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
11998
11999         $TRUNCATE $TF 6000
12000         $TRUNCATE $DIR/$tfile 6000
12001         cancel_lru_locks $OSC
12002         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
12003
12004         echo "12345" >>$TF
12005         echo "12345" >>$DIR/$tfile
12006         cancel_lru_locks $OSC
12007         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
12008
12009         echo "12345" >>$TF
12010         echo "12345" >>$DIR/$tfile
12011         cancel_lru_locks $OSC
12012         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
12013
12014         rm -f $TF
12015         true
12016 }
12017 run_test 150 "truncate/append tests"
12018
12019 #LU-2902 roc_hit was not able to read all values from lproc
12020 function roc_hit_init() {
12021         local list=$(comma_list $(osts_nodes))
12022         local dir=$DIR/$tdir-check
12023         local file=$dir/$tfile
12024         local BEFORE
12025         local AFTER
12026         local idx
12027
12028         test_mkdir $dir
12029         #use setstripe to do a write to every ost
12030         for i in $(seq 0 $((OSTCOUNT-1))); do
12031                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
12032                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
12033                 idx=$(printf %04x $i)
12034                 BEFORE=$(get_osd_param $list *OST*$idx stats |
12035                         awk '$1 == "cache_access" {sum += $7}
12036                                 END { printf("%0.0f", sum) }')
12037
12038                 cancel_lru_locks osc
12039                 cat $file >/dev/null
12040
12041                 AFTER=$(get_osd_param $list *OST*$idx stats |
12042                         awk '$1 == "cache_access" {sum += $7}
12043                                 END { printf("%0.0f", sum) }')
12044
12045                 echo BEFORE:$BEFORE AFTER:$AFTER
12046                 if ! let "AFTER - BEFORE == 4"; then
12047                         rm -rf $dir
12048                         error "roc_hit is not safe to use"
12049                 fi
12050                 rm $file
12051         done
12052
12053         rm -rf $dir
12054 }
12055
12056 function roc_hit() {
12057         local list=$(comma_list $(osts_nodes))
12058         echo $(get_osd_param $list '' stats |
12059                 awk '$1 == "cache_hit" {sum += $7}
12060                         END { printf("%0.0f", sum) }')
12061 }
12062
12063 function set_cache() {
12064         local on=1
12065
12066         if [ "$2" == "off" ]; then
12067                 on=0;
12068         fi
12069         local list=$(comma_list $(osts_nodes))
12070         set_osd_param $list '' $1_cache_enable $on
12071
12072         cancel_lru_locks osc
12073 }
12074
12075 test_151() {
12076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12077         remote_ost_nodsh && skip "remote OST with nodsh"
12078
12079         local CPAGES=3
12080         local list=$(comma_list $(osts_nodes))
12081
12082         # check whether obdfilter is cache capable at all
12083         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
12084                 skip "not cache-capable obdfilter"
12085         fi
12086
12087         # check cache is enabled on all obdfilters
12088         if get_osd_param $list '' read_cache_enable | grep 0; then
12089                 skip "oss cache is disabled"
12090         fi
12091
12092         set_osd_param $list '' writethrough_cache_enable 1
12093
12094         # check write cache is enabled on all obdfilters
12095         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
12096                 skip "oss write cache is NOT enabled"
12097         fi
12098
12099         roc_hit_init
12100
12101         #define OBD_FAIL_OBD_NO_LRU  0x609
12102         do_nodes $list $LCTL set_param fail_loc=0x609
12103
12104         # pages should be in the case right after write
12105         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
12106                 error "dd failed"
12107
12108         local BEFORE=$(roc_hit)
12109         cancel_lru_locks osc
12110         cat $DIR/$tfile >/dev/null
12111         local AFTER=$(roc_hit)
12112
12113         do_nodes $list $LCTL set_param fail_loc=0
12114
12115         if ! let "AFTER - BEFORE == CPAGES"; then
12116                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12117         fi
12118
12119         # the following read invalidates the cache
12120         cancel_lru_locks osc
12121         set_osd_param $list '' read_cache_enable 0
12122         cat $DIR/$tfile >/dev/null
12123
12124         # now data shouldn't be found in the cache
12125         BEFORE=$(roc_hit)
12126         cancel_lru_locks osc
12127         cat $DIR/$tfile >/dev/null
12128         AFTER=$(roc_hit)
12129         if let "AFTER - BEFORE != 0"; then
12130                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12131         fi
12132
12133         set_osd_param $list '' read_cache_enable 1
12134         rm -f $DIR/$tfile
12135 }
12136 run_test 151 "test cache on oss and controls ==============================="
12137
12138 test_152() {
12139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12140
12141         local TF="$TMP/$tfile"
12142
12143         # simulate ENOMEM during write
12144 #define OBD_FAIL_OST_NOMEM      0x226
12145         lctl set_param fail_loc=0x80000226
12146         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12147         cp $TF $DIR/$tfile
12148         sync || error "sync failed"
12149         lctl set_param fail_loc=0
12150
12151         # discard client's cache
12152         cancel_lru_locks osc
12153
12154         # simulate ENOMEM during read
12155         lctl set_param fail_loc=0x80000226
12156         cmp $TF $DIR/$tfile || error "cmp failed"
12157         lctl set_param fail_loc=0
12158
12159         rm -f $TF
12160 }
12161 run_test 152 "test read/write with enomem ============================"
12162
12163 test_153() {
12164         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
12165 }
12166 run_test 153 "test if fdatasync does not crash ======================="
12167
12168 dot_lustre_fid_permission_check() {
12169         local fid=$1
12170         local ffid=$MOUNT/.lustre/fid/$fid
12171         local test_dir=$2
12172
12173         echo "stat fid $fid"
12174         stat $ffid > /dev/null || error "stat $ffid failed."
12175         echo "touch fid $fid"
12176         touch $ffid || error "touch $ffid failed."
12177         echo "write to fid $fid"
12178         cat /etc/hosts > $ffid || error "write $ffid failed."
12179         echo "read fid $fid"
12180         diff /etc/hosts $ffid || error "read $ffid failed."
12181         echo "append write to fid $fid"
12182         cat /etc/hosts >> $ffid || error "append write $ffid failed."
12183         echo "rename fid $fid"
12184         mv $ffid $test_dir/$tfile.1 &&
12185                 error "rename $ffid to $tfile.1 should fail."
12186         touch $test_dir/$tfile.1
12187         mv $test_dir/$tfile.1 $ffid &&
12188                 error "rename $tfile.1 to $ffid should fail."
12189         rm -f $test_dir/$tfile.1
12190         echo "truncate fid $fid"
12191         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
12192         echo "link fid $fid"
12193         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
12194         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
12195                 echo "setfacl fid $fid"
12196                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
12197                 echo "getfacl fid $fid"
12198                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
12199         fi
12200         echo "unlink fid $fid"
12201         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
12202         echo "mknod fid $fid"
12203         mknod $ffid c 1 3 && error "mknod $ffid should fail."
12204
12205         fid=[0xf00000400:0x1:0x0]
12206         ffid=$MOUNT/.lustre/fid/$fid
12207
12208         echo "stat non-exist fid $fid"
12209         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
12210         echo "write to non-exist fid $fid"
12211         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
12212         echo "link new fid $fid"
12213         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
12214
12215         mkdir -p $test_dir/$tdir
12216         touch $test_dir/$tdir/$tfile
12217         fid=$($LFS path2fid $test_dir/$tdir)
12218         rc=$?
12219         [ $rc -ne 0 ] &&
12220                 error "error: could not get fid for $test_dir/$dir/$tfile."
12221
12222         ffid=$MOUNT/.lustre/fid/$fid
12223
12224         echo "ls $fid"
12225         ls $ffid > /dev/null || error "ls $ffid failed."
12226         echo "touch $fid/$tfile.1"
12227         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
12228
12229         echo "touch $MOUNT/.lustre/fid/$tfile"
12230         touch $MOUNT/.lustre/fid/$tfile && \
12231                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
12232
12233         echo "setxattr to $MOUNT/.lustre/fid"
12234         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
12235
12236         echo "listxattr for $MOUNT/.lustre/fid"
12237         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
12238
12239         echo "delxattr from $MOUNT/.lustre/fid"
12240         setfattr -x trusted.name1 $MOUNT/.lustre/fid
12241
12242         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
12243         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
12244                 error "touch invalid fid should fail."
12245
12246         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
12247         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
12248                 error "touch non-normal fid should fail."
12249
12250         echo "rename $tdir to $MOUNT/.lustre/fid"
12251         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
12252                 error "rename to $MOUNT/.lustre/fid should fail."
12253
12254         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
12255         then            # LU-3547
12256                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
12257                 local new_obf_mode=777
12258
12259                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
12260                 chmod $new_obf_mode $DIR/.lustre/fid ||
12261                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
12262
12263                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
12264                 [ $obf_mode -eq $new_obf_mode ] ||
12265                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
12266
12267                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
12268                 chmod $old_obf_mode $DIR/.lustre/fid ||
12269                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
12270         fi
12271
12272         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
12273         fid=$($LFS path2fid $test_dir/$tfile-2)
12274
12275         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
12276         then # LU-5424
12277                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
12278                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
12279                         error "create lov data thru .lustre failed"
12280         fi
12281         echo "cp /etc/passwd $test_dir/$tfile-2"
12282         cp /etc/passwd $test_dir/$tfile-2 ||
12283                 error "copy to $test_dir/$tfile-2 failed."
12284         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
12285         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
12286                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
12287
12288         rm -rf $test_dir/tfile.lnk
12289         rm -rf $test_dir/$tfile-2
12290 }
12291
12292 test_154A() {
12293         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12294                 skip "Need MDS version at least 2.4.1"
12295
12296         local tf=$DIR/$tfile
12297         touch $tf
12298
12299         local fid=$($LFS path2fid $tf)
12300         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
12301
12302         # check that we get the same pathname back
12303         local found=$($LFS fid2path $MOUNT "$fid")
12304         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
12305         [ "$found" == "$tf" ] ||
12306                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
12307 }
12308 run_test 154A "lfs path2fid and fid2path basic checks"
12309
12310 test_154B() {
12311         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12312                 skip "Need MDS version at least 2.4.1"
12313
12314         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
12315         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
12316         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
12317         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
12318
12319         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
12320         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
12321
12322         # check that we get the same pathname
12323         echo "PFID: $PFID, name: $name"
12324         local FOUND=$($LFS fid2path $MOUNT "$PFID")
12325         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
12326         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
12327                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
12328
12329         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
12330 }
12331 run_test 154B "verify the ll_decode_linkea tool"
12332
12333 test_154a() {
12334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12335         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12336         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12337                 skip "Need MDS version at least 2.2.51"
12338         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12339
12340         cp /etc/hosts $DIR/$tfile
12341
12342         fid=$($LFS path2fid $DIR/$tfile)
12343         rc=$?
12344         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
12345
12346         dot_lustre_fid_permission_check "$fid" $DIR ||
12347                 error "dot lustre permission check $fid failed"
12348
12349         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
12350
12351         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
12352
12353         touch $MOUNT/.lustre/file &&
12354                 error "creation is not allowed under .lustre"
12355
12356         mkdir $MOUNT/.lustre/dir &&
12357                 error "mkdir is not allowed under .lustre"
12358
12359         rm -rf $DIR/$tfile
12360 }
12361 run_test 154a "Open-by-FID"
12362
12363 test_154b() {
12364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12365         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12366         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12367         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12368                 skip "Need MDS version at least 2.2.51"
12369
12370         local remote_dir=$DIR/$tdir/remote_dir
12371         local MDTIDX=1
12372         local rc=0
12373
12374         mkdir -p $DIR/$tdir
12375         $LFS mkdir -i $MDTIDX $remote_dir ||
12376                 error "create remote directory failed"
12377
12378         cp /etc/hosts $remote_dir/$tfile
12379
12380         fid=$($LFS path2fid $remote_dir/$tfile)
12381         rc=$?
12382         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
12383
12384         dot_lustre_fid_permission_check "$fid" $remote_dir ||
12385                 error "dot lustre permission check $fid failed"
12386         rm -rf $DIR/$tdir
12387 }
12388 run_test 154b "Open-by-FID for remote directory"
12389
12390 test_154c() {
12391         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12392                 skip "Need MDS version at least 2.4.1"
12393
12394         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
12395         local FID1=$($LFS path2fid $DIR/$tfile.1)
12396         local FID2=$($LFS path2fid $DIR/$tfile.2)
12397         local FID3=$($LFS path2fid $DIR/$tfile.3)
12398
12399         local N=1
12400         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
12401                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
12402                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
12403                 local want=FID$N
12404                 [ "$FID" = "${!want}" ] ||
12405                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
12406                 N=$((N + 1))
12407         done
12408
12409         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
12410         do
12411                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
12412                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
12413                 N=$((N + 1))
12414         done
12415 }
12416 run_test 154c "lfs path2fid and fid2path multiple arguments"
12417
12418 test_154d() {
12419         remote_mds_nodsh && skip "remote MDS with nodsh"
12420         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
12421                 skip "Need MDS version at least 2.5.53"
12422
12423         if remote_mds; then
12424                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
12425         else
12426                 nid="0@lo"
12427         fi
12428         local proc_ofile="mdt.*.exports.'$nid'.open_files"
12429         local fd
12430         local cmd
12431
12432         rm -f $DIR/$tfile
12433         touch $DIR/$tfile
12434
12435         local fid=$($LFS path2fid $DIR/$tfile)
12436         # Open the file
12437         fd=$(free_fd)
12438         cmd="exec $fd<$DIR/$tfile"
12439         eval $cmd
12440         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
12441         echo "$fid_list" | grep "$fid"
12442         rc=$?
12443
12444         cmd="exec $fd>/dev/null"
12445         eval $cmd
12446         if [ $rc -ne 0 ]; then
12447                 error "FID $fid not found in open files list $fid_list"
12448         fi
12449 }
12450 run_test 154d "Verify open file fid"
12451
12452 test_154e()
12453 {
12454         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
12455                 skip "Need MDS version at least 2.6.50"
12456
12457         if ls -a $MOUNT | grep -q '^\.lustre$'; then
12458                 error ".lustre returned by readdir"
12459         fi
12460 }
12461 run_test 154e ".lustre is not returned by readdir"
12462
12463 test_154f() {
12464         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12465
12466         # create parent directory on a single MDT to avoid cross-MDT hardlinks
12467         test_mkdir -p -c1 $DIR/$tdir/d
12468         # test dirs inherit from its stripe
12469         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
12470         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
12471         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
12472         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
12473         touch $DIR/f
12474
12475         # get fid of parents
12476         local FID0=$($LFS path2fid $DIR/$tdir/d)
12477         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
12478         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
12479         local FID3=$($LFS path2fid $DIR)
12480
12481         # check that path2fid --parents returns expected <parent_fid>/name
12482         # 1) test for a directory (single parent)
12483         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
12484         [ "$parent" == "$FID0/foo1" ] ||
12485                 error "expected parent: $FID0/foo1, got: $parent"
12486
12487         # 2) test for a file with nlink > 1 (multiple parents)
12488         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
12489         echo "$parent" | grep -F "$FID1/$tfile" ||
12490                 error "$FID1/$tfile not returned in parent list"
12491         echo "$parent" | grep -F "$FID2/link" ||
12492                 error "$FID2/link not returned in parent list"
12493
12494         # 3) get parent by fid
12495         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
12496         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12497         echo "$parent" | grep -F "$FID1/$tfile" ||
12498                 error "$FID1/$tfile not returned in parent list (by fid)"
12499         echo "$parent" | grep -F "$FID2/link" ||
12500                 error "$FID2/link not returned in parent list (by fid)"
12501
12502         # 4) test for entry in root directory
12503         parent=$($LFS path2fid --parents $DIR/f)
12504         echo "$parent" | grep -F "$FID3/f" ||
12505                 error "$FID3/f not returned in parent list"
12506
12507         # 5) test it on root directory
12508         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
12509                 error "$MOUNT should not have parents"
12510
12511         # enable xattr caching and check that linkea is correctly updated
12512         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12513         save_lustre_params client "llite.*.xattr_cache" > $save
12514         lctl set_param llite.*.xattr_cache 1
12515
12516         # 6.1) linkea update on rename
12517         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
12518
12519         # get parents by fid
12520         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12521         # foo1 should no longer be returned in parent list
12522         echo "$parent" | grep -F "$FID1" &&
12523                 error "$FID1 should no longer be in parent list"
12524         # the new path should appear
12525         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
12526                 error "$FID2/$tfile.moved is not in parent list"
12527
12528         # 6.2) linkea update on unlink
12529         rm -f $DIR/$tdir/d/foo2/link
12530         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12531         # foo2/link should no longer be returned in parent list
12532         echo "$parent" | grep -F "$FID2/link" &&
12533                 error "$FID2/link should no longer be in parent list"
12534         true
12535
12536         rm -f $DIR/f
12537         restore_lustre_params < $save
12538         rm -f $save
12539 }
12540 run_test 154f "get parent fids by reading link ea"
12541
12542 test_154g()
12543 {
12544         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12545         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
12546            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
12547                 skip "Need MDS version at least 2.6.92"
12548
12549         mkdir -p $DIR/$tdir
12550         llapi_fid_test -d $DIR/$tdir
12551 }
12552 run_test 154g "various llapi FID tests"
12553
12554 test_155_small_load() {
12555     local temp=$TMP/$tfile
12556     local file=$DIR/$tfile
12557
12558     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12559         error "dd of=$temp bs=6096 count=1 failed"
12560     cp $temp $file
12561     cancel_lru_locks $OSC
12562     cmp $temp $file || error "$temp $file differ"
12563
12564     $TRUNCATE $temp 6000
12565     $TRUNCATE $file 6000
12566     cmp $temp $file || error "$temp $file differ (truncate1)"
12567
12568     echo "12345" >>$temp
12569     echo "12345" >>$file
12570     cmp $temp $file || error "$temp $file differ (append1)"
12571
12572     echo "12345" >>$temp
12573     echo "12345" >>$file
12574     cmp $temp $file || error "$temp $file differ (append2)"
12575
12576     rm -f $temp $file
12577     true
12578 }
12579
12580 test_155_big_load() {
12581         remote_ost_nodsh && skip "remote OST with nodsh"
12582
12583         local temp=$TMP/$tfile
12584         local file=$DIR/$tfile
12585
12586         free_min_max
12587         local cache_size=$(do_facet ost$((MAXI+1)) \
12588                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12589         local large_file_size=$((cache_size * 2))
12590
12591         echo "OSS cache size: $cache_size KB"
12592         echo "Large file size: $large_file_size KB"
12593
12594         [ $MAXV -le $large_file_size ] &&
12595                 skip_env "max available OST size needs > $large_file_size KB"
12596
12597         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12598
12599         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12600                 error "dd of=$temp bs=$large_file_size count=1k failed"
12601         cp $temp $file
12602         ls -lh $temp $file
12603         cancel_lru_locks osc
12604         cmp $temp $file || error "$temp $file differ"
12605
12606         rm -f $temp $file
12607         true
12608 }
12609
12610 save_writethrough() {
12611         local facets=$(get_facets OST)
12612
12613         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12614 }
12615
12616 test_155a() {
12617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12618
12619         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12620
12621         save_writethrough $p
12622
12623         set_cache read on
12624         set_cache writethrough on
12625         test_155_small_load
12626         restore_lustre_params < $p
12627         rm -f $p
12628 }
12629 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12630
12631 test_155b() {
12632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12633
12634         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12635
12636         save_writethrough $p
12637
12638         set_cache read on
12639         set_cache writethrough off
12640         test_155_small_load
12641         restore_lustre_params < $p
12642         rm -f $p
12643 }
12644 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12645
12646 test_155c() {
12647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12648
12649         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12650
12651         save_writethrough $p
12652
12653         set_cache read off
12654         set_cache writethrough on
12655         test_155_small_load
12656         restore_lustre_params < $p
12657         rm -f $p
12658 }
12659 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12660
12661 test_155d() {
12662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12663
12664         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12665
12666         save_writethrough $p
12667
12668         set_cache read off
12669         set_cache writethrough off
12670         test_155_small_load
12671         restore_lustre_params < $p
12672         rm -f $p
12673 }
12674 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12675
12676 test_155e() {
12677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12678
12679         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12680
12681         save_writethrough $p
12682
12683         set_cache read on
12684         set_cache writethrough on
12685         test_155_big_load
12686         restore_lustre_params < $p
12687         rm -f $p
12688 }
12689 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12690
12691 test_155f() {
12692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12693
12694         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12695
12696         save_writethrough $p
12697
12698         set_cache read on
12699         set_cache writethrough off
12700         test_155_big_load
12701         restore_lustre_params < $p
12702         rm -f $p
12703 }
12704 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12705
12706 test_155g() {
12707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12708
12709         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12710
12711         save_writethrough $p
12712
12713         set_cache read off
12714         set_cache writethrough on
12715         test_155_big_load
12716         restore_lustre_params < $p
12717         rm -f $p
12718 }
12719 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12720
12721 test_155h() {
12722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12723
12724         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12725
12726         save_writethrough $p
12727
12728         set_cache read off
12729         set_cache writethrough off
12730         test_155_big_load
12731         restore_lustre_params < $p
12732         rm -f $p
12733 }
12734 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12735
12736 test_156() {
12737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12738         remote_ost_nodsh && skip "remote OST with nodsh"
12739         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12740                 skip "stats not implemented on old servers"
12741         [ "$ost1_FSTYPE" = "zfs" ] &&
12742                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12743
12744         local CPAGES=3
12745         local BEFORE
12746         local AFTER
12747         local file="$DIR/$tfile"
12748         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12749
12750         save_writethrough $p
12751         roc_hit_init
12752
12753         log "Turn on read and write cache"
12754         set_cache read on
12755         set_cache writethrough on
12756
12757         log "Write data and read it back."
12758         log "Read should be satisfied from the cache."
12759         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12760         BEFORE=$(roc_hit)
12761         cancel_lru_locks osc
12762         cat $file >/dev/null
12763         AFTER=$(roc_hit)
12764         if ! let "AFTER - BEFORE == CPAGES"; then
12765                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12766         else
12767                 log "cache hits:: before: $BEFORE, after: $AFTER"
12768         fi
12769
12770         log "Read again; it should be satisfied from the cache."
12771         BEFORE=$AFTER
12772         cancel_lru_locks osc
12773         cat $file >/dev/null
12774         AFTER=$(roc_hit)
12775         if ! let "AFTER - BEFORE == CPAGES"; then
12776                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12777         else
12778                 log "cache hits:: before: $BEFORE, after: $AFTER"
12779         fi
12780
12781         log "Turn off the read cache and turn on the write cache"
12782         set_cache read off
12783         set_cache writethrough on
12784
12785         log "Read again; it should be satisfied from the cache."
12786         BEFORE=$(roc_hit)
12787         cancel_lru_locks osc
12788         cat $file >/dev/null
12789         AFTER=$(roc_hit)
12790         if ! let "AFTER - BEFORE == CPAGES"; then
12791                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12792         else
12793                 log "cache hits:: before: $BEFORE, after: $AFTER"
12794         fi
12795
12796         log "Read again; it should not be satisfied from the cache."
12797         BEFORE=$AFTER
12798         cancel_lru_locks osc
12799         cat $file >/dev/null
12800         AFTER=$(roc_hit)
12801         if ! let "AFTER - BEFORE == 0"; then
12802                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12803         else
12804                 log "cache hits:: before: $BEFORE, after: $AFTER"
12805         fi
12806
12807         log "Write data and read it back."
12808         log "Read should be satisfied from the cache."
12809         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12810         BEFORE=$(roc_hit)
12811         cancel_lru_locks osc
12812         cat $file >/dev/null
12813         AFTER=$(roc_hit)
12814         if ! let "AFTER - BEFORE == CPAGES"; then
12815                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12816         else
12817                 log "cache hits:: before: $BEFORE, after: $AFTER"
12818         fi
12819
12820         log "Read again; it should not be satisfied from the cache."
12821         BEFORE=$AFTER
12822         cancel_lru_locks osc
12823         cat $file >/dev/null
12824         AFTER=$(roc_hit)
12825         if ! let "AFTER - BEFORE == 0"; then
12826                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12827         else
12828                 log "cache hits:: before: $BEFORE, after: $AFTER"
12829         fi
12830
12831         log "Turn off read and write cache"
12832         set_cache read off
12833         set_cache writethrough off
12834
12835         log "Write data and read it back"
12836         log "It should not be satisfied from the cache."
12837         rm -f $file
12838         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12839         cancel_lru_locks osc
12840         BEFORE=$(roc_hit)
12841         cat $file >/dev/null
12842         AFTER=$(roc_hit)
12843         if ! let "AFTER - BEFORE == 0"; then
12844                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12845         else
12846                 log "cache hits:: before: $BEFORE, after: $AFTER"
12847         fi
12848
12849         log "Turn on the read cache and turn off the write cache"
12850         set_cache read on
12851         set_cache writethrough off
12852
12853         log "Write data and read it back"
12854         log "It should not be satisfied from the cache."
12855         rm -f $file
12856         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12857         BEFORE=$(roc_hit)
12858         cancel_lru_locks osc
12859         cat $file >/dev/null
12860         AFTER=$(roc_hit)
12861         if ! let "AFTER - BEFORE == 0"; then
12862                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12863         else
12864                 log "cache hits:: before: $BEFORE, after: $AFTER"
12865         fi
12866
12867         log "Read again; it should be satisfied from the cache."
12868         BEFORE=$(roc_hit)
12869         cancel_lru_locks osc
12870         cat $file >/dev/null
12871         AFTER=$(roc_hit)
12872         if ! let "AFTER - BEFORE == CPAGES"; then
12873                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12874         else
12875                 log "cache hits:: before: $BEFORE, after: $AFTER"
12876         fi
12877
12878         restore_lustre_params < $p
12879         rm -f $p $file
12880 }
12881 run_test 156 "Verification of tunables"
12882
12883 test_160a() {
12884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12885         remote_mds_nodsh && skip "remote MDS with nodsh"
12886         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12887                 skip "Need MDS version at least 2.2.0"
12888
12889         changelog_register || error "changelog_register failed"
12890         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12891         changelog_users $SINGLEMDS | grep -q $cl_user ||
12892                 error "User $cl_user not found in changelog_users"
12893
12894         # change something
12895         test_mkdir -p $DIR/$tdir/pics/2008/zachy
12896         changelog_clear 0 || error "changelog_clear failed"
12897         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
12898         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
12899         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
12900         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
12901         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
12902         rm $DIR/$tdir/pics/desktop.jpg
12903
12904         changelog_dump | tail -10
12905
12906         echo "verifying changelog mask"
12907         changelog_chmask "-MKDIR"
12908         changelog_chmask "-CLOSE"
12909
12910         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
12911         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
12912
12913         changelog_chmask "+MKDIR"
12914         changelog_chmask "+CLOSE"
12915
12916         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
12917         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
12918
12919         changelog_dump | tail -10
12920         MKDIRS=$(changelog_dump | grep -c "MKDIR")
12921         CLOSES=$(changelog_dump | grep -c "CLOSE")
12922         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
12923         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
12924
12925         # verify contents
12926         echo "verifying target fid"
12927         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
12928         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
12929         [ "$fidc" == "$fidf" ] ||
12930                 error "changelog '$tfile' fid $fidc != file fid $fidf"
12931         echo "verifying parent fid"
12932         # The FID returned from the Changelog may be the directory shard on
12933         # a different MDT, and not the FID returned by path2fid on the parent.
12934         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
12935         # since this is what will matter when recreating this file in the tree.
12936         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
12937         local pathp=$($LFS fid2path $MOUNT "$fidp")
12938         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
12939                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
12940
12941         echo "getting records for $cl_user"
12942         changelog_users $SINGLEMDS
12943         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
12944         local nclr=3
12945         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
12946                 error "changelog_clear failed"
12947         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
12948         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
12949         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
12950                 error "user index expect $user_rec1 + $nclr != $user_rec2"
12951
12952         local min0_rec=$(changelog_users $SINGLEMDS |
12953                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
12954         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
12955                           awk '{ print $1; exit; }')
12956
12957         changelog_dump | tail -n 5
12958         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
12959         [ $first_rec == $((min0_rec + 1)) ] ||
12960                 error "first index should be $min0_rec + 1 not $first_rec"
12961
12962         # LU-3446 changelog index reset on MDT restart
12963         local cur_rec1=$(changelog_users $SINGLEMDS |
12964                          awk '/^current.index:/ { print $NF }')
12965         changelog_clear 0 ||
12966                 error "clear all changelog records for $cl_user failed"
12967         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
12968         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
12969                 error "Fail to start $SINGLEMDS"
12970         local cur_rec2=$(changelog_users $SINGLEMDS |
12971                          awk '/^current.index:/ { print $NF }')
12972         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
12973         [ $cur_rec1 == $cur_rec2 ] ||
12974                 error "current index should be $cur_rec1 not $cur_rec2"
12975
12976         echo "verifying users from this test are deregistered"
12977         changelog_deregister || error "changelog_deregister failed"
12978         changelog_users $SINGLEMDS | grep -q $cl_user &&
12979                 error "User '$cl_user' still in changelog_users"
12980
12981         # lctl get_param -n mdd.*.changelog_users
12982         # current index: 144
12983         # ID    index (idle seconds)
12984         # cl3   144 (2)
12985         if ! changelog_users $SINGLEMDS | grep "^cl"; then
12986                 # this is the normal case where all users were deregistered
12987                 # make sure no new records are added when no users are present
12988                 local last_rec1=$(changelog_users $SINGLEMDS |
12989                                   awk '/^current.index:/ { print $NF }')
12990                 touch $DIR/$tdir/chloe
12991                 local last_rec2=$(changelog_users $SINGLEMDS |
12992                                   awk '/^current.index:/ { print $NF }')
12993                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
12994                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
12995         else
12996                 # any changelog users must be leftovers from a previous test
12997                 changelog_users $SINGLEMDS
12998                 echo "other changelog users; can't verify off"
12999         fi
13000 }
13001 run_test 160a "changelog sanity"
13002
13003 test_160b() { # LU-3587
13004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13005         remote_mds_nodsh && skip "remote MDS with nodsh"
13006         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13007                 skip "Need MDS version at least 2.2.0"
13008
13009         changelog_register || error "changelog_register failed"
13010         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13011         changelog_users $SINGLEMDS | grep -q $cl_user ||
13012                 error "User '$cl_user' not found in changelog_users"
13013
13014         local longname1=$(str_repeat a 255)
13015         local longname2=$(str_repeat b 255)
13016
13017         cd $DIR
13018         echo "creating very long named file"
13019         touch $longname1 || error "create of '$longname1' failed"
13020         echo "renaming very long named file"
13021         mv $longname1 $longname2
13022
13023         changelog_dump | grep RENME | tail -n 5
13024         rm -f $longname2
13025 }
13026 run_test 160b "Verify that very long rename doesn't crash in changelog"
13027
13028 test_160c() {
13029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13030         remote_mds_nodsh && skip "remote MDS with nodsh"
13031
13032         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
13033                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
13034                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
13035                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
13036
13037         local rc=0
13038
13039         # Registration step
13040         changelog_register || error "changelog_register failed"
13041
13042         rm -rf $DIR/$tdir
13043         mkdir -p $DIR/$tdir
13044         $MCREATE $DIR/$tdir/foo_160c
13045         changelog_chmask "-TRUNC"
13046         $TRUNCATE $DIR/$tdir/foo_160c 200
13047         changelog_chmask "+TRUNC"
13048         $TRUNCATE $DIR/$tdir/foo_160c 199
13049         changelog_dump | tail -n 5
13050         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
13051         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
13052 }
13053 run_test 160c "verify that changelog log catch the truncate event"
13054
13055 test_160d() {
13056         remote_mds_nodsh && skip "remote MDS with nodsh"
13057         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13059         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
13060                 skip "Need MDS version at least 2.7.60"
13061
13062         # Registration step
13063         changelog_register || error "changelog_register failed"
13064
13065         mkdir -p $DIR/$tdir/migrate_dir
13066         changelog_clear 0 || error "changelog_clear failed"
13067
13068         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
13069         changelog_dump | tail -n 5
13070         local migrates=$(changelog_dump | grep -c "MIGRT")
13071         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
13072 }
13073 run_test 160d "verify that changelog log catch the migrate event"
13074
13075 test_160e() {
13076         remote_mds_nodsh && skip "remote MDS with nodsh"
13077
13078         # Create a user
13079         changelog_register || error "changelog_register failed"
13080
13081         # Delete a future user (expect fail)
13082         local MDT0=$(facet_svc $SINGLEMDS)
13083         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
13084         local rc=$?
13085
13086         if [ $rc -eq 0 ]; then
13087                 error "Deleted non-existant user cl77"
13088         elif [ $rc -ne 2 ]; then
13089                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
13090         fi
13091
13092         # Clear to a bad index (1 billion should be safe)
13093         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
13094         rc=$?
13095
13096         if [ $rc -eq 0 ]; then
13097                 error "Successfully cleared to invalid CL index"
13098         elif [ $rc -ne 22 ]; then
13099                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
13100         fi
13101 }
13102 run_test 160e "changelog negative testing (should return errors)"
13103
13104 test_160f() {
13105         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13106         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13107                 skip "Need MDS version at least 2.10.56"
13108
13109         local mdts=$(comma_list $(mdts_nodes))
13110
13111         # Create a user
13112         changelog_register || error "first changelog_register failed"
13113         changelog_register || error "second changelog_register failed"
13114         local cl_users
13115         declare -A cl_user1
13116         declare -A cl_user2
13117         local user_rec1
13118         local user_rec2
13119         local i
13120
13121         # generate some changelog records to accumulate on each MDT
13122         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13123         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13124                 error "create $DIR/$tdir/$tfile failed"
13125
13126         # check changelogs have been generated
13127         local nbcl=$(changelog_dump | wc -l)
13128         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13129
13130         for param in "changelog_max_idle_time=10" \
13131                      "changelog_gc=1" \
13132                      "changelog_min_gc_interval=2" \
13133                      "changelog_min_free_cat_entries=3"; do
13134                 local MDT0=$(facet_svc $SINGLEMDS)
13135                 local var="${param%=*}"
13136                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13137
13138                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13139                 do_nodes $mdts $LCTL set_param mdd.*.$param
13140         done
13141
13142         # force cl_user2 to be idle (1st part)
13143         sleep 9
13144
13145         # simulate changelog catalog almost full
13146         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13147         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13148
13149         for i in $(seq $MDSCOUNT); do
13150                 cl_users=(${CL_USERS[mds$i]})
13151                 cl_user1[mds$i]="${cl_users[0]}"
13152                 cl_user2[mds$i]="${cl_users[1]}"
13153
13154                 [ -n "${cl_user1[mds$i]}" ] ||
13155                         error "mds$i: no user registered"
13156                 [ -n "${cl_user2[mds$i]}" ] ||
13157                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13158
13159                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13160                 [ -n "$user_rec1" ] ||
13161                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13162                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13163                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13164                 [ -n "$user_rec2" ] ||
13165                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13166                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13167                      "$user_rec1 + 2 == $user_rec2"
13168                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13169                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13170                               "$user_rec1 + 2, but is $user_rec2"
13171                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13172                 [ -n "$user_rec2" ] ||
13173                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13174                 [ $user_rec1 == $user_rec2 ] ||
13175                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13176                               "$user_rec1, but is $user_rec2"
13177         done
13178
13179         # force cl_user2 to be idle (2nd part) and to reach
13180         # changelog_max_idle_time
13181         sleep 2
13182
13183         # generate one more changelog to trigger fail_loc
13184         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13185                 error "create $DIR/$tdir/${tfile}bis failed"
13186
13187         # ensure gc thread is done
13188         for i in $(mdts_nodes); do
13189                 wait_update $i \
13190                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13191                         error "$i: GC-thread not done"
13192         done
13193
13194         local first_rec
13195         for i in $(seq $MDSCOUNT); do
13196                 # check cl_user1 still registered
13197                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13198                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13199                 # check cl_user2 unregistered
13200                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13201                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13202
13203                 # check changelogs are present and starting at $user_rec1 + 1
13204                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13205                 [ -n "$user_rec1" ] ||
13206                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13207                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13208                             awk '{ print $1; exit; }')
13209
13210                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13211                 [ $((user_rec1 + 1)) == $first_rec ] ||
13212                         error "mds$i: first index should be $user_rec1 + 1, " \
13213                               "but is $first_rec"
13214         done
13215 }
13216 run_test 160f "changelog garbage collect (timestamped users)"
13217
13218 test_160g() {
13219         remote_mds_nodsh && skip "remote MDS with nodsh"
13220         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13221                 skip "Need MDS version at least 2.10.56"
13222
13223         local mdts=$(comma_list $(mdts_nodes))
13224
13225         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
13226         do_nodes $mdts $LCTL set_param fail_loc=0x1314
13227
13228         # Create a user
13229         changelog_register || error "first changelog_register failed"
13230         changelog_register || error "second changelog_register failed"
13231         local cl_users
13232         declare -A cl_user1
13233         declare -A cl_user2
13234         local user_rec1
13235         local user_rec2
13236         local i
13237
13238         # generate some changelog records to accumulate on each MDT
13239         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13240         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13241                 error "create $DIR/$tdir/$tfile failed"
13242
13243         # check changelogs have been generated
13244         local nbcl=$(changelog_dump | wc -l)
13245         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13246
13247         # reduce the max_idle_indexes value to make sure we exceed it
13248         max_ndx=$((nbcl / 2 - 1))
13249
13250         for param in "changelog_max_idle_indexes=$max_ndx" \
13251                      "changelog_gc=1" \
13252                      "changelog_min_gc_interval=2" \
13253                      "changelog_min_free_cat_entries=3"; do
13254                 local MDT0=$(facet_svc $SINGLEMDS)
13255                 local var="${param%=*}"
13256                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13257
13258                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13259                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
13260                         error "unable to set mdd.*.$param"
13261         done
13262
13263         # simulate changelog catalog almost full
13264         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13265         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13266
13267         for i in $(seq $MDSCOUNT); do
13268                 cl_users=(${CL_USERS[mds$i]})
13269                 cl_user1[mds$i]="${cl_users[0]}"
13270                 cl_user2[mds$i]="${cl_users[1]}"
13271
13272                 [ -n "${cl_user1[mds$i]}" ] ||
13273                         error "mds$i: no user registered"
13274                 [ -n "${cl_user2[mds$i]}" ] ||
13275                         error "mds$i: only ${cl_user1[mds$i]} is registered"
13276
13277                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13278                 [ -n "$user_rec1" ] ||
13279                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13280                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13281                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13282                 [ -n "$user_rec2" ] ||
13283                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13284                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13285                      "$user_rec1 + 2 == $user_rec2"
13286                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13287                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13288                               "$user_rec1 + 2, but is $user_rec2"
13289                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13290                 [ -n "$user_rec2" ] ||
13291                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13292                 [ $user_rec1 == $user_rec2 ] ||
13293                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13294                               "$user_rec1, but is $user_rec2"
13295         done
13296
13297         # ensure we are past the previous changelog_min_gc_interval set above
13298         sleep 2
13299
13300         # generate one more changelog to trigger fail_loc
13301         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13302                 error "create $DIR/$tdir/${tfile}bis failed"
13303
13304         # ensure gc thread is done
13305         for i in $(mdts_nodes); do
13306                 wait_update $i \
13307                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13308                         error "$i: GC-thread not done"
13309         done
13310
13311         local first_rec
13312         for i in $(seq $MDSCOUNT); do
13313                 # check cl_user1 still registered
13314                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13315                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13316                 # check cl_user2 unregistered
13317                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13318                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13319
13320                 # check changelogs are present and starting at $user_rec1 + 1
13321                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13322                 [ -n "$user_rec1" ] ||
13323                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13324                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13325                             awk '{ print $1; exit; }')
13326
13327                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13328                 [ $((user_rec1 + 1)) == $first_rec ] ||
13329                         error "mds$i: first index should be $user_rec1 + 1, " \
13330                               "but is $first_rec"
13331         done
13332 }
13333 run_test 160g "changelog garbage collect (old users)"
13334
13335 test_160h() {
13336         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13337         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13338                 skip "Need MDS version at least 2.10.56"
13339
13340         local mdts=$(comma_list $(mdts_nodes))
13341
13342         # Create a user
13343         changelog_register || error "first changelog_register failed"
13344         changelog_register || error "second changelog_register failed"
13345         local cl_users
13346         declare -A cl_user1
13347         declare -A cl_user2
13348         local user_rec1
13349         local user_rec2
13350         local i
13351
13352         # generate some changelog records to accumulate on each MDT
13353         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13354         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13355                 error "create $DIR/$tdir/$tfile failed"
13356
13357         # check changelogs have been generated
13358         local nbcl=$(changelog_dump | wc -l)
13359         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13360
13361         for param in "changelog_max_idle_time=10" \
13362                      "changelog_gc=1" \
13363                      "changelog_min_gc_interval=2"; do
13364                 local MDT0=$(facet_svc $SINGLEMDS)
13365                 local var="${param%=*}"
13366                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13367
13368                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13369                 do_nodes $mdts $LCTL set_param mdd.*.$param
13370         done
13371
13372         # force cl_user2 to be idle (1st part)
13373         sleep 9
13374
13375         for i in $(seq $MDSCOUNT); do
13376                 cl_users=(${CL_USERS[mds$i]})
13377                 cl_user1[mds$i]="${cl_users[0]}"
13378                 cl_user2[mds$i]="${cl_users[1]}"
13379
13380                 [ -n "${cl_user1[mds$i]}" ] ||
13381                         error "mds$i: no user registered"
13382                 [ -n "${cl_user2[mds$i]}" ] ||
13383                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13384
13385                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13386                 [ -n "$user_rec1" ] ||
13387                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13388                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13389                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13390                 [ -n "$user_rec2" ] ||
13391                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13392                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13393                      "$user_rec1 + 2 == $user_rec2"
13394                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13395                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13396                               "$user_rec1 + 2, but is $user_rec2"
13397                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13398                 [ -n "$user_rec2" ] ||
13399                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13400                 [ $user_rec1 == $user_rec2 ] ||
13401                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13402                               "$user_rec1, but is $user_rec2"
13403         done
13404
13405         # force cl_user2 to be idle (2nd part) and to reach
13406         # changelog_max_idle_time
13407         sleep 2
13408
13409         # force each GC-thread start and block then
13410         # one per MDT/MDD, set fail_val accordingly
13411         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
13412         do_nodes $mdts $LCTL set_param fail_loc=0x1316
13413
13414         # generate more changelogs to trigger fail_loc
13415         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13416                 error "create $DIR/$tdir/${tfile}bis failed"
13417
13418         # stop MDT to stop GC-thread, should be done in back-ground as it will
13419         # block waiting for the thread to be released and exit
13420         declare -A stop_pids
13421         for i in $(seq $MDSCOUNT); do
13422                 stop mds$i &
13423                 stop_pids[mds$i]=$!
13424         done
13425
13426         for i in $(mdts_nodes); do
13427                 local facet
13428                 local nb=0
13429                 local facets=$(facets_up_on_host $i)
13430
13431                 for facet in ${facets//,/ }; do
13432                         if [[ $facet == mds* ]]; then
13433                                 nb=$((nb + 1))
13434                         fi
13435                 done
13436                 # ensure each MDS's gc threads are still present and all in "R"
13437                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
13438                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
13439                         error "$i: expected $nb GC-thread"
13440                 wait_update $i \
13441                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
13442                         "R" 20 ||
13443                         error "$i: GC-thread not found in R-state"
13444                 # check umounts of each MDT on MDS have reached kthread_stop()
13445                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
13446                         error "$i: expected $nb umount"
13447                 wait_update $i \
13448                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
13449                         error "$i: umount not found in D-state"
13450         done
13451
13452         # release all GC-threads
13453         do_nodes $mdts $LCTL set_param fail_loc=0
13454
13455         # wait for MDT stop to complete
13456         for i in $(seq $MDSCOUNT); do
13457                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
13458         done
13459
13460         # XXX
13461         # may try to check if any orphan changelog records are present
13462         # via ldiskfs/zfs and llog_reader...
13463
13464         # re-start/mount MDTs
13465         for i in $(seq $MDSCOUNT); do
13466                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
13467                         error "Fail to start mds$i"
13468         done
13469
13470         local first_rec
13471         for i in $(seq $MDSCOUNT); do
13472                 # check cl_user1 still registered
13473                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13474                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13475                 # check cl_user2 unregistered
13476                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13477                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13478
13479                 # check changelogs are present and starting at $user_rec1 + 1
13480                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13481                 [ -n "$user_rec1" ] ||
13482                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13483                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13484                             awk '{ print $1; exit; }')
13485
13486                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13487                 [ $((user_rec1 + 1)) == $first_rec ] ||
13488                         error "mds$i: first index should be $user_rec1 + 1, " \
13489                               "but is $first_rec"
13490         done
13491 }
13492 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
13493               "during mount"
13494
13495 test_160i() {
13496
13497         local mdts=$(comma_list $(mdts_nodes))
13498
13499         changelog_register || error "first changelog_register failed"
13500
13501         # generate some changelog records to accumulate on each MDT
13502         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13503         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13504                 error "create $DIR/$tdir/$tfile failed"
13505
13506         # check changelogs have been generated
13507         local nbcl=$(changelog_dump | wc -l)
13508         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13509
13510         # simulate race between register and unregister
13511         # XXX as fail_loc is set per-MDS, with DNE configs the race
13512         # simulation will only occur for one MDT per MDS and for the
13513         # others the normal race scenario will take place
13514         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
13515         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
13516         do_nodes $mdts $LCTL set_param fail_val=1
13517
13518         # unregister 1st user
13519         changelog_deregister &
13520         local pid1=$!
13521         # wait some time for deregister work to reach race rdv
13522         sleep 2
13523         # register 2nd user
13524         changelog_register || error "2nd user register failed"
13525
13526         wait $pid1 || error "1st user deregister failed"
13527
13528         local i
13529         local last_rec
13530         declare -A LAST_REC
13531         for i in $(seq $MDSCOUNT); do
13532                 if changelog_users mds$i | grep "^cl"; then
13533                         # make sure new records are added with one user present
13534                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
13535                                           awk '/^current.index:/ { print $NF }')
13536                 else
13537                         error "mds$i has no user registered"
13538                 fi
13539         done
13540
13541         # generate more changelog records to accumulate on each MDT
13542         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13543                 error "create $DIR/$tdir/${tfile}bis failed"
13544
13545         for i in $(seq $MDSCOUNT); do
13546                 last_rec=$(changelog_users $SINGLEMDS |
13547                            awk '/^current.index:/ { print $NF }')
13548                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
13549                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
13550                         error "changelogs are off on mds$i"
13551         done
13552 }
13553 run_test 160i "changelog user register/unregister race"
13554
13555 test_161a() {
13556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13557
13558         test_mkdir -c1 $DIR/$tdir
13559         cp /etc/hosts $DIR/$tdir/$tfile
13560         test_mkdir -c1 $DIR/$tdir/foo1
13561         test_mkdir -c1 $DIR/$tdir/foo2
13562         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13563         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13564         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13565         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13566         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13567         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13568                 $LFS fid2path $DIR $FID
13569                 error "bad link ea"
13570         fi
13571         # middle
13572         rm $DIR/$tdir/foo2/zachary
13573         # last
13574         rm $DIR/$tdir/foo2/thor
13575         # first
13576         rm $DIR/$tdir/$tfile
13577         # rename
13578         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13579         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13580                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13581         rm $DIR/$tdir/foo2/maggie
13582
13583         # overflow the EA
13584         local longname=$tfile.avg_len_is_thirty_two_
13585         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13586                 error_noexit 'failed to unlink many hardlinks'" EXIT
13587         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13588                 error "failed to hardlink many files"
13589         links=$($LFS fid2path $DIR $FID | wc -l)
13590         echo -n "${links}/1000 links in link EA"
13591         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13592 }
13593 run_test 161a "link ea sanity"
13594
13595 test_161b() {
13596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13597         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13598
13599         local MDTIDX=1
13600         local remote_dir=$DIR/$tdir/remote_dir
13601
13602         mkdir -p $DIR/$tdir
13603         $LFS mkdir -i $MDTIDX $remote_dir ||
13604                 error "create remote directory failed"
13605
13606         cp /etc/hosts $remote_dir/$tfile
13607         mkdir -p $remote_dir/foo1
13608         mkdir -p $remote_dir/foo2
13609         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13610         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13611         ln $remote_dir/$tfile $remote_dir/foo1/luna
13612         ln $remote_dir/$tfile $remote_dir/foo2/thor
13613
13614         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13615                      tr -d ']')
13616         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13617                 $LFS fid2path $DIR $FID
13618                 error "bad link ea"
13619         fi
13620         # middle
13621         rm $remote_dir/foo2/zachary
13622         # last
13623         rm $remote_dir/foo2/thor
13624         # first
13625         rm $remote_dir/$tfile
13626         # rename
13627         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13628         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13629         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13630                 $LFS fid2path $DIR $FID
13631                 error "bad link rename"
13632         fi
13633         rm $remote_dir/foo2/maggie
13634
13635         # overflow the EA
13636         local longname=filename_avg_len_is_thirty_two_
13637         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13638                 error "failed to hardlink many files"
13639         links=$($LFS fid2path $DIR $FID | wc -l)
13640         echo -n "${links}/1000 links in link EA"
13641         [[ ${links} -gt 60 ]] ||
13642                 error "expected at least 60 links in link EA"
13643         unlinkmany $remote_dir/foo2/$longname 1000 ||
13644         error "failed to unlink many hardlinks"
13645 }
13646 run_test 161b "link ea sanity under remote directory"
13647
13648 test_161c() {
13649         remote_mds_nodsh && skip "remote MDS with nodsh"
13650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13651         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13652                 skip "Need MDS version at least 2.1.5"
13653
13654         # define CLF_RENAME_LAST 0x0001
13655         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13656         changelog_register || error "changelog_register failed"
13657
13658         rm -rf $DIR/$tdir
13659         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13660         touch $DIR/$tdir/foo_161c
13661         touch $DIR/$tdir/bar_161c
13662         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13663         changelog_dump | grep RENME | tail -n 5
13664         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13665         changelog_clear 0 || error "changelog_clear failed"
13666         if [ x$flags != "x0x1" ]; then
13667                 error "flag $flags is not 0x1"
13668         fi
13669
13670         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13671         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13672         touch $DIR/$tdir/foo_161c
13673         touch $DIR/$tdir/bar_161c
13674         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13675         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13676         changelog_dump | grep RENME | tail -n 5
13677         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13678         changelog_clear 0 || error "changelog_clear failed"
13679         if [ x$flags != "x0x0" ]; then
13680                 error "flag $flags is not 0x0"
13681         fi
13682         echo "rename overwrite a target having nlink > 1," \
13683                 "changelog record has flags of $flags"
13684
13685         # rename doesn't overwrite a target (changelog flag 0x0)
13686         touch $DIR/$tdir/foo_161c
13687         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13688         changelog_dump | grep RENME | tail -n 5
13689         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13690         changelog_clear 0 || error "changelog_clear failed"
13691         if [ x$flags != "x0x0" ]; then
13692                 error "flag $flags is not 0x0"
13693         fi
13694         echo "rename doesn't overwrite a target," \
13695                 "changelog record has flags of $flags"
13696
13697         # define CLF_UNLINK_LAST 0x0001
13698         # unlink a file having nlink = 1 (changelog flag 0x1)
13699         rm -f $DIR/$tdir/foo2_161c
13700         changelog_dump | grep UNLNK | tail -n 5
13701         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13702         changelog_clear 0 || error "changelog_clear failed"
13703         if [ x$flags != "x0x1" ]; then
13704                 error "flag $flags is not 0x1"
13705         fi
13706         echo "unlink a file having nlink = 1," \
13707                 "changelog record has flags of $flags"
13708
13709         # unlink a file having nlink > 1 (changelog flag 0x0)
13710         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13711         rm -f $DIR/$tdir/foobar_161c
13712         changelog_dump | grep UNLNK | tail -n 5
13713         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13714         changelog_clear 0 || error "changelog_clear failed"
13715         if [ x$flags != "x0x0" ]; then
13716                 error "flag $flags is not 0x0"
13717         fi
13718         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13719 }
13720 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13721
13722 test_161d() {
13723         remote_mds_nodsh && skip "remote MDS with nodsh"
13724         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13725
13726         local pid
13727         local fid
13728
13729         changelog_register || error "changelog_register failed"
13730
13731         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13732         # interfer with $MOUNT/.lustre/fid/ access
13733         mkdir $DIR/$tdir
13734         [[ $? -eq 0 ]] || error "mkdir failed"
13735
13736         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13737         $LCTL set_param fail_loc=0x8000140c
13738         # 5s pause
13739         $LCTL set_param fail_val=5
13740
13741         # create file
13742         echo foofoo > $DIR/$tdir/$tfile &
13743         pid=$!
13744
13745         # wait for create to be delayed
13746         sleep 2
13747
13748         ps -p $pid
13749         [[ $? -eq 0 ]] || error "create should be blocked"
13750
13751         local tempfile=$(mktemp)
13752         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13753         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13754         # some delay may occur during ChangeLog publishing and file read just
13755         # above, that could allow file write to happen finally
13756         [[ -s $tempfile ]] && echo "file should be empty"
13757
13758         $LCTL set_param fail_loc=0
13759
13760         wait $pid
13761         [[ $? -eq 0 ]] || error "create failed"
13762 }
13763 run_test 161d "create with concurrent .lustre/fid access"
13764
13765 check_path() {
13766         local expected="$1"
13767         shift
13768         local fid="$2"
13769
13770         local path
13771         path=$($LFS fid2path "$@")
13772         local rc=$?
13773
13774         if [ $rc -ne 0 ]; then
13775                 error "path looked up of '$expected' failed: rc=$rc"
13776         elif [ "$path" != "$expected" ]; then
13777                 error "path looked up '$path' instead of '$expected'"
13778         else
13779                 echo "FID '$fid' resolves to path '$path' as expected"
13780         fi
13781 }
13782
13783 test_162a() { # was test_162
13784         test_mkdir -p -c1 $DIR/$tdir/d2
13785         touch $DIR/$tdir/d2/$tfile
13786         touch $DIR/$tdir/d2/x1
13787         touch $DIR/$tdir/d2/x2
13788         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13789         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13790         # regular file
13791         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13792         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13793
13794         # softlink
13795         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13796         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13797         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13798
13799         # softlink to wrong file
13800         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13801         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13802         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13803
13804         # hardlink
13805         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13806         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13807         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13808         # fid2path dir/fsname should both work
13809         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13810         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13811
13812         # hardlink count: check that there are 2 links
13813         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13814         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13815
13816         # hardlink indexing: remove the first link
13817         rm $DIR/$tdir/d2/p/q/r/hlink
13818         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13819 }
13820 run_test 162a "path lookup sanity"
13821
13822 test_162b() {
13823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13824         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13825
13826         mkdir $DIR/$tdir
13827         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13828                                 error "create striped dir failed"
13829
13830         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13831                                         tail -n 1 | awk '{print $2}')
13832         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13833
13834         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13835         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13836
13837         # regular file
13838         for ((i=0;i<5;i++)); do
13839                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13840                         error "get fid for f$i failed"
13841                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13842
13843                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13844                         error "get fid for d$i failed"
13845                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13846         done
13847
13848         return 0
13849 }
13850 run_test 162b "striped directory path lookup sanity"
13851
13852 # LU-4239: Verify fid2path works with paths 100 or more directories deep
13853 test_162c() {
13854         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
13855                 skip "Need MDS version at least 2.7.51"
13856
13857         local lpath=$tdir.local
13858         local rpath=$tdir.remote
13859
13860         test_mkdir $DIR/$lpath
13861         test_mkdir $DIR/$rpath
13862
13863         for ((i = 0; i <= 101; i++)); do
13864                 lpath="$lpath/$i"
13865                 mkdir $DIR/$lpath
13866                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
13867                         error "get fid for local directory $DIR/$lpath failed"
13868                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
13869
13870                 rpath="$rpath/$i"
13871                 test_mkdir $DIR/$rpath
13872                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
13873                         error "get fid for remote directory $DIR/$rpath failed"
13874                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
13875         done
13876
13877         return 0
13878 }
13879 run_test 162c "fid2path works with paths 100 or more directories deep"
13880
13881 test_169() {
13882         # do directio so as not to populate the page cache
13883         log "creating a 10 Mb file"
13884         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13885         log "starting reads"
13886         dd if=$DIR/$tfile of=/dev/null bs=4096 &
13887         log "truncating the file"
13888         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13889         log "killing dd"
13890         kill %+ || true # reads might have finished
13891         echo "wait until dd is finished"
13892         wait
13893         log "removing the temporary file"
13894         rm -rf $DIR/$tfile || error "tmp file removal failed"
13895 }
13896 run_test 169 "parallel read and truncate should not deadlock"
13897
13898 test_170() {
13899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13900
13901         $LCTL clear     # bug 18514
13902         $LCTL debug_daemon start $TMP/${tfile}_log_good
13903         touch $DIR/$tfile
13904         $LCTL debug_daemon stop
13905         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
13906                 error "sed failed to read log_good"
13907
13908         $LCTL debug_daemon start $TMP/${tfile}_log_good
13909         rm -rf $DIR/$tfile
13910         $LCTL debug_daemon stop
13911
13912         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
13913                error "lctl df log_bad failed"
13914
13915         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13916         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13917
13918         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
13919         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
13920
13921         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
13922                 error "bad_line good_line1 good_line2 are empty"
13923
13924         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13925         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
13926         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13927
13928         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
13929         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13930         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13931
13932         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
13933                 error "bad_line_new good_line_new are empty"
13934
13935         local expected_good=$((good_line1 + good_line2*2))
13936
13937         rm -f $TMP/${tfile}*
13938         # LU-231, short malformed line may not be counted into bad lines
13939         if [ $bad_line -ne $bad_line_new ] &&
13940                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
13941                 error "expected $bad_line bad lines, but got $bad_line_new"
13942                 return 1
13943         fi
13944
13945         if [ $expected_good -ne $good_line_new ]; then
13946                 error "expected $expected_good good lines, but got $good_line_new"
13947                 return 2
13948         fi
13949         true
13950 }
13951 run_test 170 "test lctl df to handle corrupted log ====================="
13952
13953 test_171() { # bug20592
13954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13955
13956         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
13957         $LCTL set_param fail_loc=0x50e
13958         $LCTL set_param fail_val=3000
13959         multiop_bg_pause $DIR/$tfile O_s || true
13960         local MULTIPID=$!
13961         kill -USR1 $MULTIPID
13962         # cause log dump
13963         sleep 3
13964         wait $MULTIPID
13965         if dmesg | grep "recursive fault"; then
13966                 error "caught a recursive fault"
13967         fi
13968         $LCTL set_param fail_loc=0
13969         true
13970 }
13971 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
13972
13973 # it would be good to share it with obdfilter-survey/iokit-libecho code
13974 setup_obdecho_osc () {
13975         local rc=0
13976         local ost_nid=$1
13977         local obdfilter_name=$2
13978         echo "Creating new osc for $obdfilter_name on $ost_nid"
13979         # make sure we can find loopback nid
13980         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
13981
13982         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
13983                            ${obdfilter_name}_osc_UUID || rc=2; }
13984         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
13985                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
13986         return $rc
13987 }
13988
13989 cleanup_obdecho_osc () {
13990         local obdfilter_name=$1
13991         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
13992         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
13993         return 0
13994 }
13995
13996 obdecho_test() {
13997         local OBD=$1
13998         local node=$2
13999         local pages=${3:-64}
14000         local rc=0
14001         local id
14002
14003         local count=10
14004         local obd_size=$(get_obd_size $node $OBD)
14005         local page_size=$(get_page_size $node)
14006         if [[ -n "$obd_size" ]]; then
14007                 local new_count=$((obd_size / (pages * page_size / 1024)))
14008                 [[ $new_count -ge $count ]] || count=$new_count
14009         fi
14010
14011         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
14012         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
14013                            rc=2; }
14014         if [ $rc -eq 0 ]; then
14015             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
14016             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
14017         fi
14018         echo "New object id is $id"
14019         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
14020                            rc=4; }
14021         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
14022                            "test_brw $count w v $pages $id" || rc=4; }
14023         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
14024                            rc=4; }
14025         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
14026                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
14027         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
14028                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
14029         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
14030         return $rc
14031 }
14032
14033 test_180a() {
14034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14035
14036         if ! module_loaded obdecho; then
14037                 load_module obdecho/obdecho &&
14038                         stack_trap "rmmod obdecho" EXIT ||
14039                         error "unable to load obdecho on client"
14040         fi
14041
14042         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
14043         local host=$($LCTL get_param -n osc.$osc.import |
14044                      awk '/current_connection:/ { print $2 }' )
14045         local target=$($LCTL get_param -n osc.$osc.import |
14046                        awk '/target:/ { print $2 }' )
14047         target=${target%_UUID}
14048
14049         if [ -n "$target" ]; then
14050                 setup_obdecho_osc $host $target &&
14051                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
14052                         { error "obdecho setup failed with $?"; return; }
14053
14054                 obdecho_test ${target}_osc client ||
14055                         error "obdecho_test failed on ${target}_osc"
14056         else
14057                 $LCTL get_param osc.$osc.import
14058                 error "there is no osc.$osc.import target"
14059         fi
14060 }
14061 run_test 180a "test obdecho on osc"
14062
14063 test_180b() {
14064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14065         remote_ost_nodsh && skip "remote OST with nodsh"
14066
14067         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14068                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14069                 error "failed to load module obdecho"
14070
14071         local target=$(do_facet ost1 $LCTL dl |
14072                        awk '/obdfilter/ { print $4; exit; }')
14073
14074         if [ -n "$target" ]; then
14075                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
14076         else
14077                 do_facet ost1 $LCTL dl
14078                 error "there is no obdfilter target on ost1"
14079         fi
14080 }
14081 run_test 180b "test obdecho directly on obdfilter"
14082
14083 test_180c() { # LU-2598
14084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14085         remote_ost_nodsh && skip "remote OST with nodsh"
14086         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
14087                 skip "Need MDS version at least 2.4.0"
14088
14089         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14090                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14091                 error "failed to load module obdecho"
14092
14093         local target=$(do_facet ost1 $LCTL dl |
14094                        awk '/obdfilter/ { print $4; exit; }')
14095
14096         if [ -n "$target" ]; then
14097                 local pages=16384 # 64MB bulk I/O RPC size
14098
14099                 obdecho_test "$target" ost1 "$pages" ||
14100                         error "obdecho_test with pages=$pages failed with $?"
14101         else
14102                 do_facet ost1 $LCTL dl
14103                 error "there is no obdfilter target on ost1"
14104         fi
14105 }
14106 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
14107
14108 test_181() { # bug 22177
14109         test_mkdir $DIR/$tdir
14110         # create enough files to index the directory
14111         createmany -o $DIR/$tdir/foobar 4000
14112         # print attributes for debug purpose
14113         lsattr -d .
14114         # open dir
14115         multiop_bg_pause $DIR/$tdir D_Sc || return 1
14116         MULTIPID=$!
14117         # remove the files & current working dir
14118         unlinkmany $DIR/$tdir/foobar 4000
14119         rmdir $DIR/$tdir
14120         kill -USR1 $MULTIPID
14121         wait $MULTIPID
14122         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
14123         return 0
14124 }
14125 run_test 181 "Test open-unlinked dir ========================"
14126
14127 test_182() {
14128         local fcount=1000
14129         local tcount=10
14130
14131         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14132
14133         $LCTL set_param mdc.*.rpc_stats=clear
14134
14135         for (( i = 0; i < $tcount; i++ )) ; do
14136                 mkdir $DIR/$tdir/$i
14137         done
14138
14139         for (( i = 0; i < $tcount; i++ )) ; do
14140                 createmany -o $DIR/$tdir/$i/f- $fcount &
14141         done
14142         wait
14143
14144         for (( i = 0; i < $tcount; i++ )) ; do
14145                 unlinkmany $DIR/$tdir/$i/f- $fcount &
14146         done
14147         wait
14148
14149         $LCTL get_param mdc.*.rpc_stats
14150
14151         rm -rf $DIR/$tdir
14152 }
14153 run_test 182 "Test parallel modify metadata operations ================"
14154
14155 test_183() { # LU-2275
14156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14157         remote_mds_nodsh && skip "remote MDS with nodsh"
14158         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
14159                 skip "Need MDS version at least 2.3.56"
14160
14161         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14162         echo aaa > $DIR/$tdir/$tfile
14163
14164 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
14165         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
14166
14167         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
14168         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
14169
14170         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
14171
14172         # Flush negative dentry cache
14173         touch $DIR/$tdir/$tfile
14174
14175         # We are not checking for any leaked references here, they'll
14176         # become evident next time we do cleanup with module unload.
14177         rm -rf $DIR/$tdir
14178 }
14179 run_test 183 "No crash or request leak in case of strange dispositions ========"
14180
14181 # test suite 184 is for LU-2016, LU-2017
14182 test_184a() {
14183         check_swap_layouts_support
14184
14185         dir0=$DIR/$tdir/$testnum
14186         test_mkdir -p -c1 $dir0
14187         ref1=/etc/passwd
14188         ref2=/etc/group
14189         file1=$dir0/f1
14190         file2=$dir0/f2
14191         $LFS setstripe -c1 $file1
14192         cp $ref1 $file1
14193         $LFS setstripe -c2 $file2
14194         cp $ref2 $file2
14195         gen1=$($LFS getstripe -g $file1)
14196         gen2=$($LFS getstripe -g $file2)
14197
14198         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
14199         gen=$($LFS getstripe -g $file1)
14200         [[ $gen1 != $gen ]] ||
14201                 "Layout generation on $file1 does not change"
14202         gen=$($LFS getstripe -g $file2)
14203         [[ $gen2 != $gen ]] ||
14204                 "Layout generation on $file2 does not change"
14205
14206         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
14207         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
14208
14209         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
14210 }
14211 run_test 184a "Basic layout swap"
14212
14213 test_184b() {
14214         check_swap_layouts_support
14215
14216         dir0=$DIR/$tdir/$testnum
14217         mkdir -p $dir0 || error "creating dir $dir0"
14218         file1=$dir0/f1
14219         file2=$dir0/f2
14220         file3=$dir0/f3
14221         dir1=$dir0/d1
14222         dir2=$dir0/d2
14223         mkdir $dir1 $dir2
14224         $LFS setstripe -c1 $file1
14225         $LFS setstripe -c2 $file2
14226         $LFS setstripe -c1 $file3
14227         chown $RUNAS_ID $file3
14228         gen1=$($LFS getstripe -g $file1)
14229         gen2=$($LFS getstripe -g $file2)
14230
14231         $LFS swap_layouts $dir1 $dir2 &&
14232                 error "swap of directories layouts should fail"
14233         $LFS swap_layouts $dir1 $file1 &&
14234                 error "swap of directory and file layouts should fail"
14235         $RUNAS $LFS swap_layouts $file1 $file2 &&
14236                 error "swap of file we cannot write should fail"
14237         $LFS swap_layouts $file1 $file3 &&
14238                 error "swap of file with different owner should fail"
14239         /bin/true # to clear error code
14240 }
14241 run_test 184b "Forbidden layout swap (will generate errors)"
14242
14243 test_184c() {
14244         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
14245         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
14246         check_swap_layouts_support
14247
14248         local dir0=$DIR/$tdir/$testnum
14249         mkdir -p $dir0 || error "creating dir $dir0"
14250
14251         local ref1=$dir0/ref1
14252         local ref2=$dir0/ref2
14253         local file1=$dir0/file1
14254         local file2=$dir0/file2
14255         # create a file large enough for the concurrent test
14256         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
14257         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
14258         echo "ref file size: ref1($(stat -c %s $ref1))," \
14259              "ref2($(stat -c %s $ref2))"
14260
14261         cp $ref2 $file2
14262         dd if=$ref1 of=$file1 bs=16k &
14263         local DD_PID=$!
14264
14265         # Make sure dd starts to copy file
14266         while [ ! -f $file1 ]; do sleep 0.1; done
14267
14268         $LFS swap_layouts $file1 $file2
14269         local rc=$?
14270         wait $DD_PID
14271         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
14272         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
14273
14274         # how many bytes copied before swapping layout
14275         local copied=$(stat -c %s $file2)
14276         local remaining=$(stat -c %s $ref1)
14277         remaining=$((remaining - copied))
14278         echo "Copied $copied bytes before swapping layout..."
14279
14280         cmp -n $copied $file1 $ref2 | grep differ &&
14281                 error "Content mismatch [0, $copied) of ref2 and file1"
14282         cmp -n $copied $file2 $ref1 ||
14283                 error "Content mismatch [0, $copied) of ref1 and file2"
14284         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
14285                 error "Content mismatch [$copied, EOF) of ref1 and file1"
14286
14287         # clean up
14288         rm -f $ref1 $ref2 $file1 $file2
14289 }
14290 run_test 184c "Concurrent write and layout swap"
14291
14292 test_184d() {
14293         check_swap_layouts_support
14294         [ -z "$(which getfattr 2>/dev/null)" ] &&
14295                 skip_env "no getfattr command"
14296
14297         local file1=$DIR/$tdir/$tfile-1
14298         local file2=$DIR/$tdir/$tfile-2
14299         local file3=$DIR/$tdir/$tfile-3
14300         local lovea1
14301         local lovea2
14302
14303         mkdir -p $DIR/$tdir
14304         touch $file1 || error "create $file1 failed"
14305         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14306                 error "create $file2 failed"
14307         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14308                 error "create $file3 failed"
14309         lovea1=$(get_layout_param $file1)
14310
14311         $LFS swap_layouts $file2 $file3 ||
14312                 error "swap $file2 $file3 layouts failed"
14313         $LFS swap_layouts $file1 $file2 ||
14314                 error "swap $file1 $file2 layouts failed"
14315
14316         lovea2=$(get_layout_param $file2)
14317         echo "$lovea1"
14318         echo "$lovea2"
14319         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
14320
14321         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14322         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
14323 }
14324 run_test 184d "allow stripeless layouts swap"
14325
14326 test_184e() {
14327         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
14328                 skip "Need MDS version at least 2.6.94"
14329         check_swap_layouts_support
14330         [ -z "$(which getfattr 2>/dev/null)" ] &&
14331                 skip_env "no getfattr command"
14332
14333         local file1=$DIR/$tdir/$tfile-1
14334         local file2=$DIR/$tdir/$tfile-2
14335         local file3=$DIR/$tdir/$tfile-3
14336         local lovea
14337
14338         mkdir -p $DIR/$tdir
14339         touch $file1 || error "create $file1 failed"
14340         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14341                 error "create $file2 failed"
14342         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14343                 error "create $file3 failed"
14344
14345         $LFS swap_layouts $file1 $file2 ||
14346                 error "swap $file1 $file2 layouts failed"
14347
14348         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14349         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
14350
14351         echo 123 > $file1 || error "Should be able to write into $file1"
14352
14353         $LFS swap_layouts $file1 $file3 ||
14354                 error "swap $file1 $file3 layouts failed"
14355
14356         echo 123 > $file1 || error "Should be able to write into $file1"
14357
14358         rm -rf $file1 $file2 $file3
14359 }
14360 run_test 184e "Recreate layout after stripeless layout swaps"
14361
14362 test_184f() {
14363         # Create a file with name longer than sizeof(struct stat) ==
14364         # 144 to see if we can get chars from the file name to appear
14365         # in the returned striping. Note that 'f' == 0x66.
14366         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
14367
14368         mkdir -p $DIR/$tdir
14369         mcreate $DIR/$tdir/$file
14370         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
14371                 error "IOC_MDC_GETFILEINFO returned garbage striping"
14372         fi
14373 }
14374 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
14375
14376 test_185() { # LU-2441
14377         # LU-3553 - no volatile file support in old servers
14378         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
14379                 skip "Need MDS version at least 2.3.60"
14380
14381         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14382         touch $DIR/$tdir/spoo
14383         local mtime1=$(stat -c "%Y" $DIR/$tdir)
14384         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
14385                 error "cannot create/write a volatile file"
14386         [ "$FILESET" == "" ] &&
14387         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
14388                 error "FID is still valid after close"
14389
14390         multiop_bg_pause $DIR/$tdir vVw4096_c
14391         local multi_pid=$!
14392
14393         local OLD_IFS=$IFS
14394         IFS=":"
14395         local fidv=($fid)
14396         IFS=$OLD_IFS
14397         # assume that the next FID for this client is sequential, since stdout
14398         # is unfortunately eaten by multiop_bg_pause
14399         local n=$((${fidv[1]} + 1))
14400         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
14401         if [ "$FILESET" == "" ]; then
14402                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
14403                         error "FID is missing before close"
14404         fi
14405         kill -USR1 $multi_pid
14406         # 1 second delay, so if mtime change we will see it
14407         sleep 1
14408         local mtime2=$(stat -c "%Y" $DIR/$tdir)
14409         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
14410 }
14411 run_test 185 "Volatile file support"
14412
14413 test_187a() {
14414         remote_mds_nodsh && skip "remote MDS with nodsh"
14415         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14416                 skip "Need MDS version at least 2.3.0"
14417
14418         local dir0=$DIR/$tdir/$testnum
14419         mkdir -p $dir0 || error "creating dir $dir0"
14420
14421         local file=$dir0/file1
14422         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
14423         local dv1=$($LFS data_version $file)
14424         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
14425         local dv2=$($LFS data_version $file)
14426         [[ $dv1 != $dv2 ]] ||
14427                 error "data version did not change on write $dv1 == $dv2"
14428
14429         # clean up
14430         rm -f $file1
14431 }
14432 run_test 187a "Test data version change"
14433
14434 test_187b() {
14435         remote_mds_nodsh && skip "remote MDS with nodsh"
14436         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14437                 skip "Need MDS version at least 2.3.0"
14438
14439         local dir0=$DIR/$tdir/$testnum
14440         mkdir -p $dir0 || error "creating dir $dir0"
14441
14442         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
14443         [[ ${DV[0]} != ${DV[1]} ]] ||
14444                 error "data version did not change on write"\
14445                       " ${DV[0]} == ${DV[1]}"
14446
14447         # clean up
14448         rm -f $file1
14449 }
14450 run_test 187b "Test data version change on volatile file"
14451
14452 test_200() {
14453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14454         remote_mgs_nodsh && skip "remote MGS with nodsh"
14455         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14456
14457         local POOL=${POOL:-cea1}
14458         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
14459         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
14460         # Pool OST targets
14461         local first_ost=0
14462         local last_ost=$(($OSTCOUNT - 1))
14463         local ost_step=2
14464         local ost_list=$(seq $first_ost $ost_step $last_ost)
14465         local ost_range="$first_ost $last_ost $ost_step"
14466         local test_path=$POOL_ROOT/$POOL_DIR_NAME
14467         local file_dir=$POOL_ROOT/file_tst
14468         local subdir=$test_path/subdir
14469         local rc=0
14470
14471         if ! combined_mgs_mds ; then
14472                 mount_mgs_client
14473         fi
14474
14475         while : ; do
14476                 # former test_200a test_200b
14477                 pool_add $POOL                          || { rc=$? ; break; }
14478                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
14479                 # former test_200c test_200d
14480                 mkdir -p $test_path
14481                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
14482                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
14483                 mkdir -p $subdir
14484                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
14485                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
14486                                                         || { rc=$? ; break; }
14487                 # former test_200e test_200f
14488                 local files=$((OSTCOUNT*3))
14489                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
14490                                                         || { rc=$? ; break; }
14491                 pool_create_files $POOL $file_dir $files "$ost_list" \
14492                                                         || { rc=$? ; break; }
14493                 # former test_200g test_200h
14494                 pool_lfs_df $POOL                       || { rc=$? ; break; }
14495                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
14496
14497                 # former test_201a test_201b test_201c
14498                 pool_remove_first_target $POOL          || { rc=$? ; break; }
14499
14500                 local f=$test_path/$tfile
14501                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
14502                 pool_remove $POOL $f                    || { rc=$? ; break; }
14503                 break
14504         done
14505
14506         destroy_test_pools
14507
14508         if ! combined_mgs_mds ; then
14509                 umount_mgs_client
14510         fi
14511         return $rc
14512 }
14513 run_test 200 "OST pools"
14514
14515 # usage: default_attr <count | size | offset>
14516 default_attr() {
14517         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14518 }
14519
14520 # usage: check_default_stripe_attr
14521 check_default_stripe_attr() {
14522         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14523         case $1 in
14524         --stripe-count|-c)
14525                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14526         --stripe-size|-S)
14527                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14528         --stripe-index|-i)
14529                 EXPECTED=-1;;
14530         *)
14531                 error "unknown getstripe attr '$1'"
14532         esac
14533
14534         [ $ACTUAL == $EXPECTED ] ||
14535                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14536 }
14537
14538 test_204a() {
14539         test_mkdir $DIR/$tdir
14540         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14541
14542         check_default_stripe_attr --stripe-count
14543         check_default_stripe_attr --stripe-size
14544         check_default_stripe_attr --stripe-index
14545 }
14546 run_test 204a "Print default stripe attributes"
14547
14548 test_204b() {
14549         test_mkdir $DIR/$tdir
14550         $LFS setstripe --stripe-count 1 $DIR/$tdir
14551
14552         check_default_stripe_attr --stripe-size
14553         check_default_stripe_attr --stripe-index
14554 }
14555 run_test 204b "Print default stripe size and offset"
14556
14557 test_204c() {
14558         test_mkdir $DIR/$tdir
14559         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14560
14561         check_default_stripe_attr --stripe-count
14562         check_default_stripe_attr --stripe-index
14563 }
14564 run_test 204c "Print default stripe count and offset"
14565
14566 test_204d() {
14567         test_mkdir $DIR/$tdir
14568         $LFS setstripe --stripe-index 0 $DIR/$tdir
14569
14570         check_default_stripe_attr --stripe-count
14571         check_default_stripe_attr --stripe-size
14572 }
14573 run_test 204d "Print default stripe count and size"
14574
14575 test_204e() {
14576         test_mkdir $DIR/$tdir
14577         $LFS setstripe -d $DIR/$tdir
14578
14579         check_default_stripe_attr --stripe-count --raw
14580         check_default_stripe_attr --stripe-size --raw
14581         check_default_stripe_attr --stripe-index --raw
14582 }
14583 run_test 204e "Print raw stripe attributes"
14584
14585 test_204f() {
14586         test_mkdir $DIR/$tdir
14587         $LFS setstripe --stripe-count 1 $DIR/$tdir
14588
14589         check_default_stripe_attr --stripe-size --raw
14590         check_default_stripe_attr --stripe-index --raw
14591 }
14592 run_test 204f "Print raw stripe size and offset"
14593
14594 test_204g() {
14595         test_mkdir $DIR/$tdir
14596         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14597
14598         check_default_stripe_attr --stripe-count --raw
14599         check_default_stripe_attr --stripe-index --raw
14600 }
14601 run_test 204g "Print raw stripe count and offset"
14602
14603 test_204h() {
14604         test_mkdir $DIR/$tdir
14605         $LFS setstripe --stripe-index 0 $DIR/$tdir
14606
14607         check_default_stripe_attr --stripe-count --raw
14608         check_default_stripe_attr --stripe-size --raw
14609 }
14610 run_test 204h "Print raw stripe count and size"
14611
14612 # Figure out which job scheduler is being used, if any,
14613 # or use a fake one
14614 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14615         JOBENV=SLURM_JOB_ID
14616 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14617         JOBENV=LSB_JOBID
14618 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14619         JOBENV=PBS_JOBID
14620 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14621         JOBENV=LOADL_STEP_ID
14622 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14623         JOBENV=JOB_ID
14624 else
14625         $LCTL list_param jobid_name > /dev/null 2>&1
14626         if [ $? -eq 0 ]; then
14627                 JOBENV=nodelocal
14628         else
14629                 JOBENV=FAKE_JOBID
14630         fi
14631 fi
14632 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14633
14634 verify_jobstats() {
14635         local cmd=($1)
14636         shift
14637         local facets="$@"
14638
14639 # we don't really need to clear the stats for this test to work, since each
14640 # command has a unique jobid, but it makes debugging easier if needed.
14641 #       for facet in $facets; do
14642 #               local dev=$(convert_facet2label $facet)
14643 #               # clear old jobstats
14644 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14645 #       done
14646
14647         # use a new JobID for each test, or we might see an old one
14648         [ "$JOBENV" = "FAKE_JOBID" ] &&
14649                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14650
14651         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14652
14653         [ "$JOBENV" = "nodelocal" ] && {
14654                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14655                 $LCTL set_param jobid_name=$FAKE_JOBID
14656                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14657         }
14658
14659         log "Test: ${cmd[*]}"
14660         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14661
14662         if [ $JOBENV = "FAKE_JOBID" ]; then
14663                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14664         else
14665                 ${cmd[*]}
14666         fi
14667
14668         # all files are created on OST0000
14669         for facet in $facets; do
14670                 local stats="*.$(convert_facet2label $facet).job_stats"
14671
14672                 # strip out libtool wrappers for in-tree executables
14673                 if [ $(do_facet $facet lctl get_param $stats |
14674                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14675                         do_facet $facet lctl get_param $stats
14676                         error "No jobstats for $JOBVAL found on $facet::$stats"
14677                 fi
14678         done
14679 }
14680
14681 jobstats_set() {
14682         local new_jobenv=$1
14683
14684         set_persistent_param_and_check client "jobid_var" \
14685                 "$FSNAME.sys.jobid_var" $new_jobenv
14686 }
14687
14688 test_205() { # Job stats
14689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14690         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14691                 skip "Need MDS version with at least 2.7.1"
14692         remote_mgs_nodsh && skip "remote MGS with nodsh"
14693         remote_mds_nodsh && skip "remote MDS with nodsh"
14694         remote_ost_nodsh && skip "remote OST with nodsh"
14695         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14696                 skip "Server doesn't support jobstats"
14697         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14698
14699         local old_jobenv=$($LCTL get_param -n jobid_var)
14700         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14701
14702         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14703                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14704         else
14705                 stack_trap "do_facet mgs $PERM_CMD \
14706                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14707         fi
14708         changelog_register
14709
14710         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14711                                 mdt.*.job_cleanup_interval | head -n 1)
14712         local new_interval=5
14713         do_facet $SINGLEMDS \
14714                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14715         stack_trap "do_facet $SINGLEMDS \
14716                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14717         local start=$SECONDS
14718
14719         local cmd
14720         # mkdir
14721         cmd="mkdir $DIR/$tdir"
14722         verify_jobstats "$cmd" "$SINGLEMDS"
14723         # rmdir
14724         cmd="rmdir $DIR/$tdir"
14725         verify_jobstats "$cmd" "$SINGLEMDS"
14726         # mkdir on secondary MDT
14727         if [ $MDSCOUNT -gt 1 ]; then
14728                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14729                 verify_jobstats "$cmd" "mds2"
14730         fi
14731         # mknod
14732         cmd="mknod $DIR/$tfile c 1 3"
14733         verify_jobstats "$cmd" "$SINGLEMDS"
14734         # unlink
14735         cmd="rm -f $DIR/$tfile"
14736         verify_jobstats "$cmd" "$SINGLEMDS"
14737         # create all files on OST0000 so verify_jobstats can find OST stats
14738         # open & close
14739         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14740         verify_jobstats "$cmd" "$SINGLEMDS"
14741         # setattr
14742         cmd="touch $DIR/$tfile"
14743         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14744         # write
14745         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14746         verify_jobstats "$cmd" "ost1"
14747         # read
14748         cancel_lru_locks osc
14749         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14750         verify_jobstats "$cmd" "ost1"
14751         # truncate
14752         cmd="$TRUNCATE $DIR/$tfile 0"
14753         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14754         # rename
14755         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14756         verify_jobstats "$cmd" "$SINGLEMDS"
14757         # jobstats expiry - sleep until old stats should be expired
14758         local left=$((new_interval + 5 - (SECONDS - start)))
14759         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14760                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14761                         "0" $left
14762         cmd="mkdir $DIR/$tdir.expire"
14763         verify_jobstats "$cmd" "$SINGLEMDS"
14764         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14765             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14766
14767         # Ensure that jobid are present in changelog (if supported by MDS)
14768         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14769                 changelog_dump | tail -10
14770                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14771                 [ $jobids -eq 9 ] ||
14772                         error "Wrong changelog jobid count $jobids != 9"
14773
14774                 # LU-5862
14775                 JOBENV="disable"
14776                 jobstats_set $JOBENV
14777                 touch $DIR/$tfile
14778                 changelog_dump | grep $tfile
14779                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14780                 [ $jobids -eq 0 ] ||
14781                         error "Unexpected jobids when jobid_var=$JOBENV"
14782         fi
14783
14784         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14785         JOBENV="JOBCOMPLEX"
14786         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14787
14788         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14789 }
14790 run_test 205 "Verify job stats"
14791
14792 # LU-1480, LU-1773 and LU-1657
14793 test_206() {
14794         mkdir -p $DIR/$tdir
14795         $LFS setstripe -c -1 $DIR/$tdir
14796 #define OBD_FAIL_LOV_INIT 0x1403
14797         $LCTL set_param fail_loc=0xa0001403
14798         $LCTL set_param fail_val=1
14799         touch $DIR/$tdir/$tfile || true
14800 }
14801 run_test 206 "fail lov_init_raid0() doesn't lbug"
14802
14803 test_207a() {
14804         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14805         local fsz=`stat -c %s $DIR/$tfile`
14806         cancel_lru_locks mdc
14807
14808         # do not return layout in getattr intent
14809 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14810         $LCTL set_param fail_loc=0x170
14811         local sz=`stat -c %s $DIR/$tfile`
14812
14813         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
14814
14815         rm -rf $DIR/$tfile
14816 }
14817 run_test 207a "can refresh layout at glimpse"
14818
14819 test_207b() {
14820         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14821         local cksum=`md5sum $DIR/$tfile`
14822         local fsz=`stat -c %s $DIR/$tfile`
14823         cancel_lru_locks mdc
14824         cancel_lru_locks osc
14825
14826         # do not return layout in getattr intent
14827 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
14828         $LCTL set_param fail_loc=0x171
14829
14830         # it will refresh layout after the file is opened but before read issues
14831         echo checksum is "$cksum"
14832         echo "$cksum" |md5sum -c --quiet || error "file differs"
14833
14834         rm -rf $DIR/$tfile
14835 }
14836 run_test 207b "can refresh layout at open"
14837
14838 test_208() {
14839         # FIXME: in this test suite, only RD lease is used. This is okay
14840         # for now as only exclusive open is supported. After generic lease
14841         # is done, this test suite should be revised. - Jinshan
14842
14843         remote_mds_nodsh && skip "remote MDS with nodsh"
14844         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
14845                 skip "Need MDS version at least 2.4.52"
14846
14847         echo "==== test 1: verify get lease work"
14848         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
14849
14850         echo "==== test 2: verify lease can be broken by upcoming open"
14851         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14852         local PID=$!
14853         sleep 1
14854
14855         $MULTIOP $DIR/$tfile oO_RDONLY:c
14856         kill -USR1 $PID && wait $PID || error "break lease error"
14857
14858         echo "==== test 3: verify lease can't be granted if an open already exists"
14859         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
14860         local PID=$!
14861         sleep 1
14862
14863         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
14864         kill -USR1 $PID && wait $PID || error "open file error"
14865
14866         echo "==== test 4: lease can sustain over recovery"
14867         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
14868         PID=$!
14869         sleep 1
14870
14871         fail mds1
14872
14873         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
14874
14875         echo "==== test 5: lease broken can't be regained by replay"
14876         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14877         PID=$!
14878         sleep 1
14879
14880         # open file to break lease and then recovery
14881         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
14882         fail mds1
14883
14884         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
14885
14886         rm -f $DIR/$tfile
14887 }
14888 run_test 208 "Exclusive open"
14889
14890 test_209() {
14891         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
14892                 skip_env "must have disp_stripe"
14893
14894         touch $DIR/$tfile
14895         sync; sleep 5; sync;
14896
14897         echo 3 > /proc/sys/vm/drop_caches
14898         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14899
14900         # open/close 500 times
14901         for i in $(seq 500); do
14902                 cat $DIR/$tfile
14903         done
14904
14905         echo 3 > /proc/sys/vm/drop_caches
14906         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14907
14908         echo "before: $req_before, after: $req_after"
14909         [ $((req_after - req_before)) -ge 300 ] &&
14910                 error "open/close requests are not freed"
14911         return 0
14912 }
14913 run_test 209 "read-only open/close requests should be freed promptly"
14914
14915 test_212() {
14916         size=`date +%s`
14917         size=$((size % 8192 + 1))
14918         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
14919         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
14920         rm -f $DIR/f212 $DIR/f212.xyz
14921 }
14922 run_test 212 "Sendfile test ============================================"
14923
14924 test_213() {
14925         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
14926         cancel_lru_locks osc
14927         lctl set_param fail_loc=0x8000040f
14928         # generate a read lock
14929         cat $DIR/$tfile > /dev/null
14930         # write to the file, it will try to cancel the above read lock.
14931         cat /etc/hosts >> $DIR/$tfile
14932 }
14933 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
14934
14935 test_214() { # for bug 20133
14936         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
14937         for (( i=0; i < 340; i++ )) ; do
14938                 touch $DIR/$tdir/d214c/a$i
14939         done
14940
14941         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
14942         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
14943         ls $DIR/d214c || error "ls $DIR/d214c failed"
14944         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
14945         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
14946 }
14947 run_test 214 "hash-indexed directory test - bug 20133"
14948
14949 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
14950 create_lnet_proc_files() {
14951         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
14952 }
14953
14954 # counterpart of create_lnet_proc_files
14955 remove_lnet_proc_files() {
14956         rm -f $TMP/lnet_$1.sys
14957 }
14958
14959 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14960 # 3rd arg as regexp for body
14961 check_lnet_proc_stats() {
14962         local l=$(cat "$TMP/lnet_$1" |wc -l)
14963         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
14964
14965         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
14966 }
14967
14968 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14969 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
14970 # optional and can be regexp for 2nd line (lnet.routes case)
14971 check_lnet_proc_entry() {
14972         local blp=2          # blp stands for 'position of 1st line of body'
14973         [ -z "$5" ] || blp=3 # lnet.routes case
14974
14975         local l=$(cat "$TMP/lnet_$1" |wc -l)
14976         # subtracting one from $blp because the body can be empty
14977         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
14978
14979         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
14980                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
14981
14982         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
14983                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
14984
14985         # bail out if any unexpected line happened
14986         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
14987         [ "$?" != 0 ] || error "$2 misformatted"
14988 }
14989
14990 test_215() { # for bugs 18102, 21079, 21517
14991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14992
14993         local N='(0|[1-9][0-9]*)'       # non-negative numeric
14994         local P='[1-9][0-9]*'           # positive numeric
14995         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
14996         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
14997         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
14998         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
14999
15000         local L1 # regexp for 1st line
15001         local L2 # regexp for 2nd line (optional)
15002         local BR # regexp for the rest (body)
15003
15004         # lnet.stats should look as 11 space-separated non-negative numerics
15005         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
15006         create_lnet_proc_files "stats"
15007         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
15008         remove_lnet_proc_files "stats"
15009
15010         # lnet.routes should look like this:
15011         # Routing disabled/enabled
15012         # net hops priority state router
15013         # where net is a string like tcp0, hops > 0, priority >= 0,
15014         # state is up/down,
15015         # router is a string like 192.168.1.1@tcp2
15016         L1="^Routing (disabled|enabled)$"
15017         L2="^net +hops +priority +state +router$"
15018         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
15019         create_lnet_proc_files "routes"
15020         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
15021         remove_lnet_proc_files "routes"
15022
15023         # lnet.routers should look like this:
15024         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
15025         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
15026         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
15027         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
15028         L1="^ref +rtr_ref +alive +router$"
15029         BR="^$P +$P +(up|down) +$NID$"
15030         create_lnet_proc_files "routers"
15031         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
15032         remove_lnet_proc_files "routers"
15033
15034         # lnet.peers should look like this:
15035         # nid refs state last max rtr min tx min queue
15036         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
15037         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
15038         # numeric (0 or >0 or <0), queue >= 0.
15039         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
15040         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
15041         create_lnet_proc_files "peers"
15042         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
15043         remove_lnet_proc_files "peers"
15044
15045         # lnet.buffers  should look like this:
15046         # pages count credits min
15047         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
15048         L1="^pages +count +credits +min$"
15049         BR="^ +$N +$N +$I +$I$"
15050         create_lnet_proc_files "buffers"
15051         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
15052         remove_lnet_proc_files "buffers"
15053
15054         # lnet.nis should look like this:
15055         # nid status alive refs peer rtr max tx min
15056         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
15057         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
15058         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
15059         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
15060         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
15061         create_lnet_proc_files "nis"
15062         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
15063         remove_lnet_proc_files "nis"
15064
15065         # can we successfully write to lnet.stats?
15066         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
15067 }
15068 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
15069
15070 test_216() { # bug 20317
15071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15072         remote_ost_nodsh && skip "remote OST with nodsh"
15073
15074         local node
15075         local facets=$(get_facets OST)
15076         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15077
15078         save_lustre_params client "osc.*.contention_seconds" > $p
15079         save_lustre_params $facets \
15080                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
15081         save_lustre_params $facets \
15082                 "ldlm.namespaces.filter-*.contended_locks" >> $p
15083         save_lustre_params $facets \
15084                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
15085         clear_stats osc.*.osc_stats
15086
15087         # agressive lockless i/o settings
15088         do_nodes $(comma_list $(osts_nodes)) \
15089                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
15090                         ldlm.namespaces.filter-*.contended_locks=0 \
15091                         ldlm.namespaces.filter-*.contention_seconds=60"
15092         lctl set_param -n osc.*.contention_seconds=60
15093
15094         $DIRECTIO write $DIR/$tfile 0 10 4096
15095         $CHECKSTAT -s 40960 $DIR/$tfile
15096
15097         # disable lockless i/o
15098         do_nodes $(comma_list $(osts_nodes)) \
15099                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
15100                         ldlm.namespaces.filter-*.contended_locks=32 \
15101                         ldlm.namespaces.filter-*.contention_seconds=0"
15102         lctl set_param -n osc.*.contention_seconds=0
15103         clear_stats osc.*.osc_stats
15104
15105         dd if=/dev/zero of=$DIR/$tfile count=0
15106         $CHECKSTAT -s 0 $DIR/$tfile
15107
15108         restore_lustre_params <$p
15109         rm -f $p
15110         rm $DIR/$tfile
15111 }
15112 run_test 216 "check lockless direct write updates file size and kms correctly"
15113
15114 test_217() { # bug 22430
15115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15116
15117         local node
15118         local nid
15119
15120         for node in $(nodes_list); do
15121                 nid=$(host_nids_address $node $NETTYPE)
15122                 if [[ $nid = *-* ]] ; then
15123                         echo "lctl ping $(h2nettype $nid)"
15124                         lctl ping $(h2nettype $nid)
15125                 else
15126                         echo "skipping $node (no hyphen detected)"
15127                 fi
15128         done
15129 }
15130 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
15131
15132 test_218() {
15133        # do directio so as not to populate the page cache
15134        log "creating a 10 Mb file"
15135        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15136        log "starting reads"
15137        dd if=$DIR/$tfile of=/dev/null bs=4096 &
15138        log "truncating the file"
15139        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15140        log "killing dd"
15141        kill %+ || true # reads might have finished
15142        echo "wait until dd is finished"
15143        wait
15144        log "removing the temporary file"
15145        rm -rf $DIR/$tfile || error "tmp file removal failed"
15146 }
15147 run_test 218 "parallel read and truncate should not deadlock"
15148
15149 test_219() {
15150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15151
15152         # write one partial page
15153         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
15154         # set no grant so vvp_io_commit_write will do sync write
15155         $LCTL set_param fail_loc=0x411
15156         # write a full page at the end of file
15157         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
15158
15159         $LCTL set_param fail_loc=0
15160         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
15161         $LCTL set_param fail_loc=0x411
15162         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
15163
15164         # LU-4201
15165         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
15166         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
15167 }
15168 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
15169
15170 test_220() { #LU-325
15171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15172         remote_ost_nodsh && skip "remote OST with nodsh"
15173         remote_mds_nodsh && skip "remote MDS with nodsh"
15174         remote_mgs_nodsh && skip "remote MGS with nodsh"
15175
15176         local OSTIDX=0
15177
15178         # create on MDT0000 so the last_id and next_id are correct
15179         mkdir $DIR/$tdir
15180         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
15181         OST=${OST%_UUID}
15182
15183         # on the mdt's osc
15184         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
15185         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
15186                         osp.$mdtosc_proc1.prealloc_last_id)
15187         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
15188                         osp.$mdtosc_proc1.prealloc_next_id)
15189
15190         $LFS df -i
15191
15192         if ! combined_mgs_mds ; then
15193                 mount_mgs_client
15194         fi
15195
15196         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
15197         #define OBD_FAIL_OST_ENOINO              0x229
15198         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
15199         create_pool $FSNAME.$TESTNAME || return 1
15200         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
15201
15202         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
15203
15204         MDSOBJS=$((last_id - next_id))
15205         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
15206
15207         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
15208         echo "OST still has $count kbytes free"
15209
15210         echo "create $MDSOBJS files @next_id..."
15211         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
15212
15213         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15214                         osp.$mdtosc_proc1.prealloc_last_id)
15215         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15216                         osp.$mdtosc_proc1.prealloc_next_id)
15217
15218         echo "after creation, last_id=$last_id2, next_id=$next_id2"
15219         $LFS df -i
15220
15221         echo "cleanup..."
15222
15223         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
15224         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
15225
15226         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
15227                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
15228         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
15229                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
15230         echo "unlink $MDSOBJS files @$next_id..."
15231         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
15232
15233         if ! combined_mgs_mds ; then
15234                 umount_mgs_client
15235         fi
15236 }
15237 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
15238
15239 test_221() {
15240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15241
15242         dd if=`which date` of=$MOUNT/date oflag=sync
15243         chmod +x $MOUNT/date
15244
15245         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
15246         $LCTL set_param fail_loc=0x80001401
15247
15248         $MOUNT/date > /dev/null
15249         rm -f $MOUNT/date
15250 }
15251 run_test 221 "make sure fault and truncate race to not cause OOM"
15252
15253 test_222a () {
15254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15255
15256         rm -rf $DIR/$tdir
15257         test_mkdir $DIR/$tdir
15258         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15259         createmany -o $DIR/$tdir/$tfile 10
15260         cancel_lru_locks mdc
15261         cancel_lru_locks osc
15262         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15263         $LCTL set_param fail_loc=0x31a
15264         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
15265         $LCTL set_param fail_loc=0
15266         rm -r $DIR/$tdir
15267 }
15268 run_test 222a "AGL for ls should not trigger CLIO lock failure"
15269
15270 test_222b () {
15271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15272
15273         rm -rf $DIR/$tdir
15274         test_mkdir $DIR/$tdir
15275         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15276         createmany -o $DIR/$tdir/$tfile 10
15277         cancel_lru_locks mdc
15278         cancel_lru_locks osc
15279         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15280         $LCTL set_param fail_loc=0x31a
15281         rm -r $DIR/$tdir || error "AGL for rmdir failed"
15282         $LCTL set_param fail_loc=0
15283 }
15284 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
15285
15286 test_223 () {
15287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15288
15289         rm -rf $DIR/$tdir
15290         test_mkdir $DIR/$tdir
15291         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15292         createmany -o $DIR/$tdir/$tfile 10
15293         cancel_lru_locks mdc
15294         cancel_lru_locks osc
15295         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
15296         $LCTL set_param fail_loc=0x31b
15297         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
15298         $LCTL set_param fail_loc=0
15299         rm -r $DIR/$tdir
15300 }
15301 run_test 223 "osc reenqueue if without AGL lock granted ======================="
15302
15303 test_224a() { # LU-1039, MRP-303
15304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15305
15306         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
15307         $LCTL set_param fail_loc=0x508
15308         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
15309         $LCTL set_param fail_loc=0
15310         df $DIR
15311 }
15312 run_test 224a "Don't panic on bulk IO failure"
15313
15314 test_224b() { # LU-1039, MRP-303
15315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15316
15317         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
15318         cancel_lru_locks osc
15319         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
15320         $LCTL set_param fail_loc=0x515
15321         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
15322         $LCTL set_param fail_loc=0
15323         df $DIR
15324 }
15325 run_test 224b "Don't panic on bulk IO failure"
15326
15327 test_224c() { # LU-6441
15328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15329         remote_mds_nodsh && skip "remote MDS with nodsh"
15330
15331         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15332         save_writethrough $p
15333         set_cache writethrough on
15334
15335         local pages_per_rpc=$($LCTL get_param \
15336                                 osc.*.max_pages_per_rpc)
15337         local at_max=$($LCTL get_param -n at_max)
15338         local timeout=$($LCTL get_param -n timeout)
15339         local test_at="at_max"
15340         local param_at="$FSNAME.sys.at_max"
15341         local test_timeout="timeout"
15342         local param_timeout="$FSNAME.sys.timeout"
15343
15344         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
15345
15346         set_persistent_param_and_check client "$test_at" "$param_at" 0
15347         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
15348
15349         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
15350         do_facet ost1 "$LCTL set_param fail_loc=0x520"
15351         $LFS setstripe -c 1 -i 0 $DIR/$tfile
15352         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
15353         sync
15354         do_facet ost1 "$LCTL set_param fail_loc=0"
15355
15356         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
15357         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
15358                 $timeout
15359
15360         $LCTL set_param -n $pages_per_rpc
15361         restore_lustre_params < $p
15362         rm -f $p
15363 }
15364 run_test 224c "Don't hang if one of md lost during large bulk RPC"
15365
15366 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
15367 test_225a () {
15368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15369         if [ -z ${MDSSURVEY} ]; then
15370                 skip_env "mds-survey not found"
15371         fi
15372         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15373                 skip "Need MDS version at least 2.2.51"
15374
15375         local mds=$(facet_host $SINGLEMDS)
15376         local target=$(do_nodes $mds 'lctl dl' |
15377                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15378
15379         local cmd1="file_count=1000 thrhi=4"
15380         local cmd2="dir_count=2 layer=mdd stripe_count=0"
15381         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15382         local cmd="$cmd1 $cmd2 $cmd3"
15383
15384         rm -f ${TMP}/mds_survey*
15385         echo + $cmd
15386         eval $cmd || error "mds-survey with zero-stripe failed"
15387         cat ${TMP}/mds_survey*
15388         rm -f ${TMP}/mds_survey*
15389 }
15390 run_test 225a "Metadata survey sanity with zero-stripe"
15391
15392 test_225b () {
15393         if [ -z ${MDSSURVEY} ]; then
15394                 skip_env "mds-survey not found"
15395         fi
15396         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15397                 skip "Need MDS version at least 2.2.51"
15398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15399         remote_mds_nodsh && skip "remote MDS with nodsh"
15400         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
15401                 skip_env "Need to mount OST to test"
15402         fi
15403
15404         local mds=$(facet_host $SINGLEMDS)
15405         local target=$(do_nodes $mds 'lctl dl' |
15406                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15407
15408         local cmd1="file_count=1000 thrhi=4"
15409         local cmd2="dir_count=2 layer=mdd stripe_count=1"
15410         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15411         local cmd="$cmd1 $cmd2 $cmd3"
15412
15413         rm -f ${TMP}/mds_survey*
15414         echo + $cmd
15415         eval $cmd || error "mds-survey with stripe_count failed"
15416         cat ${TMP}/mds_survey*
15417         rm -f ${TMP}/mds_survey*
15418 }
15419 run_test 225b "Metadata survey sanity with stripe_count = 1"
15420
15421 mcreate_path2fid () {
15422         local mode=$1
15423         local major=$2
15424         local minor=$3
15425         local name=$4
15426         local desc=$5
15427         local path=$DIR/$tdir/$name
15428         local fid
15429         local rc
15430         local fid_path
15431
15432         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
15433                 error "cannot create $desc"
15434
15435         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
15436         rc=$?
15437         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
15438
15439         fid_path=$($LFS fid2path $MOUNT $fid)
15440         rc=$?
15441         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
15442
15443         [ "$path" == "$fid_path" ] ||
15444                 error "fid2path returned $fid_path, expected $path"
15445
15446         echo "pass with $path and $fid"
15447 }
15448
15449 test_226a () {
15450         rm -rf $DIR/$tdir
15451         mkdir -p $DIR/$tdir
15452
15453         mcreate_path2fid 0010666 0 0 fifo "FIFO"
15454         mcreate_path2fid 0020666 1 3 null "character special file (null)"
15455         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
15456         mcreate_path2fid 0040666 0 0 dir "directory"
15457         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
15458         mcreate_path2fid 0100666 0 0 file "regular file"
15459         mcreate_path2fid 0120666 0 0 link "symbolic link"
15460         mcreate_path2fid 0140666 0 0 sock "socket"
15461 }
15462 run_test 226a "call path2fid and fid2path on files of all type"
15463
15464 test_226b () {
15465         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15466
15467         local MDTIDX=1
15468
15469         rm -rf $DIR/$tdir
15470         mkdir -p $DIR/$tdir
15471         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
15472                 error "create remote directory failed"
15473         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
15474         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
15475                                 "character special file (null)"
15476         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
15477                                 "character special file (no device)"
15478         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
15479         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
15480                                 "block special file (loop)"
15481         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
15482         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
15483         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
15484 }
15485 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
15486
15487 # LU-1299 Executing or running ldd on a truncated executable does not
15488 # cause an out-of-memory condition.
15489 test_227() {
15490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15491         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
15492
15493         dd if=$(which date) of=$MOUNT/date bs=1k count=1
15494         chmod +x $MOUNT/date
15495
15496         $MOUNT/date > /dev/null
15497         ldd $MOUNT/date > /dev/null
15498         rm -f $MOUNT/date
15499 }
15500 run_test 227 "running truncated executable does not cause OOM"
15501
15502 # LU-1512 try to reuse idle OI blocks
15503 test_228a() {
15504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15505         remote_mds_nodsh && skip "remote MDS with nodsh"
15506         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15507
15508         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15509         local myDIR=$DIR/$tdir
15510
15511         mkdir -p $myDIR
15512         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15513         $LCTL set_param fail_loc=0x80001002
15514         createmany -o $myDIR/t- 10000
15515         $LCTL set_param fail_loc=0
15516         # The guard is current the largest FID holder
15517         touch $myDIR/guard
15518         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15519                     tr -d '[')
15520         local IDX=$(($SEQ % 64))
15521
15522         do_facet $SINGLEMDS sync
15523         # Make sure journal flushed.
15524         sleep 6
15525         local blk1=$(do_facet $SINGLEMDS \
15526                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15527                      grep Blockcount | awk '{print $4}')
15528
15529         # Remove old files, some OI blocks will become idle.
15530         unlinkmany $myDIR/t- 10000
15531         # Create new files, idle OI blocks should be reused.
15532         createmany -o $myDIR/t- 2000
15533         do_facet $SINGLEMDS sync
15534         # Make sure journal flushed.
15535         sleep 6
15536         local blk2=$(do_facet $SINGLEMDS \
15537                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15538                      grep Blockcount | awk '{print $4}')
15539
15540         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15541 }
15542 run_test 228a "try to reuse idle OI blocks"
15543
15544 test_228b() {
15545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15546         remote_mds_nodsh && skip "remote MDS with nodsh"
15547         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15548
15549         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15550         local myDIR=$DIR/$tdir
15551
15552         mkdir -p $myDIR
15553         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15554         $LCTL set_param fail_loc=0x80001002
15555         createmany -o $myDIR/t- 10000
15556         $LCTL set_param fail_loc=0
15557         # The guard is current the largest FID holder
15558         touch $myDIR/guard
15559         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15560                     tr -d '[')
15561         local IDX=$(($SEQ % 64))
15562
15563         do_facet $SINGLEMDS sync
15564         # Make sure journal flushed.
15565         sleep 6
15566         local blk1=$(do_facet $SINGLEMDS \
15567                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15568                      grep Blockcount | awk '{print $4}')
15569
15570         # Remove old files, some OI blocks will become idle.
15571         unlinkmany $myDIR/t- 10000
15572
15573         # stop the MDT
15574         stop $SINGLEMDS || error "Fail to stop MDT."
15575         # remount the MDT
15576         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15577
15578         df $MOUNT || error "Fail to df."
15579         # Create new files, idle OI blocks should be reused.
15580         createmany -o $myDIR/t- 2000
15581         do_facet $SINGLEMDS sync
15582         # Make sure journal flushed.
15583         sleep 6
15584         local blk2=$(do_facet $SINGLEMDS \
15585                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15586                      grep Blockcount | awk '{print $4}')
15587
15588         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15589 }
15590 run_test 228b "idle OI blocks can be reused after MDT restart"
15591
15592 #LU-1881
15593 test_228c() {
15594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15595         remote_mds_nodsh && skip "remote MDS with nodsh"
15596         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15597
15598         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15599         local myDIR=$DIR/$tdir
15600
15601         mkdir -p $myDIR
15602         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15603         $LCTL set_param fail_loc=0x80001002
15604         # 20000 files can guarantee there are index nodes in the OI file
15605         createmany -o $myDIR/t- 20000
15606         $LCTL set_param fail_loc=0
15607         # The guard is current the largest FID holder
15608         touch $myDIR/guard
15609         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15610                     tr -d '[')
15611         local IDX=$(($SEQ % 64))
15612
15613         do_facet $SINGLEMDS sync
15614         # Make sure journal flushed.
15615         sleep 6
15616         local blk1=$(do_facet $SINGLEMDS \
15617                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15618                      grep Blockcount | awk '{print $4}')
15619
15620         # Remove old files, some OI blocks will become idle.
15621         unlinkmany $myDIR/t- 20000
15622         rm -f $myDIR/guard
15623         # The OI file should become empty now
15624
15625         # Create new files, idle OI blocks should be reused.
15626         createmany -o $myDIR/t- 2000
15627         do_facet $SINGLEMDS sync
15628         # Make sure journal flushed.
15629         sleep 6
15630         local blk2=$(do_facet $SINGLEMDS \
15631                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15632                      grep Blockcount | awk '{print $4}')
15633
15634         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15635 }
15636 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15637
15638 test_229() { # LU-2482, LU-3448
15639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15640         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15641         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15642                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15643
15644         rm -f $DIR/$tfile
15645
15646         # Create a file with a released layout and stripe count 2.
15647         $MULTIOP $DIR/$tfile H2c ||
15648                 error "failed to create file with released layout"
15649
15650         $LFS getstripe -v $DIR/$tfile
15651
15652         local pattern=$($LFS getstripe -L $DIR/$tfile)
15653         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15654
15655         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15656                 error "getstripe"
15657         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15658         stat $DIR/$tfile || error "failed to stat released file"
15659
15660         chown $RUNAS_ID $DIR/$tfile ||
15661                 error "chown $RUNAS_ID $DIR/$tfile failed"
15662
15663         chgrp $RUNAS_ID $DIR/$tfile ||
15664                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15665
15666         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15667         rm $DIR/$tfile || error "failed to remove released file"
15668 }
15669 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15670
15671 test_230a() {
15672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15673         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15674         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15675                 skip "Need MDS version at least 2.11.52"
15676
15677         local MDTIDX=1
15678
15679         test_mkdir $DIR/$tdir
15680         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15681         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15682         [ $mdt_idx -ne 0 ] &&
15683                 error "create local directory on wrong MDT $mdt_idx"
15684
15685         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15686                         error "create remote directory failed"
15687         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15688         [ $mdt_idx -ne $MDTIDX ] &&
15689                 error "create remote directory on wrong MDT $mdt_idx"
15690
15691         createmany -o $DIR/$tdir/test_230/t- 10 ||
15692                 error "create files on remote directory failed"
15693         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15694         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15695         rm -r $DIR/$tdir || error "unlink remote directory failed"
15696 }
15697 run_test 230a "Create remote directory and files under the remote directory"
15698
15699 test_230b() {
15700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15701         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15702         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15703                 skip "Need MDS version at least 2.11.52"
15704
15705         local MDTIDX=1
15706         local mdt_index
15707         local i
15708         local file
15709         local pid
15710         local stripe_count
15711         local migrate_dir=$DIR/$tdir/migrate_dir
15712         local other_dir=$DIR/$tdir/other_dir
15713
15714         test_mkdir $DIR/$tdir
15715         test_mkdir -i0 -c1 $migrate_dir
15716         test_mkdir -i0 -c1 $other_dir
15717         for ((i=0; i<10; i++)); do
15718                 mkdir -p $migrate_dir/dir_${i}
15719                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15720                         error "create files under remote dir failed $i"
15721         done
15722
15723         cp /etc/passwd $migrate_dir/$tfile
15724         cp /etc/passwd $other_dir/$tfile
15725         chattr +SAD $migrate_dir
15726         chattr +SAD $migrate_dir/$tfile
15727
15728         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15729         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15730         local old_dir_mode=$(stat -c%f $migrate_dir)
15731         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15732
15733         mkdir -p $migrate_dir/dir_default_stripe2
15734         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15735         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15736
15737         mkdir -p $other_dir
15738         ln $migrate_dir/$tfile $other_dir/luna
15739         ln $migrate_dir/$tfile $migrate_dir/sofia
15740         ln $other_dir/$tfile $migrate_dir/david
15741         ln -s $migrate_dir/$tfile $other_dir/zachary
15742         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15743         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15744
15745         $LFS migrate -m $MDTIDX $migrate_dir ||
15746                 error "fails on migrating remote dir to MDT1"
15747
15748         echo "migratate to MDT1, then checking.."
15749         for ((i = 0; i < 10; i++)); do
15750                 for file in $(find $migrate_dir/dir_${i}); do
15751                         mdt_index=$($LFS getstripe -m $file)
15752                         [ $mdt_index == $MDTIDX ] ||
15753                                 error "$file is not on MDT${MDTIDX}"
15754                 done
15755         done
15756
15757         # the multiple link file should still in MDT0
15758         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15759         [ $mdt_index == 0 ] ||
15760                 error "$file is not on MDT${MDTIDX}"
15761
15762         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15763         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15764                 error " expect $old_dir_flag get $new_dir_flag"
15765
15766         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15767         [ "$old_file_flag" = "$new_file_flag" ] ||
15768                 error " expect $old_file_flag get $new_file_flag"
15769
15770         local new_dir_mode=$(stat -c%f $migrate_dir)
15771         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15772                 error "expect mode $old_dir_mode get $new_dir_mode"
15773
15774         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15775         [ "$old_file_mode" = "$new_file_mode" ] ||
15776                 error "expect mode $old_file_mode get $new_file_mode"
15777
15778         diff /etc/passwd $migrate_dir/$tfile ||
15779                 error "$tfile different after migration"
15780
15781         diff /etc/passwd $other_dir/luna ||
15782                 error "luna different after migration"
15783
15784         diff /etc/passwd $migrate_dir/sofia ||
15785                 error "sofia different after migration"
15786
15787         diff /etc/passwd $migrate_dir/david ||
15788                 error "david different after migration"
15789
15790         diff /etc/passwd $other_dir/zachary ||
15791                 error "zachary different after migration"
15792
15793         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15794                 error "${tfile}_ln different after migration"
15795
15796         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15797                 error "${tfile}_ln_other different after migration"
15798
15799         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15800         [ $stripe_count = 2 ] ||
15801                 error "dir strpe_count $d != 2 after migration."
15802
15803         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15804         [ $stripe_count = 2 ] ||
15805                 error "file strpe_count $d != 2 after migration."
15806
15807         #migrate back to MDT0
15808         MDTIDX=0
15809
15810         $LFS migrate -m $MDTIDX $migrate_dir ||
15811                 error "fails on migrating remote dir to MDT0"
15812
15813         echo "migrate back to MDT0, checking.."
15814         for file in $(find $migrate_dir); do
15815                 mdt_index=$($LFS getstripe -m $file)
15816                 [ $mdt_index == $MDTIDX ] ||
15817                         error "$file is not on MDT${MDTIDX}"
15818         done
15819
15820         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15821         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15822                 error " expect $old_dir_flag get $new_dir_flag"
15823
15824         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15825         [ "$old_file_flag" = "$new_file_flag" ] ||
15826                 error " expect $old_file_flag get $new_file_flag"
15827
15828         local new_dir_mode=$(stat -c%f $migrate_dir)
15829         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15830                 error "expect mode $old_dir_mode get $new_dir_mode"
15831
15832         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15833         [ "$old_file_mode" = "$new_file_mode" ] ||
15834                 error "expect mode $old_file_mode get $new_file_mode"
15835
15836         diff /etc/passwd ${migrate_dir}/$tfile ||
15837                 error "$tfile different after migration"
15838
15839         diff /etc/passwd ${other_dir}/luna ||
15840                 error "luna different after migration"
15841
15842         diff /etc/passwd ${migrate_dir}/sofia ||
15843                 error "sofia different after migration"
15844
15845         diff /etc/passwd ${other_dir}/zachary ||
15846                 error "zachary different after migration"
15847
15848         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15849                 error "${tfile}_ln different after migration"
15850
15851         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15852                 error "${tfile}_ln_other different after migration"
15853
15854         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
15855         [ $stripe_count = 2 ] ||
15856                 error "dir strpe_count $d != 2 after migration."
15857
15858         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
15859         [ $stripe_count = 2 ] ||
15860                 error "file strpe_count $d != 2 after migration."
15861
15862         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15863 }
15864 run_test 230b "migrate directory"
15865
15866 test_230c() {
15867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15868         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15869         remote_mds_nodsh && skip "remote MDS with nodsh"
15870         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15871                 skip "Need MDS version at least 2.11.52"
15872
15873         local MDTIDX=1
15874         local total=3
15875         local mdt_index
15876         local file
15877         local migrate_dir=$DIR/$tdir/migrate_dir
15878
15879         #If migrating directory fails in the middle, all entries of
15880         #the directory is still accessiable.
15881         test_mkdir $DIR/$tdir
15882         test_mkdir -i0 -c1 $migrate_dir
15883         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
15884         stat $migrate_dir
15885         createmany -o $migrate_dir/f $total ||
15886                 error "create files under ${migrate_dir} failed"
15887
15888         # fail after migrating top dir, and this will fail only once, so the
15889         # first sub file migration will fail (currently f3), others succeed.
15890         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
15891         do_facet mds1 lctl set_param fail_loc=0x1801
15892         local t=$(ls $migrate_dir | wc -l)
15893         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
15894                 error "migrate should fail"
15895         local u=$(ls $migrate_dir | wc -l)
15896         [ "$u" == "$t" ] || error "$u != $t during migration"
15897
15898         # add new dir/file should succeed
15899         mkdir $migrate_dir/dir ||
15900                 error "mkdir failed under migrating directory"
15901         touch $migrate_dir/file ||
15902                 error "create file failed under migrating directory"
15903
15904         # add file with existing name should fail
15905         for file in $migrate_dir/f*; do
15906                 stat $file > /dev/null || error "stat $file failed"
15907                 $OPENFILE -f O_CREAT:O_EXCL $file &&
15908                         error "open(O_CREAT|O_EXCL) $file should fail"
15909                 $MULTIOP $file m && error "create $file should fail"
15910                 touch $DIR/$tdir/remote_dir/$tfile ||
15911                         error "touch $tfile failed"
15912                 ln $DIR/$tdir/remote_dir/$tfile $file &&
15913                         error "link $file should fail"
15914                 mdt_index=$($LFS getstripe -m $file)
15915                 if [ $mdt_index == 0 ]; then
15916                         # file failed to migrate is not allowed to rename to
15917                         mv $DIR/$tdir/remote_dir/$tfile $file &&
15918                                 error "rename to $file should fail"
15919                 else
15920                         mv $DIR/$tdir/remote_dir/$tfile $file ||
15921                                 error "rename to $file failed"
15922                 fi
15923                 echo hello >> $file || error "write $file failed"
15924         done
15925
15926         # resume migration with different options should fail
15927         $LFS migrate -m 0 $migrate_dir &&
15928                 error "migrate -m 0 $migrate_dir should fail"
15929
15930         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
15931                 error "migrate -c 2 $migrate_dir should fail"
15932
15933         # resume migration should succeed
15934         $LFS migrate -m $MDTIDX $migrate_dir ||
15935                 error "migrate $migrate_dir failed"
15936
15937         echo "Finish migration, then checking.."
15938         for file in $(find $migrate_dir); do
15939                 mdt_index=$($LFS getstripe -m $file)
15940                 [ $mdt_index == $MDTIDX ] ||
15941                         error "$file is not on MDT${MDTIDX}"
15942         done
15943
15944         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15945 }
15946 run_test 230c "check directory accessiblity if migration failed"
15947
15948 test_230d() {
15949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15950         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15951         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15952                 skip "Need MDS version at least 2.11.52"
15953         # LU-11235
15954         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
15955
15956         local migrate_dir=$DIR/$tdir/migrate_dir
15957         local old_index
15958         local new_index
15959         local old_count
15960         local new_count
15961         local new_hash
15962         local mdt_index
15963         local i
15964         local j
15965
15966         old_index=$((RANDOM % MDSCOUNT))
15967         old_count=$((MDSCOUNT - old_index))
15968         new_index=$((RANDOM % MDSCOUNT))
15969         new_count=$((MDSCOUNT - new_index))
15970         new_hash="all_char"
15971
15972         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
15973         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
15974
15975         test_mkdir $DIR/$tdir
15976         test_mkdir -i $old_index -c $old_count $migrate_dir
15977
15978         for ((i=0; i<100; i++)); do
15979                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
15980                 createmany -o $migrate_dir/dir_${i}/f 100 ||
15981                         error "create files under remote dir failed $i"
15982         done
15983
15984         echo -n "Migrate from MDT$old_index "
15985         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
15986         echo -n "to MDT$new_index"
15987         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
15988         echo
15989
15990         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
15991         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
15992                 error "migrate remote dir error"
15993
15994         echo "Finish migration, then checking.."
15995         for file in $(find $migrate_dir); do
15996                 mdt_index=$($LFS getstripe -m $file)
15997                 if [ $mdt_index -lt $new_index ] ||
15998                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
15999                         error "$file is on MDT$mdt_index"
16000                 fi
16001         done
16002
16003         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16004 }
16005 run_test 230d "check migrate big directory"
16006
16007 test_230e() {
16008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16009         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16010         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16011                 skip "Need MDS version at least 2.11.52"
16012
16013         local i
16014         local j
16015         local a_fid
16016         local b_fid
16017
16018         mkdir -p $DIR/$tdir
16019         mkdir $DIR/$tdir/migrate_dir
16020         mkdir $DIR/$tdir/other_dir
16021         touch $DIR/$tdir/migrate_dir/a
16022         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
16023         ls $DIR/$tdir/other_dir
16024
16025         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16026                 error "migrate dir fails"
16027
16028         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16029         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16030
16031         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16032         [ $mdt_index == 0 ] || error "a is not on MDT0"
16033
16034         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
16035                 error "migrate dir fails"
16036
16037         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
16038         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
16039
16040         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16041         [ $mdt_index == 1 ] || error "a is not on MDT1"
16042
16043         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
16044         [ $mdt_index == 1 ] || error "b is not on MDT1"
16045
16046         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16047         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
16048
16049         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
16050
16051         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16052 }
16053 run_test 230e "migrate mulitple local link files"
16054
16055 test_230f() {
16056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16057         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16058         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16059                 skip "Need MDS version at least 2.11.52"
16060
16061         local a_fid
16062         local ln_fid
16063
16064         mkdir -p $DIR/$tdir
16065         mkdir $DIR/$tdir/migrate_dir
16066         $LFS mkdir -i1 $DIR/$tdir/other_dir
16067         touch $DIR/$tdir/migrate_dir/a
16068         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
16069         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
16070         ls $DIR/$tdir/other_dir
16071
16072         # a should be migrated to MDT1, since no other links on MDT0
16073         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16074                 error "#1 migrate dir fails"
16075         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16076         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16077         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16078         [ $mdt_index == 1 ] || error "a is not on MDT1"
16079
16080         # a should stay on MDT1, because it is a mulitple link file
16081         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16082                 error "#2 migrate dir fails"
16083         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16084         [ $mdt_index == 1 ] || error "a is not on MDT1"
16085
16086         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16087                 error "#3 migrate dir fails"
16088
16089         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16090         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
16091         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
16092
16093         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
16094         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
16095
16096         # a should be migrated to MDT0, since no other links on MDT1
16097         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16098                 error "#4 migrate dir fails"
16099         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16100         [ $mdt_index == 0 ] || error "a is not on MDT0"
16101
16102         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16103 }
16104 run_test 230f "migrate mulitple remote link files"
16105
16106 test_230g() {
16107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16108         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16109         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16110                 skip "Need MDS version at least 2.11.52"
16111
16112         mkdir -p $DIR/$tdir/migrate_dir
16113
16114         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
16115                 error "migrating dir to non-exist MDT succeeds"
16116         true
16117 }
16118 run_test 230g "migrate dir to non-exist MDT"
16119
16120 test_230h() {
16121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16122         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16123         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16124                 skip "Need MDS version at least 2.11.52"
16125
16126         local mdt_index
16127
16128         mkdir -p $DIR/$tdir/migrate_dir
16129
16130         $LFS migrate -m1 $DIR &&
16131                 error "migrating mountpoint1 should fail"
16132
16133         $LFS migrate -m1 $DIR/$tdir/.. &&
16134                 error "migrating mountpoint2 should fail"
16135
16136         # same as mv
16137         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
16138                 error "migrating $tdir/migrate_dir/.. should fail"
16139
16140         true
16141 }
16142 run_test 230h "migrate .. and root"
16143
16144 test_230i() {
16145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16146         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16147         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16148                 skip "Need MDS version at least 2.11.52"
16149
16150         mkdir -p $DIR/$tdir/migrate_dir
16151
16152         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
16153                 error "migration fails with a tailing slash"
16154
16155         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
16156                 error "migration fails with two tailing slashes"
16157 }
16158 run_test 230i "lfs migrate -m tolerates trailing slashes"
16159
16160 test_230j() {
16161         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16162         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16163                 skip "Need MDS version at least 2.11.52"
16164
16165         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
16166         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
16167                 error "create $tfile failed"
16168         cat /etc/passwd > $DIR/$tdir/$tfile
16169
16170         $LFS migrate -m 1 $DIR/$tdir
16171
16172         cmp /etc/passwd $DIR/$tdir/$tfile ||
16173                 error "DoM file mismatch after migration"
16174 }
16175 run_test 230j "DoM file data not changed after dir migration"
16176
16177 test_230k() {
16178         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
16179         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16180                 skip "Need MDS version at least 2.11.56"
16181
16182         local total=20
16183         local files_on_starting_mdt=0
16184
16185         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
16186         $LFS getdirstripe $DIR/$tdir
16187         for i in $(seq $total); do
16188                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
16189                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16190                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16191         done
16192
16193         echo "$files_on_starting_mdt files on MDT0"
16194
16195         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
16196         $LFS getdirstripe $DIR/$tdir
16197
16198         files_on_starting_mdt=0
16199         for i in $(seq $total); do
16200                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16201                         error "file $tfile.$i mismatch after migration"
16202                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
16203                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16204         done
16205
16206         echo "$files_on_starting_mdt files on MDT1 after migration"
16207         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
16208
16209         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
16210         $LFS getdirstripe $DIR/$tdir
16211
16212         files_on_starting_mdt=0
16213         for i in $(seq $total); do
16214                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16215                         error "file $tfile.$i mismatch after 2nd migration"
16216                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16217                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16218         done
16219
16220         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
16221         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
16222
16223         true
16224 }
16225 run_test 230k "file data not changed after dir migration"
16226
16227 test_230l() {
16228         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16229         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16230                 skip "Need MDS version at least 2.11.56"
16231
16232         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
16233         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
16234                 error "create files under remote dir failed $i"
16235         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
16236 }
16237 run_test 230l "readdir between MDTs won't crash"
16238
16239 test_231a()
16240 {
16241         # For simplicity this test assumes that max_pages_per_rpc
16242         # is the same across all OSCs
16243         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
16244         local bulk_size=$((max_pages * PAGE_SIZE))
16245         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
16246                                        head -n 1)
16247
16248         mkdir -p $DIR/$tdir
16249         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
16250                 error "failed to set stripe with -S ${brw_size}M option"
16251
16252         # clear the OSC stats
16253         $LCTL set_param osc.*.stats=0 &>/dev/null
16254         stop_writeback
16255
16256         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
16257         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
16258                 oflag=direct &>/dev/null || error "dd failed"
16259
16260         sync; sleep 1; sync # just to be safe
16261         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
16262         if [ x$nrpcs != "x1" ]; then
16263                 $LCTL get_param osc.*.stats
16264                 error "found $nrpcs ost_write RPCs, not 1 as expected"
16265         fi
16266
16267         start_writeback
16268         # Drop the OSC cache, otherwise we will read from it
16269         cancel_lru_locks osc
16270
16271         # clear the OSC stats
16272         $LCTL set_param osc.*.stats=0 &>/dev/null
16273
16274         # Client reads $bulk_size.
16275         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
16276                 iflag=direct &>/dev/null || error "dd failed"
16277
16278         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
16279         if [ x$nrpcs != "x1" ]; then
16280                 $LCTL get_param osc.*.stats
16281                 error "found $nrpcs ost_read RPCs, not 1 as expected"
16282         fi
16283 }
16284 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
16285
16286 test_231b() {
16287         mkdir -p $DIR/$tdir
16288         local i
16289         for i in {0..1023}; do
16290                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
16291                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
16292                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
16293         done
16294         sync
16295 }
16296 run_test 231b "must not assert on fully utilized OST request buffer"
16297
16298 test_232a() {
16299         mkdir -p $DIR/$tdir
16300         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16301
16302         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16303         do_facet ost1 $LCTL set_param fail_loc=0x31c
16304
16305         # ignore dd failure
16306         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
16307
16308         do_facet ost1 $LCTL set_param fail_loc=0
16309         umount_client $MOUNT || error "umount failed"
16310         mount_client $MOUNT || error "mount failed"
16311         stop ost1 || error "cannot stop ost1"
16312         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16313 }
16314 run_test 232a "failed lock should not block umount"
16315
16316 test_232b() {
16317         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
16318                 skip "Need MDS version at least 2.10.58"
16319
16320         mkdir -p $DIR/$tdir
16321         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16322         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
16323         sync
16324         cancel_lru_locks osc
16325
16326         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16327         do_facet ost1 $LCTL set_param fail_loc=0x31c
16328
16329         # ignore failure
16330         $LFS data_version $DIR/$tdir/$tfile || true
16331
16332         do_facet ost1 $LCTL set_param fail_loc=0
16333         umount_client $MOUNT || error "umount failed"
16334         mount_client $MOUNT || error "mount failed"
16335         stop ost1 || error "cannot stop ost1"
16336         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16337 }
16338 run_test 232b "failed data version lock should not block umount"
16339
16340 test_233a() {
16341         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
16342                 skip "Need MDS version at least 2.3.64"
16343         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16344
16345         local fid=$($LFS path2fid $MOUNT)
16346
16347         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16348                 error "cannot access $MOUNT using its FID '$fid'"
16349 }
16350 run_test 233a "checking that OBF of the FS root succeeds"
16351
16352 test_233b() {
16353         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
16354                 skip "Need MDS version at least 2.5.90"
16355         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16356
16357         local fid=$($LFS path2fid $MOUNT/.lustre)
16358
16359         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16360                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
16361
16362         fid=$($LFS path2fid $MOUNT/.lustre/fid)
16363         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16364                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
16365 }
16366 run_test 233b "checking that OBF of the FS .lustre succeeds"
16367
16368 test_234() {
16369         local p="$TMP/sanityN-$TESTNAME.parameters"
16370         save_lustre_params client "llite.*.xattr_cache" > $p
16371         lctl set_param llite.*.xattr_cache 1 ||
16372                 skip_env "xattr cache is not supported"
16373
16374         mkdir -p $DIR/$tdir || error "mkdir failed"
16375         touch $DIR/$tdir/$tfile || error "touch failed"
16376         # OBD_FAIL_LLITE_XATTR_ENOMEM
16377         $LCTL set_param fail_loc=0x1405
16378         getfattr -n user.attr $DIR/$tdir/$tfile &&
16379                 error "getfattr should have failed with ENOMEM"
16380         $LCTL set_param fail_loc=0x0
16381         rm -rf $DIR/$tdir
16382
16383         restore_lustre_params < $p
16384         rm -f $p
16385 }
16386 run_test 234 "xattr cache should not crash on ENOMEM"
16387
16388 test_235() {
16389         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
16390                 skip "Need MDS version at least 2.4.52"
16391
16392         flock_deadlock $DIR/$tfile
16393         local RC=$?
16394         case $RC in
16395                 0)
16396                 ;;
16397                 124) error "process hangs on a deadlock"
16398                 ;;
16399                 *) error "error executing flock_deadlock $DIR/$tfile"
16400                 ;;
16401         esac
16402 }
16403 run_test 235 "LU-1715: flock deadlock detection does not work properly"
16404
16405 #LU-2935
16406 test_236() {
16407         check_swap_layouts_support
16408
16409         local ref1=/etc/passwd
16410         local ref2=/etc/group
16411         local file1=$DIR/$tdir/f1
16412         local file2=$DIR/$tdir/f2
16413
16414         test_mkdir -c1 $DIR/$tdir
16415         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
16416         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
16417         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
16418         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
16419         local fd=$(free_fd)
16420         local cmd="exec $fd<>$file2"
16421         eval $cmd
16422         rm $file2
16423         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
16424                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
16425         cmd="exec $fd>&-"
16426         eval $cmd
16427         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16428
16429         #cleanup
16430         rm -rf $DIR/$tdir
16431 }
16432 run_test 236 "Layout swap on open unlinked file"
16433
16434 # LU-4659 linkea consistency
16435 test_238() {
16436         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16437                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16438                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16439                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16440
16441         touch $DIR/$tfile
16442         ln $DIR/$tfile $DIR/$tfile.lnk
16443         touch $DIR/$tfile.new
16444         mv $DIR/$tfile.new $DIR/$tfile
16445         local fid1=$($LFS path2fid $DIR/$tfile)
16446         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
16447         local path1=$($LFS fid2path $FSNAME "$fid1")
16448         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
16449         local path2=$($LFS fid2path $FSNAME "$fid2")
16450         [ $tfile.lnk == $path2 ] ||
16451                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
16452         rm -f $DIR/$tfile*
16453 }
16454 run_test 238 "Verify linkea consistency"
16455
16456 test_239A() { # was test_239
16457         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
16458                 skip "Need MDS version at least 2.5.60"
16459
16460         local list=$(comma_list $(mdts_nodes))
16461
16462         mkdir -p $DIR/$tdir
16463         createmany -o $DIR/$tdir/f- 5000
16464         unlinkmany $DIR/$tdir/f- 5000
16465         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
16466                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
16467         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
16468                         osp.*MDT*.sync_in_flight" | calc_sum)
16469         [ "$changes" -eq 0 ] || error "$changes not synced"
16470 }
16471 run_test 239A "osp_sync test"
16472
16473 test_239a() { #LU-5297
16474         remote_mds_nodsh && skip "remote MDS with nodsh"
16475
16476         touch $DIR/$tfile
16477         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
16478         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
16479         chgrp $RUNAS_GID $DIR/$tfile
16480         wait_delete_completed
16481 }
16482 run_test 239a "process invalid osp sync record correctly"
16483
16484 test_239b() { #LU-5297
16485         remote_mds_nodsh && skip "remote MDS with nodsh"
16486
16487         touch $DIR/$tfile1
16488         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
16489         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
16490         chgrp $RUNAS_GID $DIR/$tfile1
16491         wait_delete_completed
16492         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16493         touch $DIR/$tfile2
16494         chgrp $RUNAS_GID $DIR/$tfile2
16495         wait_delete_completed
16496 }
16497 run_test 239b "process osp sync record with ENOMEM error correctly"
16498
16499 test_240() {
16500         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16501         remote_mds_nodsh && skip "remote MDS with nodsh"
16502
16503         mkdir -p $DIR/$tdir
16504
16505         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
16506                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
16507         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
16508                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
16509
16510         umount_client $MOUNT || error "umount failed"
16511         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
16512         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
16513         mount_client $MOUNT || error "failed to mount client"
16514
16515         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16516         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16517 }
16518 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16519
16520 test_241_bio() {
16521         local count=$1
16522         local bsize=$2
16523
16524         for LOOP in $(seq $count); do
16525                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16526                 cancel_lru_locks $OSC || true
16527         done
16528 }
16529
16530 test_241_dio() {
16531         local count=$1
16532         local bsize=$2
16533
16534         for LOOP in $(seq $1); do
16535                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16536                         2>/dev/null
16537         done
16538 }
16539
16540 test_241a() { # was test_241
16541         local bsize=$PAGE_SIZE
16542
16543         (( bsize < 40960 )) && bsize=40960
16544         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16545         ls -la $DIR/$tfile
16546         cancel_lru_locks $OSC
16547         test_241_bio 1000 $bsize &
16548         PID=$!
16549         test_241_dio 1000 $bsize
16550         wait $PID
16551 }
16552 run_test 241a "bio vs dio"
16553
16554 test_241b() {
16555         local bsize=$PAGE_SIZE
16556
16557         (( bsize < 40960 )) && bsize=40960
16558         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16559         ls -la $DIR/$tfile
16560         test_241_dio 1000 $bsize &
16561         PID=$!
16562         test_241_dio 1000 $bsize
16563         wait $PID
16564 }
16565 run_test 241b "dio vs dio"
16566
16567 test_242() {
16568         remote_mds_nodsh && skip "remote MDS with nodsh"
16569
16570         mkdir -p $DIR/$tdir
16571         touch $DIR/$tdir/$tfile
16572
16573         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16574         do_facet mds1 lctl set_param fail_loc=0x105
16575         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16576
16577         do_facet mds1 lctl set_param fail_loc=0
16578         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16579 }
16580 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16581
16582 test_243()
16583 {
16584         test_mkdir $DIR/$tdir
16585         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16586 }
16587 run_test 243 "various group lock tests"
16588
16589 test_244()
16590 {
16591         test_mkdir $DIR/$tdir
16592         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16593         sendfile_grouplock $DIR/$tdir/$tfile || \
16594                 error "sendfile+grouplock failed"
16595         rm -rf $DIR/$tdir
16596 }
16597 run_test 244 "sendfile with group lock tests"
16598
16599 test_245() {
16600         local flagname="multi_mod_rpcs"
16601         local connect_data_name="max_mod_rpcs"
16602         local out
16603
16604         # check if multiple modify RPCs flag is set
16605         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16606                 grep "connect_flags:")
16607         echo "$out"
16608
16609         echo "$out" | grep -qw $flagname
16610         if [ $? -ne 0 ]; then
16611                 echo "connect flag $flagname is not set"
16612                 return
16613         fi
16614
16615         # check if multiple modify RPCs data is set
16616         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16617         echo "$out"
16618
16619         echo "$out" | grep -qw $connect_data_name ||
16620                 error "import should have connect data $connect_data_name"
16621 }
16622 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16623
16624 test_246() { # LU-7371
16625         remote_ost_nodsh && skip "remote OST with nodsh"
16626         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16627                 skip "Need OST version >= 2.7.62"
16628
16629         do_facet ost1 $LCTL set_param fail_val=4095
16630 #define OBD_FAIL_OST_READ_SIZE          0x234
16631         do_facet ost1 $LCTL set_param fail_loc=0x234
16632         $LFS setstripe $DIR/$tfile -i 0 -c 1
16633         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16634         cancel_lru_locks $FSNAME-OST0000
16635         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16636 }
16637 run_test 246 "Read file of size 4095 should return right length"
16638
16639 cleanup_247() {
16640         local submount=$1
16641
16642         trap 0
16643         umount_client $submount
16644         rmdir $submount
16645 }
16646
16647 test_247a() {
16648         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16649                 grep -q subtree ||
16650                 skip_env "Fileset feature is not supported"
16651
16652         local submount=${MOUNT}_$tdir
16653
16654         mkdir $MOUNT/$tdir
16655         mkdir -p $submount || error "mkdir $submount failed"
16656         FILESET="$FILESET/$tdir" mount_client $submount ||
16657                 error "mount $submount failed"
16658         trap "cleanup_247 $submount" EXIT
16659         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16660         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16661                 error "read $MOUNT/$tdir/$tfile failed"
16662         cleanup_247 $submount
16663 }
16664 run_test 247a "mount subdir as fileset"
16665
16666 test_247b() {
16667         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16668                 skip_env "Fileset feature is not supported"
16669
16670         local submount=${MOUNT}_$tdir
16671
16672         rm -rf $MOUNT/$tdir
16673         mkdir -p $submount || error "mkdir $submount failed"
16674         SKIP_FILESET=1
16675         FILESET="$FILESET/$tdir" mount_client $submount &&
16676                 error "mount $submount should fail"
16677         rmdir $submount
16678 }
16679 run_test 247b "mount subdir that dose not exist"
16680
16681 test_247c() {
16682         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16683                 skip_env "Fileset feature is not supported"
16684
16685         local submount=${MOUNT}_$tdir
16686
16687         mkdir -p $MOUNT/$tdir/dir1
16688         mkdir -p $submount || error "mkdir $submount failed"
16689         trap "cleanup_247 $submount" EXIT
16690         FILESET="$FILESET/$tdir" mount_client $submount ||
16691                 error "mount $submount failed"
16692         local fid=$($LFS path2fid $MOUNT/)
16693         $LFS fid2path $submount $fid && error "fid2path should fail"
16694         cleanup_247 $submount
16695 }
16696 run_test 247c "running fid2path outside root"
16697
16698 test_247d() {
16699         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16700                 skip "Fileset feature is not supported"
16701
16702         local submount=${MOUNT}_$tdir
16703
16704         mkdir -p $MOUNT/$tdir/dir1
16705         mkdir -p $submount || error "mkdir $submount failed"
16706         FILESET="$FILESET/$tdir" mount_client $submount ||
16707                 error "mount $submount failed"
16708         trap "cleanup_247 $submount" EXIT
16709         local fid=$($LFS path2fid $submount/dir1)
16710         $LFS fid2path $submount $fid || error "fid2path should succeed"
16711         cleanup_247 $submount
16712 }
16713 run_test 247d "running fid2path inside root"
16714
16715 # LU-8037
16716 test_247e() {
16717         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16718                 grep -q subtree ||
16719                 skip "Fileset feature is not supported"
16720
16721         local submount=${MOUNT}_$tdir
16722
16723         mkdir $MOUNT/$tdir
16724         mkdir -p $submount || error "mkdir $submount failed"
16725         FILESET="$FILESET/.." mount_client $submount &&
16726                 error "mount $submount should fail"
16727         rmdir $submount
16728 }
16729 run_test 247e "mount .. as fileset"
16730
16731 test_248() {
16732         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16733         [ -z "$fast_read_sav" ] && skip "no fast read support"
16734
16735         # create a large file for fast read verification
16736         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16737
16738         # make sure the file is created correctly
16739         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16740                 { rm -f $DIR/$tfile; skip "file creation error"; }
16741
16742         echo "Test 1: verify that fast read is 4 times faster on cache read"
16743
16744         # small read with fast read enabled
16745         $LCTL set_param -n llite.*.fast_read=1
16746         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16747                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16748                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16749         # small read with fast read disabled
16750         $LCTL set_param -n llite.*.fast_read=0
16751         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16752                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16753                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16754
16755         # verify that fast read is 4 times faster for cache read
16756         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16757                 error_not_in_vm "fast read was not 4 times faster: " \
16758                            "$t_fast vs $t_slow"
16759
16760         echo "Test 2: verify the performance between big and small read"
16761         $LCTL set_param -n llite.*.fast_read=1
16762
16763         # 1k non-cache read
16764         cancel_lru_locks osc
16765         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16766                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16767                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16768
16769         # 1M non-cache read
16770         cancel_lru_locks osc
16771         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16772                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16773                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16774
16775         # verify that big IO is not 4 times faster than small IO
16776         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16777                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16778
16779         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16780         rm -f $DIR/$tfile
16781 }
16782 run_test 248 "fast read verification"
16783
16784 test_249() { # LU-7890
16785         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16786                 skip "Need at least version 2.8.54"
16787
16788         rm -f $DIR/$tfile
16789         $LFS setstripe -c 1 $DIR/$tfile
16790         # Offset 2T == 4k * 512M
16791         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16792                 error "dd to 2T offset failed"
16793 }
16794 run_test 249 "Write above 2T file size"
16795
16796 test_250() {
16797         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16798          && skip "no 16TB file size limit on ZFS"
16799
16800         $LFS setstripe -c 1 $DIR/$tfile
16801         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16802         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16803         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16804         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16805                 conv=notrunc,fsync && error "append succeeded"
16806         return 0
16807 }
16808 run_test 250 "Write above 16T limit"
16809
16810 test_251() {
16811         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16812
16813         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
16814         #Skip once - writing the first stripe will succeed
16815         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16816         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
16817                 error "short write happened"
16818
16819         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16820         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
16821                 error "short read happened"
16822
16823         rm -f $DIR/$tfile
16824 }
16825 run_test 251 "Handling short read and write correctly"
16826
16827 test_252() {
16828         remote_mds_nodsh && skip "remote MDS with nodsh"
16829         remote_ost_nodsh && skip "remote OST with nodsh"
16830         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
16831                 skip_env "ldiskfs only test"
16832         fi
16833
16834         local tgt
16835         local dev
16836         local out
16837         local uuid
16838         local num
16839         local gen
16840
16841         # check lr_reader on OST0000
16842         tgt=ost1
16843         dev=$(facet_device $tgt)
16844         out=$(do_facet $tgt $LR_READER $dev)
16845         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16846         echo "$out"
16847         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
16848         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
16849                 error "Invalid uuid returned by $LR_READER on target $tgt"
16850         echo -e "uuid returned by $LR_READER is '$uuid'\n"
16851
16852         # check lr_reader -c on MDT0000
16853         tgt=mds1
16854         dev=$(facet_device $tgt)
16855         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
16856                 skip "$LR_READER does not support additional options"
16857         fi
16858         out=$(do_facet $tgt $LR_READER -c $dev)
16859         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16860         echo "$out"
16861         num=$(echo "$out" | grep -c "mdtlov")
16862         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
16863                 error "Invalid number of mdtlov clients returned by $LR_READER"
16864         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
16865
16866         # check lr_reader -cr on MDT0000
16867         out=$(do_facet $tgt $LR_READER -cr $dev)
16868         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16869         echo "$out"
16870         echo "$out" | grep -q "^reply_data:$" ||
16871                 error "$LR_READER should have returned 'reply_data' section"
16872         num=$(echo "$out" | grep -c "client_generation")
16873         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
16874 }
16875 run_test 252 "check lr_reader tool"
16876
16877 test_253_fill_ost() {
16878         local size_mb #how many MB should we write to pass watermark
16879         local lwm=$3  #low watermark
16880         local free_10mb #10% of free space
16881
16882         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16883         size_mb=$((free_kb / 1024 - lwm))
16884         free_10mb=$((free_kb / 10240))
16885         #If 10% of free space cross low watermark use it
16886         if (( free_10mb > size_mb )); then
16887                 size_mb=$free_10mb
16888         else
16889                 #At least we need to store 1.1 of difference between
16890                 #free space and low watermark
16891                 size_mb=$((size_mb + size_mb / 10))
16892         fi
16893         if (( lwm <= $((free_kb / 1024)) )) || [ ! -f $DIR/$tdir/1 ]; then
16894                 dd if=/dev/zero of=$DIR/$tdir/1 bs=1M count=$size_mb \
16895                          oflag=append conv=notrunc
16896         fi
16897
16898         sleep_maxage
16899
16900         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16901         echo "OST still has $((free_kb / 1024)) mbytes free"
16902 }
16903
16904 test_253() {
16905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16906         remote_mds_nodsh && skip "remote MDS with nodsh"
16907         remote_mgs_nodsh && skip "remote MGS with nodsh"
16908
16909         local ostidx=0
16910         local rc=0
16911
16912         local ost_name=$($LFS osts |
16913                 sed -n 's/^'$ostidx': \(.*\)_UUID .*/\1/p')
16914         # on the mdt's osc
16915         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
16916         do_facet $SINGLEMDS $LCTL get_param -n \
16917                 osp.$mdtosc_proc1.reserved_mb_high ||
16918                 skip  "remote MDS does not support reserved_mb_high"
16919
16920         rm -rf $DIR/$tdir
16921         wait_mds_ost_sync
16922         wait_delete_completed
16923         mkdir $DIR/$tdir
16924
16925         local last_wm_h=$(do_facet $SINGLEMDS $LCTL get_param -n \
16926                         osp.$mdtosc_proc1.reserved_mb_high)
16927         local last_wm_l=$(do_facet $SINGLEMDS $LCTL get_param -n \
16928                         osp.$mdtosc_proc1.reserved_mb_low)
16929         echo "prev high watermark $last_wm_h, prev low watermark $last_wm_l"
16930
16931         if ! combined_mgs_mds ; then
16932                 mount_mgs_client
16933         fi
16934         create_pool $FSNAME.$TESTNAME || error "Pool creation failed"
16935         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $ost_name ||
16936                 error "Adding $ost_name to pool failed"
16937
16938         # Wait for client to see a OST at pool
16939         wait_update $HOSTNAME "$LCTL get_param -n
16940                 lov.$FSNAME-*.pools.$TESTNAME | sort -u |
16941                 grep $ost_name" "$ost_name""_UUID" $((TIMEOUT/2)) ||
16942                 error "Client can not see the pool"
16943         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
16944                 error "Setstripe failed"
16945
16946         dd if=/dev/zero of=$DIR/$tdir/0 bs=1M count=10
16947         local blocks=$($LFS df $MOUNT | grep $ost_name | awk '{ print $4 }')
16948         echo "OST still has $((blocks/1024)) mbytes free"
16949
16950         local new_lwm=$((blocks/1024-10))
16951         do_facet $SINGLEMDS $LCTL set_param \
16952                         osp.$mdtosc_proc1.reserved_mb_high=$((new_lwm+5))
16953         do_facet $SINGLEMDS $LCTL set_param \
16954                         osp.$mdtosc_proc1.reserved_mb_low=$new_lwm
16955
16956         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16957
16958         #First enospc could execute orphan deletion so repeat.
16959         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16960
16961         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16962                         osp.$mdtosc_proc1.prealloc_status)
16963         echo "prealloc_status $oa_status"
16964
16965         dd if=/dev/zero of=$DIR/$tdir/2 bs=1M count=1 &&
16966                 error "File creation should fail"
16967         #object allocation was stopped, but we still able to append files
16968         dd if=/dev/zero of=$DIR/$tdir/1 bs=1M seek=6 count=5 oflag=append ||
16969                 error "Append failed"
16970         rm -f $DIR/$tdir/1 $DIR/$tdir/0 $DIR/$tdir/r*
16971
16972         wait_delete_completed
16973
16974         sleep_maxage
16975
16976         for i in $(seq 10 12); do
16977                 dd if=/dev/zero of=$DIR/$tdir/$i bs=1M count=1 2>/dev/null ||
16978                         error "File creation failed after rm";
16979         done
16980
16981         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16982                         osp.$mdtosc_proc1.prealloc_status)
16983         echo "prealloc_status $oa_status"
16984
16985         if (( oa_status != 0 )); then
16986                 error "Object allocation still disable after rm"
16987         fi
16988         do_facet $SINGLEMDS $LCTL set_param \
16989                         osp.$mdtosc_proc1.reserved_mb_high=$last_wm_h
16990         do_facet $SINGLEMDS $LCTL set_param \
16991                         osp.$mdtosc_proc1.reserved_mb_low=$last_wm_l
16992
16993
16994         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $ost_name ||
16995                 error "Remove $ost_name from pool failed"
16996         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16997                 error "Pool destroy fialed"
16998
16999         if ! combined_mgs_mds ; then
17000                 umount_mgs_client
17001         fi
17002 }
17003 run_test 253 "Check object allocation limit"
17004
17005 test_254() {
17006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17007         remote_mds_nodsh && skip "remote MDS with nodsh"
17008         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
17009                 skip "MDS does not support changelog_size"
17010
17011         local cl_user
17012         local MDT0=$(facet_svc $SINGLEMDS)
17013
17014         changelog_register || error "changelog_register failed"
17015
17016         changelog_clear 0 || error "changelog_clear failed"
17017
17018         local size1=$(do_facet $SINGLEMDS \
17019                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17020         echo "Changelog size $size1"
17021
17022         rm -rf $DIR/$tdir
17023         $LFS mkdir -i 0 $DIR/$tdir
17024         # change something
17025         mkdir -p $DIR/$tdir/pics/2008/zachy
17026         touch $DIR/$tdir/pics/2008/zachy/timestamp
17027         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
17028         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17029         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17030         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17031         rm $DIR/$tdir/pics/desktop.jpg
17032
17033         local size2=$(do_facet $SINGLEMDS \
17034                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17035         echo "Changelog size after work $size2"
17036
17037         (( $size2 > $size1 )) ||
17038                 error "new Changelog size=$size2 less than old size=$size1"
17039 }
17040 run_test 254 "Check changelog size"
17041
17042 ladvise_no_type()
17043 {
17044         local type=$1
17045         local file=$2
17046
17047         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
17048                 awk -F: '{print $2}' | grep $type > /dev/null
17049         if [ $? -ne 0 ]; then
17050                 return 0
17051         fi
17052         return 1
17053 }
17054
17055 ladvise_no_ioctl()
17056 {
17057         local file=$1
17058
17059         lfs ladvise -a willread $file > /dev/null 2>&1
17060         if [ $? -eq 0 ]; then
17061                 return 1
17062         fi
17063
17064         lfs ladvise -a willread $file 2>&1 |
17065                 grep "Inappropriate ioctl for device" > /dev/null
17066         if [ $? -eq 0 ]; then
17067                 return 0
17068         fi
17069         return 1
17070 }
17071
17072 percent() {
17073         bc <<<"scale=2; ($1 - $2) * 100 / $2"
17074 }
17075
17076 # run a random read IO workload
17077 # usage: random_read_iops <filename> <filesize> <iosize>
17078 random_read_iops() {
17079         local file=$1
17080         local fsize=$2
17081         local iosize=${3:-4096}
17082
17083         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
17084                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
17085 }
17086
17087 drop_file_oss_cache() {
17088         local file="$1"
17089         local nodes="$2"
17090
17091         $LFS ladvise -a dontneed $file 2>/dev/null ||
17092                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
17093 }
17094
17095 ladvise_willread_performance()
17096 {
17097         local repeat=10
17098         local average_origin=0
17099         local average_cache=0
17100         local average_ladvise=0
17101
17102         for ((i = 1; i <= $repeat; i++)); do
17103                 echo "Iter $i/$repeat: reading without willread hint"
17104                 cancel_lru_locks osc
17105                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17106                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
17107                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
17108                 average_origin=$(bc <<<"$average_origin + $speed_origin")
17109
17110                 cancel_lru_locks osc
17111                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
17112                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
17113                 average_cache=$(bc <<<"$average_cache + $speed_cache")
17114
17115                 cancel_lru_locks osc
17116                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17117                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
17118                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
17119                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
17120                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
17121         done
17122         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
17123         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
17124         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
17125
17126         speedup_cache=$(percent $average_cache $average_origin)
17127         speedup_ladvise=$(percent $average_ladvise $average_origin)
17128
17129         echo "Average uncached read: $average_origin"
17130         echo "Average speedup with OSS cached read: " \
17131                 "$average_cache = +$speedup_cache%"
17132         echo "Average speedup with ladvise willread: " \
17133                 "$average_ladvise = +$speedup_ladvise%"
17134
17135         local lowest_speedup=20
17136         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
17137                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
17138                         "got $average_cache%. Skipping ladvise willread check."
17139                 return 0
17140         fi
17141
17142         # the test won't work on ZFS until it supports 'ladvise dontneed', but
17143         # it is still good to run until then to exercise 'ladvise willread'
17144         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17145                 [ "$ost1_FSTYPE" = "zfs" ] &&
17146                 echo "osd-zfs does not support dontneed or drop_caches" &&
17147                 return 0
17148
17149         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
17150         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
17151                 error_not_in_vm "Speedup with willread is less than " \
17152                         "$lowest_speedup%, got $average_ladvise%"
17153 }
17154
17155 test_255a() {
17156         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17157                 skip "lustre < 2.8.54 does not support ladvise "
17158         remote_ost_nodsh && skip "remote OST with nodsh"
17159
17160         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
17161
17162         ladvise_no_type willread $DIR/$tfile &&
17163                 skip "willread ladvise is not supported"
17164
17165         ladvise_no_ioctl $DIR/$tfile &&
17166                 skip "ladvise ioctl is not supported"
17167
17168         local size_mb=100
17169         local size=$((size_mb * 1048576))
17170         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17171                 error "dd to $DIR/$tfile failed"
17172
17173         lfs ladvise -a willread $DIR/$tfile ||
17174                 error "Ladvise failed with no range argument"
17175
17176         lfs ladvise -a willread -s 0 $DIR/$tfile ||
17177                 error "Ladvise failed with no -l or -e argument"
17178
17179         lfs ladvise -a willread -e 1 $DIR/$tfile ||
17180                 error "Ladvise failed with only -e argument"
17181
17182         lfs ladvise -a willread -l 1 $DIR/$tfile ||
17183                 error "Ladvise failed with only -l argument"
17184
17185         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
17186                 error "End offset should not be smaller than start offset"
17187
17188         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
17189                 error "End offset should not be equal to start offset"
17190
17191         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
17192                 error "Ladvise failed with overflowing -s argument"
17193
17194         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
17195                 error "Ladvise failed with overflowing -e argument"
17196
17197         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
17198                 error "Ladvise failed with overflowing -l argument"
17199
17200         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
17201                 error "Ladvise succeeded with conflicting -l and -e arguments"
17202
17203         echo "Synchronous ladvise should wait"
17204         local delay=4
17205 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
17206         do_nodes $(comma_list $(osts_nodes)) \
17207                 $LCTL set_param fail_val=$delay fail_loc=0x237
17208
17209         local start_ts=$SECONDS
17210         lfs ladvise -a willread $DIR/$tfile ||
17211                 error "Ladvise failed with no range argument"
17212         local end_ts=$SECONDS
17213         local inteval_ts=$((end_ts - start_ts))
17214
17215         if [ $inteval_ts -lt $(($delay - 1)) ]; then
17216                 error "Synchronous advice didn't wait reply"
17217         fi
17218
17219         echo "Asynchronous ladvise shouldn't wait"
17220         local start_ts=$SECONDS
17221         lfs ladvise -a willread -b $DIR/$tfile ||
17222                 error "Ladvise failed with no range argument"
17223         local end_ts=$SECONDS
17224         local inteval_ts=$((end_ts - start_ts))
17225
17226         if [ $inteval_ts -gt $(($delay / 2)) ]; then
17227                 error "Asynchronous advice blocked"
17228         fi
17229
17230         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
17231         ladvise_willread_performance
17232 }
17233 run_test 255a "check 'lfs ladvise -a willread'"
17234
17235 facet_meminfo() {
17236         local facet=$1
17237         local info=$2
17238
17239         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
17240 }
17241
17242 test_255b() {
17243         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17244                 skip "lustre < 2.8.54 does not support ladvise "
17245         remote_ost_nodsh && skip "remote OST with nodsh"
17246
17247         lfs setstripe -c 1 -i 0 $DIR/$tfile
17248
17249         ladvise_no_type dontneed $DIR/$tfile &&
17250                 skip "dontneed ladvise is not supported"
17251
17252         ladvise_no_ioctl $DIR/$tfile &&
17253                 skip "ladvise ioctl is not supported"
17254
17255         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17256                 [ "$ost1_FSTYPE" = "zfs" ] &&
17257                 skip "zfs-osd does not support 'ladvise dontneed'"
17258
17259         local size_mb=100
17260         local size=$((size_mb * 1048576))
17261         # In order to prevent disturbance of other processes, only check 3/4
17262         # of the memory usage
17263         local kibibytes=$((size_mb * 1024 * 3 / 4))
17264
17265         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17266                 error "dd to $DIR/$tfile failed"
17267
17268         #force write to complete before dropping OST cache & checking memory
17269         sync
17270
17271         local total=$(facet_meminfo ost1 MemTotal)
17272         echo "Total memory: $total KiB"
17273
17274         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
17275         local before_read=$(facet_meminfo ost1 Cached)
17276         echo "Cache used before read: $before_read KiB"
17277
17278         lfs ladvise -a willread $DIR/$tfile ||
17279                 error "Ladvise willread failed"
17280         local after_read=$(facet_meminfo ost1 Cached)
17281         echo "Cache used after read: $after_read KiB"
17282
17283         lfs ladvise -a dontneed $DIR/$tfile ||
17284                 error "Ladvise dontneed again failed"
17285         local no_read=$(facet_meminfo ost1 Cached)
17286         echo "Cache used after dontneed ladvise: $no_read KiB"
17287
17288         if [ $total -lt $((before_read + kibibytes)) ]; then
17289                 echo "Memory is too small, abort checking"
17290                 return 0
17291         fi
17292
17293         if [ $((before_read + kibibytes)) -gt $after_read ]; then
17294                 error "Ladvise willread should use more memory" \
17295                         "than $kibibytes KiB"
17296         fi
17297
17298         if [ $((no_read + kibibytes)) -gt $after_read ]; then
17299                 error "Ladvise dontneed should release more memory" \
17300                         "than $kibibytes KiB"
17301         fi
17302 }
17303 run_test 255b "check 'lfs ladvise -a dontneed'"
17304
17305 test_255c() {
17306         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
17307                 skip "lustre < 2.10.53 does not support lockahead"
17308
17309         local count
17310         local new_count
17311         local difference
17312         local i
17313         local rc
17314
17315         test_mkdir -p $DIR/$tdir
17316         $LFS setstripe -i 0 -c 1 $DIR/$tdir
17317
17318         #test 10 returns only success/failure
17319         i=10
17320         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17321         rc=$?
17322         if [ $rc -eq 255 ]; then
17323                 error "Ladvise test${i} failed, ${rc}"
17324         fi
17325
17326         #test 11 counts lock enqueue requests, all others count new locks
17327         i=11
17328         count=$(do_facet ost1 \
17329                 $LCTL get_param -n ost.OSS.ost.stats)
17330         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
17331
17332         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17333         rc=$?
17334         if [ $rc -eq 255 ]; then
17335                 error "Ladvise test${i} failed, ${rc}"
17336         fi
17337
17338         new_count=$(do_facet ost1 \
17339                 $LCTL get_param -n ost.OSS.ost.stats)
17340         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
17341                    awk '{ print $2 }')
17342
17343         difference="$((new_count - count))"
17344         if [ $difference -ne $rc ]; then
17345                 error "Ladvise test${i}, bad enqueue count, returned " \
17346                       "${rc}, actual ${difference}"
17347         fi
17348
17349         for i in $(seq 12 21); do
17350                 # If we do not do this, we run the risk of having too many
17351                 # locks and starting lock cancellation while we are checking
17352                 # lock counts.
17353                 cancel_lru_locks osc
17354
17355                 count=$($LCTL get_param -n \
17356                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17357
17358                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
17359                 rc=$?
17360                 if [ $rc -eq 255 ]; then
17361                         error "Ladvise test ${i} failed, ${rc}"
17362                 fi
17363
17364                 new_count=$($LCTL get_param -n \
17365                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17366                 difference="$((new_count - count))"
17367
17368                 # Test 15 output is divided by 100 to map down to valid return
17369                 if [ $i -eq 15 ]; then
17370                         rc="$((rc * 100))"
17371                 fi
17372
17373                 if [ $difference -ne $rc ]; then
17374                         error "Ladvise test ${i}, bad lock count, returned " \
17375                               "${rc}, actual ${difference}"
17376                 fi
17377         done
17378
17379         #test 22 returns only success/failure
17380         i=22
17381         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17382         rc=$?
17383         if [ $rc -eq 255 ]; then
17384                 error "Ladvise test${i} failed, ${rc}"
17385         fi
17386 }
17387 run_test 255c "suite of ladvise lockahead tests"
17388
17389 test_256() {
17390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17391         remote_mds_nodsh && skip "remote MDS with nodsh"
17392         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17393         changelog_users $SINGLEMDS | grep "^cl" &&
17394                 skip "active changelog user"
17395
17396         local cl_user
17397         local cat_sl
17398         local mdt_dev
17399
17400         mdt_dev=$(mdsdevname 1)
17401         echo $mdt_dev
17402
17403         changelog_register || error "changelog_register failed"
17404
17405         rm -rf $DIR/$tdir
17406         mkdir -p $DIR/$tdir
17407
17408         changelog_clear 0 || error "changelog_clear failed"
17409
17410         # change something
17411         touch $DIR/$tdir/{1..10}
17412
17413         # stop the MDT
17414         stop $SINGLEMDS || error "Fail to stop MDT"
17415
17416         # remount the MDT
17417
17418         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
17419
17420         #after mount new plainllog is used
17421         touch $DIR/$tdir/{11..19}
17422         local tmpfile=$(mktemp -u $tfile.XXXXXX)
17423         cat_sl=$(do_facet $SINGLEMDS "sync; \
17424                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17425                  llog_reader $tmpfile | grep -c type=1064553b")
17426         do_facet $SINGLEMDS llog_reader $tmpfile
17427
17428         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
17429
17430         changelog_clear 0 || error "changelog_clear failed"
17431
17432         cat_sl=$(do_facet $SINGLEMDS "sync; \
17433                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17434                  llog_reader $tmpfile | grep -c type=1064553b; rm -f $tmpfile")
17435
17436         if (( cat_sl == 2 )); then
17437                 error "Empty plain llog was not deleted from changelog catalog"
17438         elif (( cat_sl != 1 )); then
17439                 error "Active plain llog shouldn't be deleted from catalog"
17440         fi
17441 }
17442 run_test 256 "Check llog delete for empty and not full state"
17443
17444 test_257() {
17445         remote_mds_nodsh && skip "remote MDS with nodsh"
17446         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
17447                 skip "Need MDS version at least 2.8.55"
17448
17449         test_mkdir $DIR/$tdir
17450
17451         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
17452                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
17453         stat $DIR/$tdir
17454
17455 #define OBD_FAIL_MDS_XATTR_REP                  0x161
17456         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17457         local facet=mds$((mdtidx + 1))
17458         set_nodes_failloc $(facet_active_host $facet) 0x80000161
17459         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
17460
17461         stop $facet || error "stop MDS failed"
17462         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
17463                 error "start MDS fail"
17464         wait_recovery_complete $facet
17465 }
17466 run_test 257 "xattr locks are not lost"
17467
17468 # Verify we take the i_mutex when security requires it
17469 test_258a() {
17470 #define OBD_FAIL_IMUTEX_SEC 0x141c
17471         $LCTL set_param fail_loc=0x141c
17472         touch $DIR/$tfile
17473         chmod u+s $DIR/$tfile
17474         chmod a+rwx $DIR/$tfile
17475         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17476         RC=$?
17477         if [ $RC -ne 0 ]; then
17478                 error "error, failed to take i_mutex, rc=$?"
17479         fi
17480         rm -f $DIR/$tfile
17481 }
17482 run_test 258a "verify i_mutex security behavior when suid attributes is set"
17483
17484 # Verify we do NOT take the i_mutex in the normal case
17485 test_258b() {
17486 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
17487         $LCTL set_param fail_loc=0x141d
17488         touch $DIR/$tfile
17489         chmod a+rwx $DIR
17490         chmod a+rw $DIR/$tfile
17491         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17492         RC=$?
17493         if [ $RC -ne 0 ]; then
17494                 error "error, took i_mutex unnecessarily, rc=$?"
17495         fi
17496         rm -f $DIR/$tfile
17497
17498 }
17499 run_test 258b "verify i_mutex security behavior"
17500
17501 test_259() {
17502         local file=$DIR/$tfile
17503         local before
17504         local after
17505
17506         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17507
17508         stack_trap "rm -f $file" EXIT
17509
17510         wait_delete_completed
17511         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17512         echo "before: $before"
17513
17514         $LFS setstripe -i 0 -c 1 $file
17515         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17516         sync_all_data
17517         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17518         echo "after write: $after"
17519
17520 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17521         do_facet ost1 $LCTL set_param fail_loc=0x2301
17522         $TRUNCATE $file 0
17523         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17524         echo "after truncate: $after"
17525
17526         stop ost1
17527         do_facet ost1 $LCTL set_param fail_loc=0
17528         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17529         sleep 2
17530         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17531         echo "after restart: $after"
17532         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17533                 error "missing truncate?"
17534
17535         return 0
17536 }
17537 run_test 259 "crash at delayed truncate"
17538
17539 test_260() {
17540 #define OBD_FAIL_MDC_CLOSE               0x806
17541         $LCTL set_param fail_loc=0x80000806
17542         touch $DIR/$tfile
17543
17544 }
17545 run_test 260 "Check mdc_close fail"
17546
17547 ### Data-on-MDT sanity tests ###
17548 test_270a() {
17549         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17550                 skip "Need MDS version at least 2.10.55 for DoM"
17551
17552         # create DoM file
17553         local dom=$DIR/$tdir/dom_file
17554         local tmp=$DIR/$tdir/tmp_file
17555
17556         mkdir -p $DIR/$tdir
17557
17558         # basic checks for DoM component creation
17559         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17560                 error "Can set MDT layout to non-first entry"
17561
17562         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17563                 error "Can define multiple entries as MDT layout"
17564
17565         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17566
17567         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17568         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17569         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17570
17571         local mdtidx=$($LFS getstripe -m $dom)
17572         local mdtname=MDT$(printf %04x $mdtidx)
17573         local facet=mds$((mdtidx + 1))
17574         local space_check=1
17575
17576         # Skip free space checks with ZFS
17577         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17578
17579         # write
17580         sync
17581         local size_tmp=$((65536 * 3))
17582         local mdtfree1=$(do_facet $facet \
17583                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17584
17585         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17586         # check also direct IO along write
17587         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17588         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17589         sync
17590         cmp $tmp $dom || error "file data is different"
17591         [ $(stat -c%s $dom) == $size_tmp ] ||
17592                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17593         if [ $space_check == 1 ]; then
17594                 local mdtfree2=$(do_facet $facet \
17595                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17596
17597                 # increase in usage from by $size_tmp
17598                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17599                         error "MDT free space wrong after write: " \
17600                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17601         fi
17602
17603         # truncate
17604         local size_dom=10000
17605
17606         $TRUNCATE $dom $size_dom
17607         [ $(stat -c%s $dom) == $size_dom ] ||
17608                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17609         if [ $space_check == 1 ]; then
17610                 mdtfree1=$(do_facet $facet \
17611                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17612                 # decrease in usage from $size_tmp to new $size_dom
17613                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17614                   $(((size_tmp - size_dom) / 1024)) ] ||
17615                         error "MDT free space is wrong after truncate: " \
17616                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17617         fi
17618
17619         # append
17620         cat $tmp >> $dom
17621         sync
17622         size_dom=$((size_dom + size_tmp))
17623         [ $(stat -c%s $dom) == $size_dom ] ||
17624                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17625         if [ $space_check == 1 ]; then
17626                 mdtfree2=$(do_facet $facet \
17627                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17628                 # increase in usage by $size_tmp from previous
17629                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17630                         error "MDT free space is wrong after append: " \
17631                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17632         fi
17633
17634         # delete
17635         rm $dom
17636         if [ $space_check == 1 ]; then
17637                 mdtfree1=$(do_facet $facet \
17638                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17639                 # decrease in usage by $size_dom from previous
17640                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17641                         error "MDT free space is wrong after removal: " \
17642                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17643         fi
17644
17645         # combined striping
17646         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17647                 error "Can't create DoM + OST striping"
17648
17649         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17650         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17651         # check also direct IO along write
17652         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17653         sync
17654         cmp $tmp $dom || error "file data is different"
17655         [ $(stat -c%s $dom) == $size_tmp ] ||
17656                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17657         rm $dom $tmp
17658
17659         return 0
17660 }
17661 run_test 270a "DoM: basic functionality tests"
17662
17663 test_270b() {
17664         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17665                 skip "Need MDS version at least 2.10.55"
17666
17667         local dom=$DIR/$tdir/dom_file
17668         local max_size=1048576
17669
17670         mkdir -p $DIR/$tdir
17671         $LFS setstripe -E $max_size -L mdt $dom
17672
17673         # truncate over the limit
17674         $TRUNCATE $dom $(($max_size + 1)) &&
17675                 error "successful truncate over the maximum size"
17676         # write over the limit
17677         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17678                 error "successful write over the maximum size"
17679         # append over the limit
17680         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17681         echo "12345" >> $dom && error "successful append over the maximum size"
17682         rm $dom
17683
17684         return 0
17685 }
17686 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17687
17688 test_270c() {
17689         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17690                 skip "Need MDS version at least 2.10.55"
17691
17692         mkdir -p $DIR/$tdir
17693         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17694
17695         # check files inherit DoM EA
17696         touch $DIR/$tdir/first
17697         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17698                 error "bad pattern"
17699         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17700                 error "bad stripe count"
17701         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17702                 error "bad stripe size"
17703
17704         # check directory inherits DoM EA and uses it as default
17705         mkdir $DIR/$tdir/subdir
17706         touch $DIR/$tdir/subdir/second
17707         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17708                 error "bad pattern in sub-directory"
17709         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17710                 error "bad stripe count in sub-directory"
17711         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17712                 error "bad stripe size in sub-directory"
17713         return 0
17714 }
17715 run_test 270c "DoM: DoM EA inheritance tests"
17716
17717 test_270d() {
17718         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17719                 skip "Need MDS version at least 2.10.55"
17720
17721         mkdir -p $DIR/$tdir
17722         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17723
17724         # inherit default DoM striping
17725         mkdir $DIR/$tdir/subdir
17726         touch $DIR/$tdir/subdir/f1
17727
17728         # change default directory striping
17729         $LFS setstripe -c 1 $DIR/$tdir/subdir
17730         touch $DIR/$tdir/subdir/f2
17731         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17732                 error "wrong default striping in file 2"
17733         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17734                 error "bad pattern in file 2"
17735         return 0
17736 }
17737 run_test 270d "DoM: change striping from DoM to RAID0"
17738
17739 test_270e() {
17740         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17741                 skip "Need MDS version at least 2.10.55"
17742
17743         mkdir -p $DIR/$tdir/dom
17744         mkdir -p $DIR/$tdir/norm
17745         DOMFILES=20
17746         NORMFILES=10
17747         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17748         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17749
17750         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17751         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17752
17753         # find DoM files by layout
17754         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17755         [ $NUM -eq  $DOMFILES ] ||
17756                 error "lfs find -L: found $NUM, expected $DOMFILES"
17757         echo "Test 1: lfs find 20 DOM files by layout: OK"
17758
17759         # there should be 1 dir with default DOM striping
17760         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17761         [ $NUM -eq  1 ] ||
17762                 error "lfs find -L: found $NUM, expected 1 dir"
17763         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17764
17765         # find DoM files by stripe size
17766         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17767         [ $NUM -eq  $DOMFILES ] ||
17768                 error "lfs find -S: found $NUM, expected $DOMFILES"
17769         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17770
17771         # find files by stripe offset except DoM files
17772         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17773         [ $NUM -eq  $NORMFILES ] ||
17774                 error "lfs find -i: found $NUM, expected $NORMFILES"
17775         echo "Test 5: lfs find no DOM files by stripe index: OK"
17776         return 0
17777 }
17778 run_test 270e "DoM: lfs find with DoM files test"
17779
17780 test_270f() {
17781         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17782                 skip "Need MDS version at least 2.10.55"
17783
17784         local mdtname=${FSNAME}-MDT0000-mdtlov
17785         local dom=$DIR/$tdir/dom_file
17786         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17787                                                 lod.$mdtname.dom_stripesize)
17788         local dom_limit=131072
17789
17790         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17791         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17792                                                 lod.$mdtname.dom_stripesize)
17793         [ ${dom_limit} -eq ${dom_current} ] ||
17794                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17795
17796         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17797         $LFS setstripe -d $DIR/$tdir
17798         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17799                 error "Can't set directory default striping"
17800
17801         # exceed maximum stripe size
17802         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17803                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17804         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17805                 error "Able to create DoM component size more than LOD limit"
17806
17807         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17808         dom_current=$(do_facet mds1 $LCTL get_param -n \
17809                                                 lod.$mdtname.dom_stripesize)
17810         [ 0 -eq ${dom_current} ] ||
17811                 error "Can't set zero DoM stripe limit"
17812         rm $dom
17813
17814         # attempt to create DoM file on server with disabled DoM should
17815         # remove DoM entry from layout and be succeed
17816         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17817                 error "Can't create DoM file (DoM is disabled)"
17818         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17819                 error "File has DoM component while DoM is disabled"
17820         rm $dom
17821
17822         # attempt to create DoM file with only DoM stripe should return error
17823         $LFS setstripe -E $dom_limit -L mdt $dom &&
17824                 error "Able to create DoM-only file while DoM is disabled"
17825
17826         # too low values to be aligned with smallest stripe size 64K
17827         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17828         dom_current=$(do_facet mds1 $LCTL get_param -n \
17829                                                 lod.$mdtname.dom_stripesize)
17830         [ 30000 -eq ${dom_current} ] &&
17831                 error "Can set too small DoM stripe limit"
17832
17833         # 64K is a minimal stripe size in Lustre, expect limit of that size
17834         [ 65536 -eq ${dom_current} ] ||
17835                 error "Limit is not set to 64K but ${dom_current}"
17836
17837         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17838         dom_current=$(do_facet mds1 $LCTL get_param -n \
17839                                                 lod.$mdtname.dom_stripesize)
17840         echo $dom_current
17841         [ 2147483648 -eq ${dom_current} ] &&
17842                 error "Can set too large DoM stripe limit"
17843
17844         do_facet mds1 $LCTL set_param -n \
17845                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17846         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17847                 error "Can't create DoM component size after limit change"
17848         do_facet mds1 $LCTL set_param -n \
17849                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17850         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17851                 error "Can't create DoM file after limit decrease"
17852         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17853                 error "Can create big DoM component after limit decrease"
17854         touch ${dom}_def ||
17855                 error "Can't create file with old default layout"
17856
17857         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17858         return 0
17859 }
17860 run_test 270f "DoM: maximum DoM stripe size checks"
17861
17862 test_271a() {
17863         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17864                 skip "Need MDS version at least 2.10.55"
17865
17866         local dom=$DIR/$tdir/dom
17867
17868         mkdir -p $DIR/$tdir
17869
17870         $LFS setstripe -E 1024K -L mdt $dom
17871
17872         lctl set_param -n mdc.*.stats=clear
17873         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17874         cat $dom > /dev/null
17875         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
17876         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
17877         ls $dom
17878         rm -f $dom
17879 }
17880 run_test 271a "DoM: data is cached for read after write"
17881
17882 test_271b() {
17883         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17884                 skip "Need MDS version at least 2.10.55"
17885
17886         local dom=$DIR/$tdir/dom
17887
17888         mkdir -p $DIR/$tdir
17889
17890         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17891
17892         lctl set_param -n mdc.*.stats=clear
17893         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17894         cancel_lru_locks mdc
17895         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
17896         # second stat to check size is cached on client
17897         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
17898         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17899         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
17900         rm -f $dom
17901 }
17902 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
17903
17904 test_271ba() {
17905         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17906                 skip "Need MDS version at least 2.10.55"
17907
17908         local dom=$DIR/$tdir/dom
17909
17910         mkdir -p $DIR/$tdir
17911
17912         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17913
17914         lctl set_param -n mdc.*.stats=clear
17915         lctl set_param -n osc.*.stats=clear
17916         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
17917         cancel_lru_locks mdc
17918         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17919         # second stat to check size is cached on client
17920         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17921         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17922         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
17923         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
17924         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
17925         rm -f $dom
17926 }
17927 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
17928
17929
17930 get_mdc_stats() {
17931         local mdtidx=$1
17932         local param=$2
17933         local mdt=MDT$(printf %04x $mdtidx)
17934
17935         if [ -z $param ]; then
17936                 lctl get_param -n mdc.*$mdt*.stats
17937         else
17938                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
17939         fi
17940 }
17941
17942 test_271c() {
17943         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17944                 skip "Need MDS version at least 2.10.55"
17945
17946         local dom=$DIR/$tdir/dom
17947
17948         mkdir -p $DIR/$tdir
17949
17950         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17951
17952         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17953         local facet=mds$((mdtidx + 1))
17954
17955         cancel_lru_locks mdc
17956         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
17957         createmany -o $dom 1000
17958         lctl set_param -n mdc.*.stats=clear
17959         smalliomany -w $dom 1000 200
17960         get_mdc_stats $mdtidx
17961         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17962         # Each file has 1 open, 1 IO enqueues, total 2000
17963         # but now we have also +1 getxattr for security.capability, total 3000
17964         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
17965         unlinkmany $dom 1000
17966
17967         cancel_lru_locks mdc
17968         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
17969         createmany -o $dom 1000
17970         lctl set_param -n mdc.*.stats=clear
17971         smalliomany -w $dom 1000 200
17972         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17973         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
17974         # for OPEN and IO lock.
17975         [ $((enq - enq_2)) -ge 1000 ] ||
17976                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
17977         unlinkmany $dom 1000
17978         return 0
17979 }
17980 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
17981
17982 cleanup_271def_tests() {
17983         trap 0
17984         rm -f $1
17985 }
17986
17987 test_271d() {
17988         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17989                 skip "Need MDS version at least 2.10.57"
17990
17991         local dom=$DIR/$tdir/dom
17992         local tmp=$TMP/$tfile
17993         trap "cleanup_271def_tests $tmp" EXIT
17994
17995         mkdir -p $DIR/$tdir
17996
17997         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17998
17999         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18000
18001         cancel_lru_locks mdc
18002         dd if=/dev/urandom of=$tmp bs=1000 count=1
18003         dd if=$tmp of=$dom bs=1000 count=1
18004         cancel_lru_locks mdc
18005
18006         cat /etc/hosts >> $tmp
18007         lctl set_param -n mdc.*.stats=clear
18008
18009         # append data to the same file it should update local page
18010         echo "Append to the same page"
18011         cat /etc/hosts >> $dom
18012         local num=$(get_mdc_stats $mdtidx ost_read)
18013         local ra=$(get_mdc_stats $mdtidx req_active)
18014         local rw=$(get_mdc_stats $mdtidx req_waittime)
18015
18016         [ -z $num ] || error "$num READ RPC occured"
18017         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18018         echo "... DONE"
18019
18020         # compare content
18021         cmp $tmp $dom || error "file miscompare"
18022
18023         cancel_lru_locks mdc
18024         lctl set_param -n mdc.*.stats=clear
18025
18026         echo "Open and read file"
18027         cat $dom > /dev/null
18028         local num=$(get_mdc_stats $mdtidx ost_read)
18029         local ra=$(get_mdc_stats $mdtidx req_active)
18030         local rw=$(get_mdc_stats $mdtidx req_waittime)
18031
18032         [ -z $num ] || error "$num READ RPC occured"
18033         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18034         echo "... DONE"
18035
18036         # compare content
18037         cmp $tmp $dom || error "file miscompare"
18038
18039         return 0
18040 }
18041 run_test 271d "DoM: read on open (1K file in reply buffer)"
18042
18043 test_271f() {
18044         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18045                 skip "Need MDS version at least 2.10.57"
18046
18047         local dom=$DIR/$tdir/dom
18048         local tmp=$TMP/$tfile
18049         trap "cleanup_271def_tests $tmp" EXIT
18050
18051         mkdir -p $DIR/$tdir
18052
18053         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18054
18055         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18056
18057         cancel_lru_locks mdc
18058         dd if=/dev/urandom of=$tmp bs=200000 count=1
18059         dd if=$tmp of=$dom bs=200000 count=1
18060         cancel_lru_locks mdc
18061         cat /etc/hosts >> $tmp
18062         lctl set_param -n mdc.*.stats=clear
18063
18064         echo "Append to the same page"
18065         cat /etc/hosts >> $dom
18066         local num=$(get_mdc_stats $mdtidx ost_read)
18067         local ra=$(get_mdc_stats $mdtidx req_active)
18068         local rw=$(get_mdc_stats $mdtidx req_waittime)
18069
18070         [ -z $num ] || error "$num READ RPC occured"
18071         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18072         echo "... DONE"
18073
18074         # compare content
18075         cmp $tmp $dom || error "file miscompare"
18076
18077         cancel_lru_locks mdc
18078         lctl set_param -n mdc.*.stats=clear
18079
18080         echo "Open and read file"
18081         cat $dom > /dev/null
18082         local num=$(get_mdc_stats $mdtidx ost_read)
18083         local ra=$(get_mdc_stats $mdtidx req_active)
18084         local rw=$(get_mdc_stats $mdtidx req_waittime)
18085
18086         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
18087         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18088         echo "... DONE"
18089
18090         # compare content
18091         cmp $tmp $dom || error "file miscompare"
18092
18093         return 0
18094 }
18095 run_test 271f "DoM: read on open (200K file and read tail)"
18096
18097 test_271g() {
18098         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
18099                 skip "Skipping due to old client or server version"
18100
18101         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
18102         # to get layout
18103         $CHECKSTAT -t file $DIR1/$tfile
18104
18105         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
18106         MULTIOP_PID=$!
18107         sleep 1
18108         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
18109         $LCTL set_param fail_loc=0x80000314
18110         rm $DIR1/$tfile || error "Unlink fails"
18111         RC=$?
18112         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
18113         [ $RC -eq 0 ] || error "Failed write to stale object"
18114 }
18115 run_test 271g "Discard DoM data vs client flush race"
18116
18117 test_272a() {
18118         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18119                 skip "Need MDS version at least 2.11.50"
18120
18121         local dom=$DIR/$tdir/dom
18122         mkdir -p $DIR/$tdir
18123
18124         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
18125         dd if=/dev/urandom of=$dom bs=512K count=1 ||
18126                 error "failed to write data into $dom"
18127         local old_md5=$(md5sum $dom)
18128
18129         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
18130                 error "failed to migrate to the same DoM component"
18131
18132         local new_md5=$(md5sum $dom)
18133
18134         [ "$old_md5" == "$new_md5" ] ||
18135                 error "md5sum differ: $old_md5, $new_md5"
18136
18137         [ $($LFS getstripe -c $dom) -eq 2 ] ||
18138                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
18139 }
18140 run_test 272a "DoM migration: new layout with the same DOM component"
18141
18142 test_272b() {
18143         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18144                 skip "Need MDS version at least 2.11.50"
18145
18146         local dom=$DIR/$tdir/dom
18147         mkdir -p $DIR/$tdir
18148         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18149
18150         local mdtidx=$($LFS getstripe -m $dom)
18151         local mdtname=MDT$(printf %04x $mdtidx)
18152         local facet=mds$((mdtidx + 1))
18153
18154         local mdtfree1=$(do_facet $facet \
18155                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18156         dd if=/dev/urandom of=$dom bs=2M count=1 ||
18157                 error "failed to write data into $dom"
18158         local old_md5=$(md5sum $dom)
18159         cancel_lru_locks mdc
18160         local mdtfree1=$(do_facet $facet \
18161                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18162
18163         $LFS migrate -c2 $dom ||
18164                 error "failed to migrate to the new composite layout"
18165         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18166                 error "MDT stripe was not removed"
18167
18168         cancel_lru_locks mdc
18169         local new_md5=$(md5sum $dom)
18170         [ "$old_md5" != "$new_md5" ] &&
18171                 error "$old_md5 != $new_md5"
18172
18173         # Skip free space checks with ZFS
18174         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18175                 local mdtfree2=$(do_facet $facet \
18176                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18177                 [ $mdtfree2 -gt $mdtfree1 ] ||
18178                         error "MDT space is not freed after migration"
18179         fi
18180         return 0
18181 }
18182 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
18183
18184 test_272c() {
18185         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18186                 skip "Need MDS version at least 2.11.50"
18187
18188         local dom=$DIR/$tdir/$tfile
18189         mkdir -p $DIR/$tdir
18190         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18191
18192         local mdtidx=$($LFS getstripe -m $dom)
18193         local mdtname=MDT$(printf %04x $mdtidx)
18194         local facet=mds$((mdtidx + 1))
18195
18196         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18197                 error "failed to write data into $dom"
18198         local old_md5=$(md5sum $dom)
18199         cancel_lru_locks mdc
18200         local mdtfree1=$(do_facet $facet \
18201                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18202
18203         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
18204                 error "failed to migrate to the new composite layout"
18205         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18206                 error "MDT stripe was not removed"
18207
18208         cancel_lru_locks mdc
18209         local new_md5=$(md5sum $dom)
18210         [ "$old_md5" != "$new_md5" ] &&
18211                 error "$old_md5 != $new_md5"
18212
18213         # Skip free space checks with ZFS
18214         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18215                 local mdtfree2=$(do_facet $facet \
18216                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18217                 [ $mdtfree2 -gt $mdtfree1 ] ||
18218                         error "MDS space is not freed after migration"
18219         fi
18220         return 0
18221 }
18222 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
18223
18224 test_273a() {
18225         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18226                 skip "Need MDS version at least 2.11.50"
18227
18228         # Layout swap cannot be done if either file has DOM component,
18229         # this will never be supported, migration should be used instead
18230
18231         local dom=$DIR/$tdir/$tfile
18232         mkdir -p $DIR/$tdir
18233
18234         $LFS setstripe -c2 ${dom}_plain
18235         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
18236         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
18237                 error "can swap layout with DoM component"
18238         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
18239                 error "can swap layout with DoM component"
18240
18241         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
18242         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
18243                 error "can swap layout with DoM component"
18244         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
18245                 error "can swap layout with DoM component"
18246         return 0
18247 }
18248 run_test 273a "DoM: layout swapping should fail with DOM"
18249
18250 test_275() {
18251         remote_ost_nodsh && skip "remote OST with nodsh"
18252         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
18253                 skip "Need OST version >= 2.10.57"
18254
18255         local file=$DIR/$tfile
18256         local oss
18257
18258         oss=$(comma_list $(osts_nodes))
18259
18260         dd if=/dev/urandom of=$file bs=1M count=2 ||
18261                 error "failed to create a file"
18262         cancel_lru_locks osc
18263
18264         #lock 1
18265         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18266                 error "failed to read a file"
18267
18268 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
18269         $LCTL set_param fail_loc=0x8000031f
18270
18271         cancel_lru_locks osc &
18272         sleep 1
18273
18274 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
18275         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
18276         #IO takes another lock, but matches the PENDING one
18277         #and places it to the IO RPC
18278         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18279                 error "failed to read a file with PENDING lock"
18280 }
18281 run_test 275 "Read on a canceled duplicate lock"
18282
18283 test_276() {
18284         remote_ost_nodsh && skip "remote OST with nodsh"
18285         local pid
18286
18287         do_facet ost1 "(while true; do \
18288                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
18289                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
18290         pid=$!
18291
18292         for LOOP in $(seq 20); do
18293                 stop ost1
18294                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
18295         done
18296         kill -9 $pid
18297         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
18298                 rm $TMP/sanity_276_pid"
18299 }
18300 run_test 276 "Race between mount and obd_statfs"
18301
18302 cleanup_test_300() {
18303         trap 0
18304         umask $SAVE_UMASK
18305 }
18306 test_striped_dir() {
18307         local mdt_index=$1
18308         local stripe_count
18309         local stripe_index
18310
18311         mkdir -p $DIR/$tdir
18312
18313         SAVE_UMASK=$(umask)
18314         trap cleanup_test_300 RETURN EXIT
18315
18316         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
18317                                                 $DIR/$tdir/striped_dir ||
18318                 error "set striped dir error"
18319
18320         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
18321         [ "$mode" = "755" ] || error "expect 755 got $mode"
18322
18323         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
18324                 error "getdirstripe failed"
18325         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
18326         if [ "$stripe_count" != "2" ]; then
18327                 error "1:stripe_count is $stripe_count, expect 2"
18328         fi
18329         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
18330         if [ "$stripe_count" != "2" ]; then
18331                 error "2:stripe_count is $stripe_count, expect 2"
18332         fi
18333
18334         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
18335         if [ "$stripe_index" != "$mdt_index" ]; then
18336                 error "stripe_index is $stripe_index, expect $mdt_index"
18337         fi
18338
18339         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18340                 error "nlink error after create striped dir"
18341
18342         mkdir $DIR/$tdir/striped_dir/a
18343         mkdir $DIR/$tdir/striped_dir/b
18344
18345         stat $DIR/$tdir/striped_dir/a ||
18346                 error "create dir under striped dir failed"
18347         stat $DIR/$tdir/striped_dir/b ||
18348                 error "create dir under striped dir failed"
18349
18350         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
18351                 error "nlink error after mkdir"
18352
18353         rmdir $DIR/$tdir/striped_dir/a
18354         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
18355                 error "nlink error after rmdir"
18356
18357         rmdir $DIR/$tdir/striped_dir/b
18358         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18359                 error "nlink error after rmdir"
18360
18361         chattr +i $DIR/$tdir/striped_dir
18362         createmany -o $DIR/$tdir/striped_dir/f 10 &&
18363                 error "immutable flags not working under striped dir!"
18364         chattr -i $DIR/$tdir/striped_dir
18365
18366         rmdir $DIR/$tdir/striped_dir ||
18367                 error "rmdir striped dir error"
18368
18369         cleanup_test_300
18370
18371         true
18372 }
18373
18374 test_300a() {
18375         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18376                 skip "skipped for lustre < 2.7.0"
18377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18378         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18379
18380         test_striped_dir 0 || error "failed on striped dir on MDT0"
18381         test_striped_dir 1 || error "failed on striped dir on MDT0"
18382 }
18383 run_test 300a "basic striped dir sanity test"
18384
18385 test_300b() {
18386         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18387                 skip "skipped for lustre < 2.7.0"
18388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18389         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18390
18391         local i
18392         local mtime1
18393         local mtime2
18394         local mtime3
18395
18396         test_mkdir $DIR/$tdir || error "mkdir fail"
18397         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18398                 error "set striped dir error"
18399         for i in {0..9}; do
18400                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
18401                 sleep 1
18402                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
18403                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
18404                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
18405                 sleep 1
18406                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
18407                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
18408                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
18409         done
18410         true
18411 }
18412 run_test 300b "check ctime/mtime for striped dir"
18413
18414 test_300c() {
18415         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18416                 skip "skipped for lustre < 2.7.0"
18417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18418         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18419
18420         local file_count
18421
18422         mkdir -p $DIR/$tdir
18423         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
18424                 error "set striped dir error"
18425
18426         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
18427                 error "chown striped dir failed"
18428
18429         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
18430                 error "create 5k files failed"
18431
18432         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
18433
18434         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
18435
18436         rm -rf $DIR/$tdir
18437 }
18438 run_test 300c "chown && check ls under striped directory"
18439
18440 test_300d() {
18441         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18442                 skip "skipped for lustre < 2.7.0"
18443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18444         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18445
18446         local stripe_count
18447         local file
18448
18449         mkdir -p $DIR/$tdir
18450         $LFS setstripe -c 2 $DIR/$tdir
18451
18452         #local striped directory
18453         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18454                 error "set striped dir error"
18455         createmany -o $DIR/$tdir/striped_dir/f 10 ||
18456                 error "create 10 files failed"
18457
18458         #remote striped directory
18459         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
18460                 error "set striped dir error"
18461         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
18462                 error "create 10 files failed"
18463
18464         for file in $(find $DIR/$tdir); do
18465                 stripe_count=$($LFS getstripe -c $file)
18466                 [ $stripe_count -eq 2 ] ||
18467                         error "wrong stripe $stripe_count for $file"
18468         done
18469
18470         rm -rf $DIR/$tdir
18471 }
18472 run_test 300d "check default stripe under striped directory"
18473
18474 test_300e() {
18475         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18476                 skip "Need MDS version at least 2.7.55"
18477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18478         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18479
18480         local stripe_count
18481         local file
18482
18483         mkdir -p $DIR/$tdir
18484
18485         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18486                 error "set striped dir error"
18487
18488         touch $DIR/$tdir/striped_dir/a
18489         touch $DIR/$tdir/striped_dir/b
18490         touch $DIR/$tdir/striped_dir/c
18491
18492         mkdir $DIR/$tdir/striped_dir/dir_a
18493         mkdir $DIR/$tdir/striped_dir/dir_b
18494         mkdir $DIR/$tdir/striped_dir/dir_c
18495
18496         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
18497                 error "set striped adir under striped dir error"
18498
18499         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
18500                 error "set striped bdir under striped dir error"
18501
18502         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
18503                 error "set striped cdir under striped dir error"
18504
18505         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
18506                 error "rename dir under striped dir fails"
18507
18508         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
18509                 error "rename dir under different stripes fails"
18510
18511         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
18512                 error "rename file under striped dir should succeed"
18513
18514         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
18515                 error "rename dir under striped dir should succeed"
18516
18517         rm -rf $DIR/$tdir
18518 }
18519 run_test 300e "check rename under striped directory"
18520
18521 test_300f() {
18522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18523         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18524         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18525                 skip "Need MDS version at least 2.7.55"
18526
18527         local stripe_count
18528         local file
18529
18530         rm -rf $DIR/$tdir
18531         mkdir -p $DIR/$tdir
18532
18533         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18534                 error "set striped dir error"
18535
18536         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18537                 error "set striped dir error"
18538
18539         touch $DIR/$tdir/striped_dir/a
18540         mkdir $DIR/$tdir/striped_dir/dir_a
18541         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18542                 error "create striped dir under striped dir fails"
18543
18544         touch $DIR/$tdir/striped_dir1/b
18545         mkdir $DIR/$tdir/striped_dir1/dir_b
18546         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18547                 error "create striped dir under striped dir fails"
18548
18549         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18550                 error "rename dir under different striped dir should fail"
18551
18552         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18553                 error "rename striped dir under diff striped dir should fail"
18554
18555         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18556                 error "rename file under diff striped dirs fails"
18557
18558         rm -rf $DIR/$tdir
18559 }
18560 run_test 300f "check rename cross striped directory"
18561
18562 test_300_check_default_striped_dir()
18563 {
18564         local dirname=$1
18565         local default_count=$2
18566         local default_index=$3
18567         local stripe_count
18568         local stripe_index
18569         local dir_stripe_index
18570         local dir
18571
18572         echo "checking $dirname $default_count $default_index"
18573         $LFS setdirstripe -D -c $default_count -i $default_index \
18574                                 -t all_char $DIR/$tdir/$dirname ||
18575                 error "set default stripe on striped dir error"
18576         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18577         [ $stripe_count -eq $default_count ] ||
18578                 error "expect $default_count get $stripe_count for $dirname"
18579
18580         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18581         [ $stripe_index -eq $default_index ] ||
18582                 error "expect $default_index get $stripe_index for $dirname"
18583
18584         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18585                                                 error "create dirs failed"
18586
18587         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18588         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18589         for dir in $(find $DIR/$tdir/$dirname/*); do
18590                 stripe_count=$($LFS getdirstripe -c $dir)
18591                 [ $stripe_count -eq $default_count ] ||
18592                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
18593                 error "stripe count $default_count != $stripe_count for $dir"
18594
18595                 stripe_index=$($LFS getdirstripe -i $dir)
18596                 [ $default_index -eq -1 ] ||
18597                         [ $stripe_index -eq $default_index ] ||
18598                         error "$stripe_index != $default_index for $dir"
18599
18600                 #check default stripe
18601                 stripe_count=$($LFS getdirstripe -D -c $dir)
18602                 [ $stripe_count -eq $default_count ] ||
18603                 error "default count $default_count != $stripe_count for $dir"
18604
18605                 stripe_index=$($LFS getdirstripe -D -i $dir)
18606                 [ $stripe_index -eq $default_index ] ||
18607                 error "default index $default_index != $stripe_index for $dir"
18608         done
18609         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18610 }
18611
18612 test_300g() {
18613         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18614         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18615                 skip "Need MDS version at least 2.7.55"
18616
18617         local dir
18618         local stripe_count
18619         local stripe_index
18620
18621         mkdir $DIR/$tdir
18622         mkdir $DIR/$tdir/normal_dir
18623
18624         #Checking when client cache stripe index
18625         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18626         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18627                 error "create striped_dir failed"
18628
18629         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18630                 error "create dir0 fails"
18631         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18632         [ $stripe_index -eq 0 ] ||
18633                 error "dir0 expect index 0 got $stripe_index"
18634
18635         mkdir $DIR/$tdir/striped_dir/dir1 ||
18636                 error "create dir1 fails"
18637         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18638         [ $stripe_index -eq 1 ] ||
18639                 error "dir1 expect index 1 got $stripe_index"
18640
18641         #check default stripe count/stripe index
18642         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18643         test_300_check_default_striped_dir normal_dir 1 0
18644         test_300_check_default_striped_dir normal_dir 2 1
18645         test_300_check_default_striped_dir normal_dir 2 -1
18646
18647         #delete default stripe information
18648         echo "delete default stripeEA"
18649         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18650                 error "set default stripe on striped dir error"
18651
18652         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18653         for dir in $(find $DIR/$tdir/normal_dir/*); do
18654                 stripe_count=$($LFS getdirstripe -c $dir)
18655                 [ $stripe_count -eq 0 ] ||
18656                         error "expect 1 get $stripe_count for $dir"
18657                 stripe_index=$($LFS getdirstripe -i $dir)
18658                 [ $stripe_index -eq 0 ] ||
18659                         error "expect 0 get $stripe_index for $dir"
18660         done
18661 }
18662 run_test 300g "check default striped directory for normal directory"
18663
18664 test_300h() {
18665         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18666         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18667                 skip "Need MDS version at least 2.7.55"
18668
18669         local dir
18670         local stripe_count
18671
18672         mkdir $DIR/$tdir
18673         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18674                 error "set striped dir error"
18675
18676         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18677         test_300_check_default_striped_dir striped_dir 1 0
18678         test_300_check_default_striped_dir striped_dir 2 1
18679         test_300_check_default_striped_dir striped_dir 2 -1
18680
18681         #delete default stripe information
18682         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18683                 error "set default stripe on striped dir error"
18684
18685         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18686         for dir in $(find $DIR/$tdir/striped_dir/*); do
18687                 stripe_count=$($LFS getdirstripe -c $dir)
18688                 [ $stripe_count -eq 0 ] ||
18689                         error "expect 1 get $stripe_count for $dir"
18690         done
18691 }
18692 run_test 300h "check default striped directory for striped directory"
18693
18694 test_300i() {
18695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18696         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18697         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18698                 skip "Need MDS version at least 2.7.55"
18699
18700         local stripe_count
18701         local file
18702
18703         mkdir $DIR/$tdir
18704
18705         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18706                 error "set striped dir error"
18707
18708         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18709                 error "create files under striped dir failed"
18710
18711         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18712                 error "set striped hashdir error"
18713
18714         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18715                 error "create dir0 under hash dir failed"
18716         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18717                 error "create dir1 under hash dir failed"
18718
18719         # unfortunately, we need to umount to clear dir layout cache for now
18720         # once we fully implement dir layout, we can drop this
18721         umount_client $MOUNT || error "umount failed"
18722         mount_client $MOUNT || error "mount failed"
18723
18724         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18725         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18726         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18727
18728         #set the stripe to be unknown hash type
18729         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18730         $LCTL set_param fail_loc=0x1901
18731         for ((i = 0; i < 10; i++)); do
18732                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18733                         error "stat f-$i failed"
18734                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18735         done
18736
18737         touch $DIR/$tdir/striped_dir/f0 &&
18738                 error "create under striped dir with unknown hash should fail"
18739
18740         $LCTL set_param fail_loc=0
18741
18742         umount_client $MOUNT || error "umount failed"
18743         mount_client $MOUNT || error "mount failed"
18744
18745         return 0
18746 }
18747 run_test 300i "client handle unknown hash type striped directory"
18748
18749 test_300j() {
18750         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18752         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18753                 skip "Need MDS version at least 2.7.55"
18754
18755         local stripe_count
18756         local file
18757
18758         mkdir $DIR/$tdir
18759
18760         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18761         $LCTL set_param fail_loc=0x1702
18762         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18763                 error "set striped dir error"
18764
18765         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18766                 error "create files under striped dir failed"
18767
18768         $LCTL set_param fail_loc=0
18769
18770         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18771
18772         return 0
18773 }
18774 run_test 300j "test large update record"
18775
18776 test_300k() {
18777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18778         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18779         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18780                 skip "Need MDS version at least 2.7.55"
18781
18782         # this test needs a huge transaction
18783         local kb
18784         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18785         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18786
18787         local stripe_count
18788         local file
18789
18790         mkdir $DIR/$tdir
18791
18792         #define OBD_FAIL_LARGE_STRIPE   0x1703
18793         $LCTL set_param fail_loc=0x1703
18794         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18795                 error "set striped dir error"
18796         $LCTL set_param fail_loc=0
18797
18798         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18799                 error "getstripeddir fails"
18800         rm -rf $DIR/$tdir/striped_dir ||
18801                 error "unlink striped dir fails"
18802
18803         return 0
18804 }
18805 run_test 300k "test large striped directory"
18806
18807 test_300l() {
18808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18809         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18810         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18811                 skip "Need MDS version at least 2.7.55"
18812
18813         local stripe_index
18814
18815         test_mkdir -p $DIR/$tdir/striped_dir
18816         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18817                         error "chown $RUNAS_ID failed"
18818         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18819                 error "set default striped dir failed"
18820
18821         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18822         $LCTL set_param fail_loc=0x80000158
18823         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18824
18825         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18826         [ $stripe_index -eq 1 ] ||
18827                 error "expect 1 get $stripe_index for $dir"
18828 }
18829 run_test 300l "non-root user to create dir under striped dir with stale layout"
18830
18831 test_300m() {
18832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18833         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18834         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18835                 skip "Need MDS version at least 2.7.55"
18836
18837         mkdir -p $DIR/$tdir/striped_dir
18838         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18839                 error "set default stripes dir error"
18840
18841         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18842
18843         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18844         [ $stripe_count -eq 0 ] ||
18845                         error "expect 0 get $stripe_count for a"
18846
18847         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18848                 error "set default stripes dir error"
18849
18850         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
18851
18852         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
18853         [ $stripe_count -eq 0 ] ||
18854                         error "expect 0 get $stripe_count for b"
18855
18856         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
18857                 error "set default stripes dir error"
18858
18859         mkdir $DIR/$tdir/striped_dir/c &&
18860                 error "default stripe_index is invalid, mkdir c should fails"
18861
18862         rm -rf $DIR/$tdir || error "rmdir fails"
18863 }
18864 run_test 300m "setstriped directory on single MDT FS"
18865
18866 cleanup_300n() {
18867         local list=$(comma_list $(mdts_nodes))
18868
18869         trap 0
18870         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18871 }
18872
18873 test_300n() {
18874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18875         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18876         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18877                 skip "Need MDS version at least 2.7.55"
18878         remote_mds_nodsh && skip "remote MDS with nodsh"
18879
18880         local stripe_index
18881         local list=$(comma_list $(mdts_nodes))
18882
18883         trap cleanup_300n RETURN EXIT
18884         mkdir -p $DIR/$tdir
18885         chmod 777 $DIR/$tdir
18886         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
18887                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18888                 error "create striped dir succeeds with gid=0"
18889
18890         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18891         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
18892                 error "create striped dir fails with gid=-1"
18893
18894         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18895         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
18896                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18897                 error "set default striped dir succeeds with gid=0"
18898
18899
18900         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18901         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
18902                 error "set default striped dir fails with gid=-1"
18903
18904
18905         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18906         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
18907                                         error "create test_dir fails"
18908         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
18909                                         error "create test_dir1 fails"
18910         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
18911                                         error "create test_dir2 fails"
18912         cleanup_300n
18913 }
18914 run_test 300n "non-root user to create dir under striped dir with default EA"
18915
18916 test_300o() {
18917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18918         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18919         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18920                 skip "Need MDS version at least 2.7.55"
18921
18922         local numfree1
18923         local numfree2
18924
18925         mkdir -p $DIR/$tdir
18926
18927         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
18928         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
18929         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
18930                 skip "not enough free inodes $numfree1 $numfree2"
18931         fi
18932
18933         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
18934         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
18935         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
18936                 skip "not enough free space $numfree1 $numfree2"
18937         fi
18938
18939         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
18940                 error "setdirstripe fails"
18941
18942         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
18943                 error "create dirs fails"
18944
18945         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
18946         ls $DIR/$tdir/striped_dir > /dev/null ||
18947                 error "ls striped dir fails"
18948         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
18949                 error "unlink big striped dir fails"
18950 }
18951 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
18952
18953 test_300p() {
18954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18955         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18956         remote_mds_nodsh && skip "remote MDS with nodsh"
18957
18958         mkdir -p $DIR/$tdir
18959
18960         #define OBD_FAIL_OUT_ENOSPC     0x1704
18961         do_facet mds2 lctl set_param fail_loc=0x80001704
18962         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
18963                  && error "create striped directory should fail"
18964
18965         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
18966
18967         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
18968         true
18969 }
18970 run_test 300p "create striped directory without space"
18971
18972 test_300q() {
18973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18974         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18975
18976         local fd=$(free_fd)
18977         local cmd="exec $fd<$tdir"
18978         cd $DIR
18979         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
18980         eval $cmd
18981         cmd="exec $fd<&-"
18982         trap "eval $cmd" EXIT
18983         cd $tdir || error "cd $tdir fails"
18984         rmdir  ../$tdir || error "rmdir $tdir fails"
18985         mkdir local_dir && error "create dir succeeds"
18986         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
18987         eval $cmd
18988         return 0
18989 }
18990 run_test 300q "create remote directory under orphan directory"
18991
18992 test_300r() {
18993         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
18994                 skip "Need MDS version at least 2.7.55" && return
18995         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18996
18997         mkdir $DIR/$tdir
18998
18999         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
19000                 error "set striped dir error"
19001
19002         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19003                 error "getstripeddir fails"
19004
19005         local stripe_count
19006         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19007                       awk '/lmv_stripe_count:/ { print $2 }')
19008
19009         [ $MDSCOUNT -ne $stripe_count ] &&
19010                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
19011
19012         rm -rf $DIR/$tdir/striped_dir ||
19013                 error "unlink striped dir fails"
19014 }
19015 run_test 300r "test -1 striped directory"
19016
19017 prepare_remote_file() {
19018         mkdir $DIR/$tdir/src_dir ||
19019                 error "create remote source failed"
19020
19021         cp /etc/hosts $DIR/$tdir/src_dir/a ||
19022                  error "cp to remote source failed"
19023         touch $DIR/$tdir/src_dir/a
19024
19025         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
19026                 error "create remote target dir failed"
19027
19028         touch $DIR/$tdir/tgt_dir/b
19029
19030         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
19031                 error "rename dir cross MDT failed!"
19032
19033         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
19034                 error "src_child still exists after rename"
19035
19036         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
19037                 error "missing file(a) after rename"
19038
19039         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
19040                 error "diff after rename"
19041 }
19042
19043 test_310a() {
19044         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19046
19047         local remote_file=$DIR/$tdir/tgt_dir/b
19048
19049         mkdir -p $DIR/$tdir
19050
19051         prepare_remote_file || error "prepare remote file failed"
19052
19053         #open-unlink file
19054         $OPENUNLINK $remote_file $remote_file ||
19055                 error "openunlink $remote_file failed"
19056         $CHECKSTAT -a $remote_file || error "$remote_file exists"
19057 }
19058 run_test 310a "open unlink remote file"
19059
19060 test_310b() {
19061         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19063
19064         local remote_file=$DIR/$tdir/tgt_dir/b
19065
19066         mkdir -p $DIR/$tdir
19067
19068         prepare_remote_file || error "prepare remote file failed"
19069
19070         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19071         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
19072         $CHECKSTAT -t file $remote_file || error "check file failed"
19073 }
19074 run_test 310b "unlink remote file with multiple links while open"
19075
19076 test_310c() {
19077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19078         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
19079
19080         local remote_file=$DIR/$tdir/tgt_dir/b
19081
19082         mkdir -p $DIR/$tdir
19083
19084         prepare_remote_file || error "prepare remote file failed"
19085
19086         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19087         multiop_bg_pause $remote_file O_uc ||
19088                         error "mulitop failed for remote file"
19089         MULTIPID=$!
19090         $MULTIOP $DIR/$tfile Ouc
19091         kill -USR1 $MULTIPID
19092         wait $MULTIPID
19093 }
19094 run_test 310c "open-unlink remote file with multiple links"
19095
19096 #LU-4825
19097 test_311() {
19098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19099         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19100         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
19101                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
19102         remote_mds_nodsh && skip "remote MDS with nodsh"
19103
19104         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19105         local mdts=$(comma_list $(mdts_nodes))
19106
19107         mkdir -p $DIR/$tdir
19108         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19109         createmany -o $DIR/$tdir/$tfile. 1000
19110
19111         # statfs data is not real time, let's just calculate it
19112         old_iused=$((old_iused + 1000))
19113
19114         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19115                         osp.*OST0000*MDT0000.create_count")
19116         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19117                                 osp.*OST0000*MDT0000.max_create_count")
19118         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
19119
19120         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
19121         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
19122         [ $index -ne 0 ] || error "$tfile stripe index is 0"
19123
19124         unlinkmany $DIR/$tdir/$tfile. 1000
19125
19126         do_nodes $mdts "$LCTL set_param -n \
19127                         osp.*OST0000*.max_create_count=$max_count"
19128         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
19129                 do_nodes $mdts "$LCTL set_param -n \
19130                                 osp.*OST0000*.create_count=$count"
19131         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
19132                         grep "=0" && error "create_count is zero"
19133
19134         local new_iused
19135         for i in $(seq 120); do
19136                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19137                 # system may be too busy to destroy all objs in time, use
19138                 # a somewhat small value to not fail autotest
19139                 [ $((old_iused - new_iused)) -gt 400 ] && break
19140                 sleep 1
19141         done
19142
19143         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
19144         [ $((old_iused - new_iused)) -gt 400 ] ||
19145                 error "objs not destroyed after unlink"
19146 }
19147 run_test 311 "disable OSP precreate, and unlink should destroy objs"
19148
19149 zfs_oid_to_objid()
19150 {
19151         local ost=$1
19152         local objid=$2
19153
19154         local vdevdir=$(dirname $(facet_vdevice $ost))
19155         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
19156         local zfs_zapid=$(do_facet $ost $cmd |
19157                           grep -w "/O/0/d$((objid%32))" -C 5 |
19158                           awk '/Object/{getline; print $1}')
19159         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
19160                           awk "/$objid = /"'{printf $3}')
19161
19162         echo $zfs_objid
19163 }
19164
19165 zfs_object_blksz() {
19166         local ost=$1
19167         local objid=$2
19168
19169         local vdevdir=$(dirname $(facet_vdevice $ost))
19170         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
19171         local blksz=$(do_facet $ost $cmd $objid |
19172                       awk '/dblk/{getline; printf $4}')
19173
19174         case "${blksz: -1}" in
19175                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
19176                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
19177                 *) ;;
19178         esac
19179
19180         echo $blksz
19181 }
19182
19183 test_312() { # LU-4856
19184         remote_ost_nodsh && skip "remote OST with nodsh"
19185         [ "$ost1_FSTYPE" = "zfs" ] ||
19186                 skip_env "the test only applies to zfs"
19187
19188         local max_blksz=$(do_facet ost1 \
19189                           $ZFS get -p recordsize $(facet_device ost1) |
19190                           awk '!/VALUE/{print $3}')
19191
19192         # to make life a little bit easier
19193         $LFS mkdir -c 1 -i 0 $DIR/$tdir
19194         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19195
19196         local tf=$DIR/$tdir/$tfile
19197         touch $tf
19198         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19199
19200         # Get ZFS object id
19201         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19202         # block size change by sequential overwrite
19203         local bs
19204
19205         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
19206                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
19207
19208                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
19209                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
19210         done
19211         rm -f $tf
19212
19213         # block size change by sequential append write
19214         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
19215         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19216         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19217         local count
19218
19219         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
19220                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
19221                         oflag=sync conv=notrunc
19222
19223                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
19224                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
19225                         error "blksz error, actual $blksz, " \
19226                                 "expected: 2 * $count * $PAGE_SIZE"
19227         done
19228         rm -f $tf
19229
19230         # random write
19231         touch $tf
19232         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19233         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19234
19235         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
19236         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19237         [ $blksz -eq $PAGE_SIZE ] ||
19238                 error "blksz error: $blksz, expected: $PAGE_SIZE"
19239
19240         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
19241         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19242         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
19243
19244         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
19245         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19246         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
19247 }
19248 run_test 312 "make sure ZFS adjusts its block size by write pattern"
19249
19250 test_313() {
19251         remote_ost_nodsh && skip "remote OST with nodsh"
19252
19253         local file=$DIR/$tfile
19254
19255         rm -f $file
19256         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
19257
19258         # define OBD_FAIL_TGT_RCVD_EIO           0x720
19259         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19260         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
19261                 error "write should failed"
19262         do_facet ost1 "$LCTL set_param fail_loc=0"
19263         rm -f $file
19264 }
19265 run_test 313 "io should fail after last_rcvd update fail"
19266
19267 test_314() {
19268         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19269
19270         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
19271         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19272         rm -f $DIR/$tfile
19273         wait_delete_completed
19274         do_facet ost1 "$LCTL set_param fail_loc=0"
19275 }
19276 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
19277
19278 test_315() { # LU-618
19279         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
19280
19281         local file=$DIR/$tfile
19282         rm -f $file
19283
19284         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
19285                 error "multiop file write failed"
19286         $MULTIOP $file oO_RDONLY:r4063232_c &
19287         PID=$!
19288
19289         sleep 2
19290
19291         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
19292         kill -USR1 $PID
19293
19294         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
19295         rm -f $file
19296 }
19297 run_test 315 "read should be accounted"
19298
19299 test_316() {
19300         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19301         large_xattr_enabled || skip_env "ea_inode feature disabled"
19302
19303         rm -rf $DIR/$tdir/d
19304         mkdir -p $DIR/$tdir/d
19305         chown nobody $DIR/$tdir/d
19306         touch $DIR/$tdir/d/file
19307
19308         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
19309 }
19310 run_test 316 "lfs mv"
19311
19312 test_317() {
19313         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
19314                 skip "Need MDS version at least 2.11.53"
19315         local trunc_sz
19316         local grant_blk_size
19317
19318         if [ "$(facet_fstype $facet)" == "zfs" ]; then
19319                 skip "LU-10370: no implementation for ZFS" && return
19320         fi
19321
19322         stack_trap "rm -f $DIR/$tfile" EXIT
19323         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
19324                         awk '/grant_block_size:/ { print $2; exit; }')
19325         #
19326         # Create File of size 5M. Truncate it to below size's and verify
19327         # blocks count.
19328         #
19329         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
19330                 error "Create file : $DIR/$tfile"
19331
19332         for trunc_sz in 2097152 4097 4000 509 0; do
19333                 $TRUNCATE $DIR/$tfile $trunc_sz ||
19334                         error "truncate $tfile to $trunc_sz failed"
19335                 local sz=$(stat --format=%s $DIR/$tfile)
19336                 local blk=$(stat --format=%b $DIR/$tfile)
19337                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
19338                                      grant_blk_size) * 8))
19339
19340                 if [[ $blk -ne $trunc_blk ]]; then
19341                         $(which stat) $DIR/$tfile
19342                         error "Expected Block $trunc_blk got $blk for $tfile"
19343                 fi
19344
19345                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19346                         error "Expected Size $trunc_sz got $sz for $tfile"
19347         done
19348
19349         #
19350         # sparse file test
19351         # Create file with a hole and write actual two blocks. Block count
19352         # must be 16.
19353         #
19354         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
19355                 conv=fsync || error "Create file : $DIR/$tfile"
19356
19357         # Calculate the final truncate size.
19358         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
19359
19360         #
19361         # truncate to size $trunc_sz bytes. Strip the last block
19362         # The block count must drop to 8
19363         #
19364         $TRUNCATE $DIR/$tfile $trunc_sz ||
19365                 error "truncate $tfile to $trunc_sz failed"
19366
19367         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
19368         sz=$(stat --format=%s $DIR/$tfile)
19369         blk=$(stat --format=%b $DIR/$tfile)
19370
19371         if [[ $blk -ne $trunc_bsz ]]; then
19372                 $(which stat) $DIR/$tfile
19373                 error "Expected Block $trunc_bsz got $blk for $tfile"
19374         fi
19375
19376         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19377                 error "Expected Size $trunc_sz got $sz for $tfile"
19378 }
19379 run_test 317 "Verify blocks get correctly update after truncate"
19380
19381 test_318() {
19382         local old_max_active=$($LCTL get_param -n \
19383                             llite.*.max_read_ahead_async_active 2>/dev/null)
19384
19385         $LCTL set_param llite.*.max_read_ahead_async_active=256
19386         local max_active=$($LCTL get_param -n \
19387                            llite.*.max_read_ahead_async_active 2>/dev/null)
19388         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
19389
19390         # currently reset to 0 is unsupported, leave it 512 for now.
19391         $LCTL set_param llite.*.max_read_ahead_async_active=0 &&
19392                 error "set max_read_ahead_async_active should fail"
19393
19394         $LCTL set_param llite.*.max_read_ahead_async_active=512
19395         max_active=$($LCTL get_param -n \
19396                      llite.*.max_read_ahead_async_active 2>/dev/null)
19397         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
19398
19399         # restore @max_active
19400         [ $old_max_active -ne 0 ] && $LCTL set_param \
19401                 llite.*.max_read_ahead_async_active=$old_max_active
19402
19403         local old_threshold=$($LCTL get_param -n \
19404                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
19405         local max_per_file_mb=$($LCTL get_param -n \
19406                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
19407
19408         local invalid=$(($max_per_file_mb + 1))
19409         $LCTL set_param \
19410                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
19411                         && error "set $invalid should fail"
19412
19413         local valid=$(($invalid - 1))
19414         $LCTL set_param \
19415                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
19416                         error "set $valid should succeed"
19417         local threshold=$($LCTL get_param -n \
19418                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
19419         [ $threshold -eq $valid ] || error \
19420                 "expect threshold $valid got $threshold"
19421         $LCTL set_param \
19422                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
19423 }
19424 run_test 318 "Verify async readahead tunables"
19425
19426 test_319() {
19427         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
19428
19429         local before=$(date +%s)
19430         local evict
19431         local mdir=$DIR/$tdir
19432         local file=$mdir/xxx
19433
19434         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
19435         touch $file
19436
19437 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
19438         $LCTL set_param fail_val=5 fail_loc=0x8000032c
19439         $LFS mv -m1 $file &
19440
19441         sleep 1
19442         dd if=$file of=/dev/null
19443         wait
19444         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
19445           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
19446
19447         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
19448 }
19449 run_test 319 "lost lease lock on migrate error"
19450
19451 test_fake_rw() {
19452         local read_write=$1
19453         if [ "$read_write" = "write" ]; then
19454                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
19455         elif [ "$read_write" = "read" ]; then
19456                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
19457         else
19458                 error "argument error"
19459         fi
19460
19461         # turn off debug for performance testing
19462         local saved_debug=$($LCTL get_param -n debug)
19463         $LCTL set_param debug=0
19464
19465         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19466
19467         # get ost1 size - lustre-OST0000
19468         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
19469         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
19470         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
19471
19472         if [ "$read_write" = "read" ]; then
19473                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
19474         fi
19475
19476         local start_time=$(date +%s.%N)
19477         $dd_cmd bs=1M count=$blocks oflag=sync ||
19478                 error "real dd $read_write error"
19479         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
19480
19481         if [ "$read_write" = "write" ]; then
19482                 rm -f $DIR/$tfile
19483         fi
19484
19485         # define OBD_FAIL_OST_FAKE_RW           0x238
19486         do_facet ost1 $LCTL set_param fail_loc=0x238
19487
19488         local start_time=$(date +%s.%N)
19489         $dd_cmd bs=1M count=$blocks oflag=sync ||
19490                 error "fake dd $read_write error"
19491         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
19492
19493         if [ "$read_write" = "write" ]; then
19494                 # verify file size
19495                 cancel_lru_locks osc
19496                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
19497                         error "$tfile size not $blocks MB"
19498         fi
19499         do_facet ost1 $LCTL set_param fail_loc=0
19500
19501         echo "fake $read_write $duration_fake vs. normal $read_write" \
19502                 "$duration in seconds"
19503         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
19504                 error_not_in_vm "fake write is slower"
19505
19506         $LCTL set_param -n debug="$saved_debug"
19507         rm -f $DIR/$tfile
19508 }
19509 test_399a() { # LU-7655 for OST fake write
19510         remote_ost_nodsh && skip "remote OST with nodsh"
19511
19512         test_fake_rw write
19513 }
19514 run_test 399a "fake write should not be slower than normal write"
19515
19516 test_399b() { # LU-8726 for OST fake read
19517         remote_ost_nodsh && skip "remote OST with nodsh"
19518         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
19519                 skip_env "ldiskfs only test"
19520         fi
19521
19522         test_fake_rw read
19523 }
19524 run_test 399b "fake read should not be slower than normal read"
19525
19526 test_400a() { # LU-1606, was conf-sanity test_74
19527         if ! which $CC > /dev/null 2>&1; then
19528                 skip_env "$CC is not installed"
19529         fi
19530
19531         local extra_flags=''
19532         local out=$TMP/$tfile
19533         local prefix=/usr/include/lustre
19534         local prog
19535
19536         if ! [[ -d $prefix ]]; then
19537                 # Assume we're running in tree and fixup the include path.
19538                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
19539                 extra_flags+=" -L$LUSTRE/utils/.lib"
19540         fi
19541
19542         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
19543                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
19544                         error "client api broken"
19545         done
19546         rm -f $out
19547 }
19548 run_test 400a "Lustre client api program can compile and link"
19549
19550 test_400b() { # LU-1606, LU-5011
19551         local header
19552         local out=$TMP/$tfile
19553         local prefix=/usr/include/linux/lustre
19554
19555         # We use a hard coded prefix so that this test will not fail
19556         # when run in tree. There are headers in lustre/include/lustre/
19557         # that are not packaged (like lustre_idl.h) and have more
19558         # complicated include dependencies (like config.h and lnet/types.h).
19559         # Since this test about correct packaging we just skip them when
19560         # they don't exist (see below) rather than try to fixup cppflags.
19561
19562         if ! which $CC > /dev/null 2>&1; then
19563                 skip_env "$CC is not installed"
19564         fi
19565
19566         for header in $prefix/*.h; do
19567                 if ! [[ -f "$header" ]]; then
19568                         continue
19569                 fi
19570
19571                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19572                         continue # lustre_ioctl.h is internal header
19573                 fi
19574
19575                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19576                         error "cannot compile '$header'"
19577         done
19578         rm -f $out
19579 }
19580 run_test 400b "packaged headers can be compiled"
19581
19582 test_401a() { #LU-7437
19583         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19584         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19585
19586         #count the number of parameters by "list_param -R"
19587         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19588         #count the number of parameters by listing proc files
19589         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19590         echo "proc_dirs='$proc_dirs'"
19591         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19592         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19593                       sort -u | wc -l)
19594
19595         [ $params -eq $procs ] ||
19596                 error "found $params parameters vs. $procs proc files"
19597
19598         # test the list_param -D option only returns directories
19599         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19600         #count the number of parameters by listing proc directories
19601         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19602                 sort -u | wc -l)
19603
19604         [ $params -eq $procs ] ||
19605                 error "found $params parameters vs. $procs proc files"
19606 }
19607 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19608
19609 test_401b() {
19610         local save=$($LCTL get_param -n jobid_var)
19611         local tmp=testing
19612
19613         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19614                 error "no error returned when setting bad parameters"
19615
19616         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19617         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19618
19619         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19620         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19621         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19622 }
19623 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19624
19625 test_401c() {
19626         local jobid_var_old=$($LCTL get_param -n jobid_var)
19627         local jobid_var_new
19628
19629         $LCTL set_param jobid_var= &&
19630                 error "no error returned for 'set_param a='"
19631
19632         jobid_var_new=$($LCTL get_param -n jobid_var)
19633         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19634                 error "jobid_var was changed by setting without value"
19635
19636         $LCTL set_param jobid_var &&
19637                 error "no error returned for 'set_param a'"
19638
19639         jobid_var_new=$($LCTL get_param -n jobid_var)
19640         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19641                 error "jobid_var was changed by setting without value"
19642 }
19643 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19644
19645 test_401d() {
19646         local jobid_var_old=$($LCTL get_param -n jobid_var)
19647         local jobid_var_new
19648         local new_value="foo=bar"
19649
19650         $LCTL set_param jobid_var=$new_value ||
19651                 error "'set_param a=b' did not accept a value containing '='"
19652
19653         jobid_var_new=$($LCTL get_param -n jobid_var)
19654         [[ "$jobid_var_new" == "$new_value" ]] ||
19655                 error "'set_param a=b' failed on a value containing '='"
19656
19657         # Reset the jobid_var to test the other format
19658         $LCTL set_param jobid_var=$jobid_var_old
19659         jobid_var_new=$($LCTL get_param -n jobid_var)
19660         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19661                 error "failed to reset jobid_var"
19662
19663         $LCTL set_param jobid_var $new_value ||
19664                 error "'set_param a b' did not accept a value containing '='"
19665
19666         jobid_var_new=$($LCTL get_param -n jobid_var)
19667         [[ "$jobid_var_new" == "$new_value" ]] ||
19668                 error "'set_param a b' failed on a value containing '='"
19669
19670         $LCTL set_param jobid_var $jobid_var_old
19671         jobid_var_new=$($LCTL get_param -n jobid_var)
19672         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19673                 error "failed to reset jobid_var"
19674 }
19675 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19676
19677 test_402() {
19678         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19679         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19680                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19681         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19682                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19683                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19684         remote_mds_nodsh && skip "remote MDS with nodsh"
19685
19686         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19687 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19688         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19689         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19690                 echo "Touch failed - OK"
19691 }
19692 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19693
19694 test_403() {
19695         local file1=$DIR/$tfile.1
19696         local file2=$DIR/$tfile.2
19697         local tfile=$TMP/$tfile
19698
19699         rm -f $file1 $file2 $tfile
19700
19701         touch $file1
19702         ln $file1 $file2
19703
19704         # 30 sec OBD_TIMEOUT in ll_getattr()
19705         # right before populating st_nlink
19706         $LCTL set_param fail_loc=0x80001409
19707         stat -c %h $file1 > $tfile &
19708
19709         # create an alias, drop all locks and reclaim the dentry
19710         < $file2
19711         cancel_lru_locks mdc
19712         cancel_lru_locks osc
19713         sysctl -w vm.drop_caches=2
19714
19715         wait
19716
19717         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19718
19719         rm -f $tfile $file1 $file2
19720 }
19721 run_test 403 "i_nlink should not drop to zero due to aliasing"
19722
19723 test_404() { # LU-6601
19724         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19725                 skip "Need server version newer than 2.8.52"
19726         remote_mds_nodsh && skip "remote MDS with nodsh"
19727
19728         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19729                 awk '/osp .*-osc-MDT/ { print $4}')
19730
19731         local osp
19732         for osp in $mosps; do
19733                 echo "Deactivate: " $osp
19734                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19735                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19736                         awk -vp=$osp '$4 == p { print $2 }')
19737                 [ $stat = IN ] || {
19738                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19739                         error "deactivate error"
19740                 }
19741                 echo "Activate: " $osp
19742                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19743                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19744                         awk -vp=$osp '$4 == p { print $2 }')
19745                 [ $stat = UP ] || {
19746                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19747                         error "activate error"
19748                 }
19749         done
19750 }
19751 run_test 404 "validate manual {de}activated works properly for OSPs"
19752
19753 test_405() {
19754         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19755         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
19756                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19757                         skip "Layout swap lock is not supported"
19758
19759         check_swap_layouts_support
19760
19761         test_mkdir $DIR/$tdir
19762         swap_lock_test -d $DIR/$tdir ||
19763                 error "One layout swap locked test failed"
19764 }
19765 run_test 405 "Various layout swap lock tests"
19766
19767 test_406() {
19768         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19769         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19770         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19772         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19773                 skip "Need MDS version at least 2.8.50"
19774
19775         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19776         local test_pool=$TESTNAME
19777
19778         if ! combined_mgs_mds ; then
19779                 mount_mgs_client
19780         fi
19781         pool_add $test_pool || error "pool_add failed"
19782         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19783                 error "pool_add_targets failed"
19784
19785         save_layout_restore_at_exit $MOUNT
19786
19787         # parent set default stripe count only, child will stripe from both
19788         # parent and fs default
19789         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19790                 error "setstripe $MOUNT failed"
19791         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19792         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19793         for i in $(seq 10); do
19794                 local f=$DIR/$tdir/$tfile.$i
19795                 touch $f || error "touch failed"
19796                 local count=$($LFS getstripe -c $f)
19797                 [ $count -eq $OSTCOUNT ] ||
19798                         error "$f stripe count $count != $OSTCOUNT"
19799                 local offset=$($LFS getstripe -i $f)
19800                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19801                 local size=$($LFS getstripe -S $f)
19802                 [ $size -eq $((def_stripe_size * 2)) ] ||
19803                         error "$f stripe size $size != $((def_stripe_size * 2))"
19804                 local pool=$($LFS getstripe -p $f)
19805                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19806         done
19807
19808         # change fs default striping, delete parent default striping, now child
19809         # will stripe from new fs default striping only
19810         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19811                 error "change $MOUNT default stripe failed"
19812         $LFS setstripe -c 0 $DIR/$tdir ||
19813                 error "delete $tdir default stripe failed"
19814         for i in $(seq 11 20); do
19815                 local f=$DIR/$tdir/$tfile.$i
19816                 touch $f || error "touch $f failed"
19817                 local count=$($LFS getstripe -c $f)
19818                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19819                 local offset=$($LFS getstripe -i $f)
19820                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19821                 local size=$($LFS getstripe -S $f)
19822                 [ $size -eq $def_stripe_size ] ||
19823                         error "$f stripe size $size != $def_stripe_size"
19824                 local pool=$($LFS getstripe -p $f)
19825                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19826         done
19827
19828         unlinkmany $DIR/$tdir/$tfile. 1 20
19829
19830         local f=$DIR/$tdir/$tfile
19831         pool_remove_all_targets $test_pool $f
19832         pool_remove $test_pool $f
19833
19834         if ! combined_mgs_mds ; then
19835                 umount_mgs_client
19836         fi
19837 }
19838 run_test 406 "DNE support fs default striping"
19839
19840 test_407() {
19841         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19842         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19843                 skip "Need MDS version at least 2.8.55"
19844         remote_mds_nodsh && skip "remote MDS with nodsh"
19845
19846         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19847                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19848         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19849                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19850         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
19851
19852         #define OBD_FAIL_DT_TXN_STOP    0x2019
19853         for idx in $(seq $MDSCOUNT); do
19854                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
19855         done
19856         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
19857         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
19858                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
19859         true
19860 }
19861 run_test 407 "transaction fail should cause operation fail"
19862
19863 test_408() {
19864         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
19865
19866         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
19867         lctl set_param fail_loc=0x8000040a
19868         # let ll_prepare_partial_page() fail
19869         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
19870
19871         rm -f $DIR/$tfile
19872
19873         # create at least 100 unused inodes so that
19874         # shrink_icache_memory(0) should not return 0
19875         touch $DIR/$tfile-{0..100}
19876         rm -f $DIR/$tfile-{0..100}
19877         sync
19878
19879         echo 2 > /proc/sys/vm/drop_caches
19880 }
19881 run_test 408 "drop_caches should not hang due to page leaks"
19882
19883 test_409()
19884 {
19885         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19886
19887         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
19888         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
19889         touch $DIR/$tdir/guard || error "(2) Fail to create"
19890
19891         local PREFIX=$(str_repeat 'A' 128)
19892         echo "Create 1K hard links start at $(date)"
19893         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19894                 error "(3) Fail to hard link"
19895
19896         echo "Links count should be right although linkEA overflow"
19897         stat $DIR/$tdir/guard || error "(4) Fail to stat"
19898         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
19899         [ $linkcount -eq 1001 ] ||
19900                 error "(5) Unexpected hard links count: $linkcount"
19901
19902         echo "List all links start at $(date)"
19903         ls -l $DIR/$tdir/foo > /dev/null ||
19904                 error "(6) Fail to list $DIR/$tdir/foo"
19905
19906         echo "Unlink hard links start at $(date)"
19907         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19908                 error "(7) Fail to unlink"
19909         echo "Unlink hard links finished at $(date)"
19910 }
19911 run_test 409 "Large amount of cross-MDTs hard links on the same file"
19912
19913 test_410()
19914 {
19915         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
19916                 skip "Need client version at least 2.9.59"
19917
19918         # Create a file, and stat it from the kernel
19919         local testfile=$DIR/$tfile
19920         touch $testfile
19921
19922         local run_id=$RANDOM
19923         local my_ino=$(stat --format "%i" $testfile)
19924
19925         # Try to insert the module. This will always fail as the
19926         # module is designed to not be inserted.
19927         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
19928             &> /dev/null
19929
19930         # Anything but success is a test failure
19931         dmesg | grep -q \
19932             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
19933             error "no inode match"
19934 }
19935 run_test 410 "Test inode number returned from kernel thread"
19936
19937 cleanup_test411_cgroup() {
19938         trap 0
19939         rmdir "$1"
19940 }
19941
19942 test_411() {
19943         local cg_basedir=/sys/fs/cgroup/memory
19944         # LU-9966
19945         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
19946                 skip "no setup for cgroup"
19947
19948         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
19949                 error "test file creation failed"
19950         cancel_lru_locks osc
19951
19952         # Create a very small memory cgroup to force a slab allocation error
19953         local cgdir=$cg_basedir/osc_slab_alloc
19954         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
19955         trap "cleanup_test411_cgroup $cgdir" EXIT
19956         echo 2M > $cgdir/memory.kmem.limit_in_bytes
19957         echo 1M > $cgdir/memory.limit_in_bytes
19958
19959         # Should not LBUG, just be killed by oom-killer
19960         # dd will return 0 even allocation failure in some environment.
19961         # So don't check return value
19962         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
19963         cleanup_test411_cgroup $cgdir
19964
19965         return 0
19966 }
19967 run_test 411 "Slab allocation error with cgroup does not LBUG"
19968
19969 test_412() {
19970         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19971         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19972                 skip "Need server version at least 2.10.55"
19973         fi
19974
19975         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
19976                 error "mkdir failed"
19977         $LFS getdirstripe $DIR/$tdir
19978         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19979         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
19980                 error "expect $((MDSCOUT - 1)) get $stripe_index"
19981         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
19982         [ $stripe_count -eq 2 ] ||
19983                 error "expect 2 get $stripe_count"
19984 }
19985 run_test 412 "mkdir on specific MDTs"
19986
19987 test_413a() {
19988         [ $MDSCOUNT -lt 2 ] &&
19989                 skip "We need at least 2 MDTs for this test"
19990
19991         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19992                 skip "Need server version at least 2.10.55"
19993         fi
19994
19995         mkdir $DIR/$tdir || error "mkdir failed"
19996
19997         # find MDT that is the most full
19998         local max=$($LFS df | grep MDT |
19999                 awk 'BEGIN { a=0 }
20000                         { sub("%", "", $5)
20001                           if (0+$5 >= a)
20002                           {
20003                                 a = $5
20004                                 b = $6
20005                           }
20006                         }
20007                      END { split(b, c, ":")
20008                            sub("]", "", c[2])
20009                            print c[2]
20010                          }')
20011
20012         for i in $(seq $((MDSCOUNT - 1))); do
20013                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
20014                         error "mkdir d$i failed"
20015                 $LFS getdirstripe $DIR/$tdir/d$i
20016                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
20017                 [ $stripe_index -ne $max ] ||
20018                         error "don't expect $max"
20019         done
20020 }
20021 run_test 413a "mkdir on less full MDTs"
20022
20023 test_413b() {
20024         [ $MDSCOUNT -lt 2 ] &&
20025                 skip "We need at least 2 MDTs for this test"
20026
20027         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
20028                 skip "Need server version at least 2.12.52"
20029
20030         mkdir $DIR/$tdir || error "mkdir failed"
20031         $LFS setdirstripe -D -i -1 -H space $DIR/$tdir ||
20032                 error "setdirstripe failed"
20033
20034         local qos_prio_free
20035         local qos_threshold_rr
20036         local count
20037
20038         qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
20039         qos_prio_free=${qos_prio_free%%%}
20040         qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr | head -n1)
20041         qos_threshold_rr=${qos_threshold_rr%%%}
20042
20043         stack_trap "$LCTL set_param lmv.*.qos_prio_free=$qos_prio_free" EXIT
20044         stack_trap "$LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr" \
20045                 EXIT
20046
20047         echo "mkdir with roundrobin"
20048
20049         $LCTL set_param lmv.*.qos_threshold_rr=100
20050         for i in $(seq $((100 * MDSCOUNT))); do
20051                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20052         done
20053         for i in $(seq $MDSCOUNT); do
20054                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20055                         wc -w)
20056                 echo "$count directories created on MDT$((i - 1))"
20057                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
20058         done
20059
20060         rm -rf $DIR/$tdir/*
20061
20062         $LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr
20063
20064         local ffree
20065         local max
20066         local min
20067         local max_index
20068         local min_index
20069
20070         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree | uniq))
20071         echo "MDT filesfree available: ${ffree[@]}"
20072         max=${ffree[0]}
20073         min=${ffree[0]}
20074         max_index=0
20075         min_index=0
20076         for ((i = 0; i < ${#ffree[@]}; i++)); do
20077                 if [[ ${ffree[i]} -gt $max ]]; then
20078                         max=${ffree[i]}
20079                         max_index=$i
20080                 fi
20081                 if [[ ${ffree[i]} -lt $min ]]; then
20082                         min=${ffree[i]}
20083                         min_index=$i
20084                 fi
20085         done
20086         echo "Min free files: MDT$min_index: $min"
20087         echo "Max free files: MDT$max_index: $max"
20088
20089         [ $min -eq 0 ] && skip "no free files in MDT$min_index"
20090         [ $min -gt 10000000 ] && skip "too much free files in MDT$min_index"
20091
20092         # Check if we need to generate uneven MDTs
20093         test_mkdir -i $min_index -c 1 -p $DIR/$tdir-MDT$min_index
20094         local threshold=10
20095         local diff=$((max - min))
20096         local diff2=$((diff * 100 / min))
20097
20098         echo -n "Check for uneven MDTs: "
20099         echo -n "diff=$diff files ($diff2%) must be > $threshold% ..."
20100
20101         if [ $diff2 -gt $threshold ]; then
20102                 echo "ok"
20103                 echo "Don't need to fill MDT$min_index"
20104         else
20105                 # generate uneven MDTs, create till 25% diff
20106                 echo "no"
20107                 diff2=$((threshold - diff2))
20108                 diff=$((min * diff2 / 100))
20109                 # 50 sec per 10000 files in vm
20110                 [ $diff -gt 40000 ] && [ "$SLOW" = "no" ] &&
20111                         skip "$diff files to create"
20112                 echo "Fill $diff2% diff in MDT$min_index with $diff files"
20113                 local i
20114                 local value="$(generate_string 1024)"
20115                 for i in $(seq $diff); do
20116                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
20117                                 $DIR/$tdir-MDT$min_index/f$i > /dev/null ||
20118                                 error "create f$i failed"
20119                         setfattr -n user.413b -v $value \
20120                                 $DIR/$tdir-MDT$min_index/f$i ||
20121                                 error "setfattr f$i failed"
20122                 done
20123         fi
20124
20125         min=$((100 *MDSCOUNT))
20126         max=0
20127
20128         echo "mkdir with balanced space usage"
20129         $LCTL set_param lmv.*.qos_prio_free=100
20130         for i in $(seq $((100 * MDSCOUNT))); do
20131                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20132         done
20133         for i in $(seq $MDSCOUNT); do
20134                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20135                         wc -w)
20136                 echo "$count directories created on MDT$((i - 1))"
20137                 [ $min -gt $count ] && min=$count
20138                 [ $max -lt $count ] && max=$count
20139         done
20140         [ $((max - min)) -gt $MDSCOUNT ] ||
20141                 error "subdirs shouldn't be evenly distributed"
20142
20143         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20144
20145         $LFS setdirstripe -D -d $DIR/$tdir || error "setdirstripe -d failed"
20146         getfattr -n trusted.dmv $DIR/$tdir && error "default dir layout exists"
20147         true
20148 }
20149 run_test 413b "mkdir with balanced space usage"
20150
20151 test_414() {
20152 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
20153         $LCTL set_param fail_loc=0x80000521
20154         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
20155         rm -f $DIR/$tfile
20156 }
20157 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
20158
20159 test_415() {
20160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20161         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
20162                 skip "Need server version at least 2.11.52"
20163
20164         # LU-11102
20165         local total
20166         local setattr_pid
20167         local start_time
20168         local end_time
20169         local duration
20170
20171         total=500
20172         # this test may be slow on ZFS
20173         [ "$mds1_FSTYPE" == "zfs" ] && total=100
20174
20175         # though this test is designed for striped directory, let's test normal
20176         # directory too since lock is always saved as CoS lock.
20177         test_mkdir $DIR/$tdir || error "mkdir $tdir"
20178         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
20179
20180         (
20181                 while true; do
20182                         touch $DIR/$tdir
20183                 done
20184         ) &
20185         setattr_pid=$!
20186
20187         start_time=$(date +%s)
20188         for i in $(seq $total); do
20189                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
20190                         > /dev/null
20191         done
20192         end_time=$(date +%s)
20193         duration=$((end_time - start_time))
20194
20195         kill -9 $setattr_pid
20196
20197         echo "rename $total files took $duration sec"
20198         [ $duration -lt 100 ] || error "rename took $duration sec"
20199 }
20200 run_test 415 "lock revoke is not missing"
20201
20202 test_416() {
20203         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
20204                 skip "Need server version at least 2.11.55"
20205
20206         # define OBD_FAIL_OSD_TXN_START    0x19a
20207         do_facet mds1 lctl set_param fail_loc=0x19a
20208
20209         lfs mkdir -c $MDSCOUNT $DIR/$tdir
20210
20211         true
20212 }
20213 run_test 416 "transaction start failure won't cause system hung"
20214
20215 cleanup_417() {
20216         trap 0
20217         do_nodes $(comma_list $(mdts_nodes)) \
20218                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
20219         do_nodes $(comma_list $(mdts_nodes)) \
20220                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
20221         do_nodes $(comma_list $(mdts_nodes)) \
20222                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
20223 }
20224
20225 test_417() {
20226         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20227         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
20228                 skip "Need MDS version at least 2.11.56"
20229
20230         trap cleanup_417 RETURN EXIT
20231
20232         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
20233         do_nodes $(comma_list $(mdts_nodes)) \
20234                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
20235         $LFS migrate -m 0 $DIR/$tdir.1 &&
20236                 error "migrate dir $tdir.1 should fail"
20237
20238         do_nodes $(comma_list $(mdts_nodes)) \
20239                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
20240         $LFS mkdir -i 1 $DIR/$tdir.2 &&
20241                 error "create remote dir $tdir.2 should fail"
20242
20243         do_nodes $(comma_list $(mdts_nodes)) \
20244                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
20245         $LFS mkdir -c 2 $DIR/$tdir.3 &&
20246                 error "create striped dir $tdir.3 should fail"
20247         true
20248 }
20249 run_test 417 "disable remote dir, striped dir and dir migration"
20250
20251 # Checks that the outputs of df [-i] and lfs df [-i] match
20252 #
20253 # usage: check_lfs_df <blocks | inodes> <mountpoint>
20254 check_lfs_df() {
20255         local dir=$2
20256         local inodes
20257         local df_out
20258         local lfs_df_out
20259         local count
20260         local passed=false
20261
20262         # blocks or inodes
20263         [ "$1" == "blocks" ] && inodes= || inodes="-i"
20264
20265         for count in {1..100}; do
20266                 cancel_lru_locks
20267                 sync; sleep 0.2
20268
20269                 # read the lines of interest
20270                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
20271                         error "df $inodes $dir | tail -n +2 failed"
20272                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
20273                         error "lfs df $inodes $dir | grep summary: failed"
20274
20275                 # skip first substrings of each output as they are different
20276                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
20277                 # compare the two outputs
20278                 passed=true
20279                 for i in {1..5}; do
20280                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
20281                 done
20282                 $passed && break
20283         done
20284
20285         if ! $passed; then
20286                 df -P $inodes $dir
20287                 echo
20288                 lfs df $inodes $dir
20289                 error "df and lfs df $1 output mismatch: "      \
20290                       "df ${inodes}: ${df_out[*]}, "            \
20291                       "lfs df ${inodes}: ${lfs_df_out[*]}"
20292         fi
20293 }
20294
20295 test_418() {
20296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20297
20298         local dir=$DIR/$tdir
20299         local numfiles=$((RANDOM % 4096 + 2))
20300         local numblocks=$((RANDOM % 256 + 1))
20301
20302         wait_delete_completed
20303         test_mkdir $dir
20304
20305         # check block output
20306         check_lfs_df blocks $dir
20307         # check inode output
20308         check_lfs_df inodes $dir
20309
20310         # create a single file and retest
20311         echo "Creating a single file and testing"
20312         createmany -o $dir/$tfile- 1 &>/dev/null ||
20313                 error "creating 1 file in $dir failed"
20314         check_lfs_df blocks $dir
20315         check_lfs_df inodes $dir
20316
20317         # create a random number of files
20318         echo "Creating $((numfiles - 1)) files and testing"
20319         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
20320                 error "creating $((numfiles - 1)) files in $dir failed"
20321
20322         # write a random number of blocks to the first test file
20323         echo "Writing $numblocks 4K blocks and testing"
20324         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
20325                 count=$numblocks &>/dev/null ||
20326                 error "dd to $dir/${tfile}-0 failed"
20327
20328         # retest
20329         check_lfs_df blocks $dir
20330         check_lfs_df inodes $dir
20331
20332         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
20333                 error "unlinking $numfiles files in $dir failed"
20334 }
20335 run_test 418 "df and lfs df outputs match"
20336
20337 test_419()
20338 {
20339         local dir=$DIR/$tdir
20340
20341         mkdir -p $dir
20342         touch $dir/file
20343
20344         cancel_lru_locks mdc
20345
20346         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
20347         $LCTL set_param fail_loc=0x1410
20348         cat $dir/file
20349         $LCTL set_param fail_loc=0
20350         rm -rf $dir
20351 }
20352 run_test 419 "Verify open file by name doesn't crash kernel"
20353
20354 test_420()
20355 {
20356         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
20357                 skip "Need MDS version at least 2.12.53"
20358
20359         local SAVE_UMASK=$(umask)
20360         local dir=$DIR/$tdir
20361         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
20362
20363         mkdir -p $dir
20364         umask 0000
20365         mkdir -m03777 $dir/testdir
20366         ls -dn $dir/testdir
20367         # Need to remove trailing '.' when SELinux is enabled
20368         local dirperms=$(ls -dn $dir/testdir |
20369                          awk '{ sub(/\.$/, "", $1); print $1}')
20370         [ $dirperms == "drwxrwsrwt" ] ||
20371                 error "incorrect perms on $dir/testdir"
20372
20373         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
20374                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
20375         ls -n $dir/testdir/testfile
20376         local fileperms=$(ls -n $dir/testdir/testfile |
20377                           awk '{ sub(/\.$/, "", $1); print $1}')
20378         [ $fileperms == "-rwxr-xr-x" ] ||
20379                 error "incorrect perms on $dir/testdir/testfile"
20380
20381         umask $SAVE_UMASK
20382 }
20383 run_test 420 "clear SGID bit on non-directories for non-members"
20384
20385 prep_801() {
20386         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
20387         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
20388                 skip "Need server version at least 2.9.55"
20389
20390         start_full_debug_logging
20391 }
20392
20393 post_801() {
20394         stop_full_debug_logging
20395 }
20396
20397 barrier_stat() {
20398         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
20399                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
20400                            awk '/The barrier for/ { print $7 }')
20401                 echo $st
20402         else
20403                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
20404                 echo \'$st\'
20405         fi
20406 }
20407
20408 barrier_expired() {
20409         local expired
20410
20411         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
20412                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
20413                           awk '/will be expired/ { print $7 }')
20414         else
20415                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
20416         fi
20417
20418         echo $expired
20419 }
20420
20421 test_801a() {
20422         prep_801
20423
20424         echo "Start barrier_freeze at: $(date)"
20425         #define OBD_FAIL_BARRIER_DELAY          0x2202
20426         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
20427         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
20428
20429         sleep 2
20430         local b_status=$(barrier_stat)
20431         echo "Got barrier status at: $(date)"
20432         [ "$b_status" = "'freezing_p1'" ] ||
20433                 error "(1) unexpected barrier status $b_status"
20434
20435         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
20436         wait
20437         b_status=$(barrier_stat)
20438         [ "$b_status" = "'frozen'" ] ||
20439                 error "(2) unexpected barrier status $b_status"
20440
20441         local expired=$(barrier_expired)
20442         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
20443         sleep $((expired + 3))
20444
20445         b_status=$(barrier_stat)
20446         [ "$b_status" = "'expired'" ] ||
20447                 error "(3) unexpected barrier status $b_status"
20448
20449         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
20450                 error "(4) fail to freeze barrier"
20451
20452         b_status=$(barrier_stat)
20453         [ "$b_status" = "'frozen'" ] ||
20454                 error "(5) unexpected barrier status $b_status"
20455
20456         echo "Start barrier_thaw at: $(date)"
20457         #define OBD_FAIL_BARRIER_DELAY          0x2202
20458         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
20459         do_facet mgs $LCTL barrier_thaw $FSNAME &
20460
20461         sleep 2
20462         b_status=$(barrier_stat)
20463         echo "Got barrier status at: $(date)"
20464         [ "$b_status" = "'thawing'" ] ||
20465                 error "(6) unexpected barrier status $b_status"
20466
20467         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
20468         wait
20469         b_status=$(barrier_stat)
20470         [ "$b_status" = "'thawed'" ] ||
20471                 error "(7) unexpected barrier status $b_status"
20472
20473         #define OBD_FAIL_BARRIER_FAILURE        0x2203
20474         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
20475         do_facet mgs $LCTL barrier_freeze $FSNAME
20476
20477         b_status=$(barrier_stat)
20478         [ "$b_status" = "'failed'" ] ||
20479                 error "(8) unexpected barrier status $b_status"
20480
20481         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20482         do_facet mgs $LCTL barrier_thaw $FSNAME
20483
20484         post_801
20485 }
20486 run_test 801a "write barrier user interfaces and stat machine"
20487
20488 test_801b() {
20489         prep_801
20490
20491         mkdir $DIR/$tdir || error "(1) fail to mkdir"
20492         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
20493         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
20494         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
20495         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
20496
20497         cancel_lru_locks mdc
20498
20499         # 180 seconds should be long enough
20500         do_facet mgs $LCTL barrier_freeze $FSNAME 180
20501
20502         local b_status=$(barrier_stat)
20503         [ "$b_status" = "'frozen'" ] ||
20504                 error "(6) unexpected barrier status $b_status"
20505
20506         mkdir $DIR/$tdir/d0/d10 &
20507         mkdir_pid=$!
20508
20509         touch $DIR/$tdir/d1/f13 &
20510         touch_pid=$!
20511
20512         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
20513         ln_pid=$!
20514
20515         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
20516         mv_pid=$!
20517
20518         rm -f $DIR/$tdir/d4/f12 &
20519         rm_pid=$!
20520
20521         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
20522
20523         # To guarantee taht the 'stat' is not blocked
20524         b_status=$(barrier_stat)
20525         [ "$b_status" = "'frozen'" ] ||
20526                 error "(8) unexpected barrier status $b_status"
20527
20528         # let above commands to run at background
20529         sleep 5
20530
20531         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
20532         ps -p $touch_pid || error "(10) touch should be blocked"
20533         ps -p $ln_pid || error "(11) link should be blocked"
20534         ps -p $mv_pid || error "(12) rename should be blocked"
20535         ps -p $rm_pid || error "(13) unlink should be blocked"
20536
20537         b_status=$(barrier_stat)
20538         [ "$b_status" = "'frozen'" ] ||
20539                 error "(14) unexpected barrier status $b_status"
20540
20541         do_facet mgs $LCTL barrier_thaw $FSNAME
20542         b_status=$(barrier_stat)
20543         [ "$b_status" = "'thawed'" ] ||
20544                 error "(15) unexpected barrier status $b_status"
20545
20546         wait $mkdir_pid || error "(16) mkdir should succeed"
20547         wait $touch_pid || error "(17) touch should succeed"
20548         wait $ln_pid || error "(18) link should succeed"
20549         wait $mv_pid || error "(19) rename should succeed"
20550         wait $rm_pid || error "(20) unlink should succeed"
20551
20552         post_801
20553 }
20554 run_test 801b "modification will be blocked by write barrier"
20555
20556 test_801c() {
20557         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20558
20559         prep_801
20560
20561         stop mds2 || error "(1) Fail to stop mds2"
20562
20563         do_facet mgs $LCTL barrier_freeze $FSNAME 30
20564
20565         local b_status=$(barrier_stat)
20566         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
20567                 do_facet mgs $LCTL barrier_thaw $FSNAME
20568                 error "(2) unexpected barrier status $b_status"
20569         }
20570
20571         do_facet mgs $LCTL barrier_rescan $FSNAME ||
20572                 error "(3) Fail to rescan barrier bitmap"
20573
20574         do_facet mgs $LCTL barrier_freeze $FSNAME 10
20575
20576         b_status=$(barrier_stat)
20577         [ "$b_status" = "'frozen'" ] ||
20578                 error "(4) unexpected barrier status $b_status"
20579
20580         do_facet mgs $LCTL barrier_thaw $FSNAME
20581         b_status=$(barrier_stat)
20582         [ "$b_status" = "'thawed'" ] ||
20583                 error "(5) unexpected barrier status $b_status"
20584
20585         local devname=$(mdsdevname 2)
20586
20587         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
20588
20589         do_facet mgs $LCTL barrier_rescan $FSNAME ||
20590                 error "(7) Fail to rescan barrier bitmap"
20591
20592         post_801
20593 }
20594 run_test 801c "rescan barrier bitmap"
20595
20596 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
20597 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
20598 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
20599
20600 cleanup_802a() {
20601         trap 0
20602
20603         stopall
20604         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
20605         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
20606         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
20607         setupall
20608 }
20609
20610 test_802a() {
20611
20612         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
20613         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
20614                 skip "Need server version at least 2.9.55"
20615
20616         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
20617
20618         mkdir $DIR/$tdir || error "(1) fail to mkdir"
20619
20620         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
20621                 error "(2) Fail to copy"
20622
20623         trap cleanup_802a EXIT
20624
20625         # sync by force before remount as readonly
20626         sync; sync_all_data; sleep 3; sync_all_data
20627
20628         stopall
20629
20630         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
20631         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
20632         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
20633
20634         echo "Mount the server as read only"
20635         setupall server_only || error "(3) Fail to start servers"
20636
20637         echo "Mount client without ro should fail"
20638         mount_client $MOUNT &&
20639                 error "(4) Mount client without 'ro' should fail"
20640
20641         echo "Mount client with ro should succeed"
20642         mount_client $MOUNT ro ||
20643                 error "(5) Mount client with 'ro' should succeed"
20644
20645         echo "Modify should be refused"
20646         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20647
20648         echo "Read should be allowed"
20649         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20650                 error "(7) Read should succeed under ro mode"
20651
20652         cleanup_802a
20653 }
20654 run_test 802a "simulate readonly device"
20655
20656 test_802b() {
20657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20658         remote_mds_nodsh && skip "remote MDS with nodsh"
20659
20660         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
20661                 skip "readonly option not available"
20662
20663         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
20664
20665         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
20666                 error "(2) Fail to copy"
20667
20668         # write back all cached data before setting MDT to readonly
20669         cancel_lru_locks
20670         sync_all_data
20671
20672         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
20673         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
20674
20675         echo "Modify should be refused"
20676         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20677
20678         echo "Read should be allowed"
20679         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20680                 error "(7) Read should succeed under ro mode"
20681
20682         # disable readonly
20683         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
20684 }
20685 run_test 802b "be able to set MDTs to readonly"
20686
20687 test_803() {
20688         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20689         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20690                 skip "MDS needs to be newer than 2.10.54"
20691
20692         mkdir -p $DIR/$tdir
20693         # Create some objects on all MDTs to trigger related logs objects
20694         for idx in $(seq $MDSCOUNT); do
20695                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
20696                         $DIR/$tdir/dir${idx} ||
20697                         error "Fail to create $DIR/$tdir/dir${idx}"
20698         done
20699
20700         sync; sleep 3
20701         wait_delete_completed # ensure old test cleanups are finished
20702         echo "before create:"
20703         $LFS df -i $MOUNT
20704         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20705
20706         for i in {1..10}; do
20707                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
20708                         error "Fail to create $DIR/$tdir/foo$i"
20709         done
20710
20711         sync; sleep 3
20712         echo "after create:"
20713         $LFS df -i $MOUNT
20714         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20715
20716         # allow for an llog to be cleaned up during the test
20717         [ $after_used -ge $((before_used + 10 - 1)) ] ||
20718                 error "before ($before_used) + 10 > after ($after_used)"
20719
20720         for i in {1..10}; do
20721                 rm -rf $DIR/$tdir/foo$i ||
20722                         error "Fail to remove $DIR/$tdir/foo$i"
20723         done
20724
20725         sleep 3 # avoid MDT return cached statfs
20726         wait_delete_completed
20727         echo "after unlink:"
20728         $LFS df -i $MOUNT
20729         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20730
20731         # allow for an llog to be created during the test
20732         [ $after_used -le $((before_used + 1)) ] ||
20733                 error "after ($after_used) > before ($before_used) + 1"
20734 }
20735 run_test 803 "verify agent object for remote object"
20736
20737 test_804() {
20738         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20739         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20740                 skip "MDS needs to be newer than 2.10.54"
20741         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20742
20743         mkdir -p $DIR/$tdir
20744         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
20745                 error "Fail to create $DIR/$tdir/dir0"
20746
20747         local fid=$($LFS path2fid $DIR/$tdir/dir0)
20748         local dev=$(mdsdevname 2)
20749
20750         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20751                 grep ${fid} || error "NOT found agent entry for dir0"
20752
20753         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
20754                 error "Fail to create $DIR/$tdir/dir1"
20755
20756         touch $DIR/$tdir/dir1/foo0 ||
20757                 error "Fail to create $DIR/$tdir/dir1/foo0"
20758         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
20759         local rc=0
20760
20761         for idx in $(seq $MDSCOUNT); do
20762                 dev=$(mdsdevname $idx)
20763                 do_facet mds${idx} \
20764                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20765                         grep ${fid} && rc=$idx
20766         done
20767
20768         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
20769                 error "Fail to rename foo0 to foo1"
20770         if [ $rc -eq 0 ]; then
20771                 for idx in $(seq $MDSCOUNT); do
20772                         dev=$(mdsdevname $idx)
20773                         do_facet mds${idx} \
20774                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20775                         grep ${fid} && rc=$idx
20776                 done
20777         fi
20778
20779         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
20780                 error "Fail to rename foo1 to foo2"
20781         if [ $rc -eq 0 ]; then
20782                 for idx in $(seq $MDSCOUNT); do
20783                         dev=$(mdsdevname $idx)
20784                         do_facet mds${idx} \
20785                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20786                         grep ${fid} && rc=$idx
20787                 done
20788         fi
20789
20790         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
20791
20792         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
20793                 error "Fail to link to $DIR/$tdir/dir1/foo2"
20794         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
20795                 error "Fail to rename foo2 to foo0"
20796         unlink $DIR/$tdir/dir1/foo0 ||
20797                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
20798         rm -rf $DIR/$tdir/dir0 ||
20799                 error "Fail to rm $DIR/$tdir/dir0"
20800
20801         for idx in $(seq $MDSCOUNT); do
20802                 dev=$(mdsdevname $idx)
20803                 rc=0
20804
20805                 stop mds${idx}
20806                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
20807                         rc=$?
20808                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
20809                         error "mount mds$idx failed"
20810                 df $MOUNT > /dev/null 2>&1
20811
20812                 # e2fsck should not return error
20813                 [ $rc -eq 0 ] ||
20814                         error "e2fsck detected error on MDT${idx}: rc=$rc"
20815         done
20816 }
20817 run_test 804 "verify agent entry for remote entry"
20818
20819 cleanup_805() {
20820         do_facet $SINGLEMDS zfs set quota=$old $fsset
20821         unlinkmany $DIR/$tdir/f- 1000000
20822         trap 0
20823 }
20824
20825 test_805() {
20826         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
20827         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
20828         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
20829                 skip "netfree not implemented before 0.7"
20830         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
20831                 skip "Need MDS version at least 2.10.57"
20832
20833         local fsset
20834         local freekb
20835         local usedkb
20836         local old
20837         local quota
20838         local pref="osd-zfs.lustre-MDT0000."
20839
20840         # limit available space on MDS dataset to meet nospace issue
20841         # quickly. then ZFS 0.7.2 can use reserved space if asked
20842         # properly (using netfree flag in osd_declare_destroy()
20843         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
20844         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
20845                 gawk '{print $3}')
20846         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
20847         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
20848         let "usedkb=usedkb-freekb"
20849         let "freekb=freekb/2"
20850         if let "freekb > 5000"; then
20851                 let "freekb=5000"
20852         fi
20853         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
20854         trap cleanup_805 EXIT
20855         mkdir $DIR/$tdir
20856         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
20857         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
20858         rm -rf $DIR/$tdir || error "not able to remove"
20859         do_facet $SINGLEMDS zfs set quota=$old $fsset
20860         trap 0
20861 }
20862 run_test 805 "ZFS can remove from full fs"
20863
20864 # Size-on-MDS test
20865 check_lsom_data()
20866 {
20867         local file=$1
20868         local size=$($LFS getsom -s $file)
20869         local expect=$(stat -c %s $file)
20870
20871         [[ $size == $expect ]] ||
20872                 error "$file expected size: $expect, got: $size"
20873
20874         local blocks=$($LFS getsom -b $file)
20875         expect=$(stat -c %b $file)
20876         [[ $blocks == $expect ]] ||
20877                 error "$file expected blocks: $expect, got: $blocks"
20878 }
20879
20880 check_lsom_size()
20881 {
20882         local size=$($LFS getsom -s $1)
20883         local expect=$2
20884
20885         [[ $size == $expect ]] ||
20886                 error "$file expected size: $expect, got: $size"
20887 }
20888
20889 test_806() {
20890         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20891                 skip "Need MDS version at least 2.11.52"
20892
20893         local bs=1048576
20894
20895         touch $DIR/$tfile || error "touch $tfile failed"
20896
20897         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20898         save_lustre_params client "llite.*.xattr_cache" > $save
20899         lctl set_param llite.*.xattr_cache=0
20900         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20901
20902         # single-threaded write
20903         echo "Test SOM for single-threaded write"
20904         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
20905                 error "write $tfile failed"
20906         check_lsom_size $DIR/$tfile $bs
20907
20908         local num=32
20909         local size=$(($num * $bs))
20910         local offset=0
20911         local i
20912
20913         echo "Test SOM for single client multi-threaded($num) write"
20914         $TRUNCATE $DIR/$tfile 0
20915         for ((i = 0; i < $num; i++)); do
20916                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20917                 local pids[$i]=$!
20918                 offset=$((offset + $bs))
20919         done
20920         for (( i=0; i < $num; i++ )); do
20921                 wait ${pids[$i]}
20922         done
20923         check_lsom_size $DIR/$tfile $size
20924
20925         $TRUNCATE $DIR/$tfile 0
20926         for ((i = 0; i < $num; i++)); do
20927                 offset=$((offset - $bs))
20928                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20929                 local pids[$i]=$!
20930         done
20931         for (( i=0; i < $num; i++ )); do
20932                 wait ${pids[$i]}
20933         done
20934         check_lsom_size $DIR/$tfile $size
20935
20936         # multi-client wirtes
20937         num=$(get_node_count ${CLIENTS//,/ })
20938         size=$(($num * $bs))
20939         offset=0
20940         i=0
20941
20942         echo "Test SOM for multi-client ($num) writes"
20943         $TRUNCATE $DIR/$tfile 0
20944         for client in ${CLIENTS//,/ }; do
20945                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20946                 local pids[$i]=$!
20947                 i=$((i + 1))
20948                 offset=$((offset + $bs))
20949         done
20950         for (( i=0; i < $num; i++ )); do
20951                 wait ${pids[$i]}
20952         done
20953         check_lsom_size $DIR/$tfile $offset
20954
20955         i=0
20956         $TRUNCATE $DIR/$tfile 0
20957         for client in ${CLIENTS//,/ }; do
20958                 offset=$((offset - $bs))
20959                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20960                 local pids[$i]=$!
20961                 i=$((i + 1))
20962         done
20963         for (( i=0; i < $num; i++ )); do
20964                 wait ${pids[$i]}
20965         done
20966         check_lsom_size $DIR/$tfile $size
20967
20968         # verify truncate
20969         echo "Test SOM for truncate"
20970         $TRUNCATE $DIR/$tfile 1048576
20971         check_lsom_size $DIR/$tfile 1048576
20972         $TRUNCATE $DIR/$tfile 1234
20973         check_lsom_size $DIR/$tfile 1234
20974
20975         # verify SOM blocks count
20976         echo "Verify SOM block count"
20977         $TRUNCATE $DIR/$tfile 0
20978         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
20979                 error "failed to write file $tfile"
20980         check_lsom_data $DIR/$tfile
20981 }
20982 run_test 806 "Verify Lazy Size on MDS"
20983
20984 test_807() {
20985         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20986         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20987                 skip "Need MDS version at least 2.11.52"
20988
20989         # Registration step
20990         changelog_register || error "changelog_register failed"
20991         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
20992         changelog_users $SINGLEMDS | grep -q $cl_user ||
20993                 error "User $cl_user not found in changelog_users"
20994
20995         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20996         save_lustre_params client "llite.*.xattr_cache" > $save
20997         lctl set_param llite.*.xattr_cache=0
20998         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20999
21000         rm -rf $DIR/$tdir || error "rm $tdir failed"
21001         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21002         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
21003         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
21004         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
21005                 error "truncate $tdir/trunc failed"
21006
21007         local bs=1048576
21008         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
21009                 error "write $tfile failed"
21010
21011         # multi-client wirtes
21012         local num=$(get_node_count ${CLIENTS//,/ })
21013         local offset=0
21014         local i=0
21015
21016         echo "Test SOM for multi-client ($num) writes"
21017         touch $DIR/$tfile || error "touch $tfile failed"
21018         $TRUNCATE $DIR/$tfile 0
21019         for client in ${CLIENTS//,/ }; do
21020                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21021                 local pids[$i]=$!
21022                 i=$((i + 1))
21023                 offset=$((offset + $bs))
21024         done
21025         for (( i=0; i < $num; i++ )); do
21026                 wait ${pids[$i]}
21027         done
21028
21029         sleep 5
21030         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
21031         check_lsom_data $DIR/$tdir/trunc
21032         check_lsom_data $DIR/$tdir/single_dd
21033         check_lsom_data $DIR/$tfile
21034
21035         rm -rf $DIR/$tdir
21036         # Deregistration step
21037         changelog_deregister || error "changelog_deregister failed"
21038 }
21039 run_test 807 "verify LSOM syncing tool"
21040
21041 check_som_nologged()
21042 {
21043         local lines=$($LFS changelog $FSNAME-MDT0000 |
21044                 grep 'x=trusted.som' | wc -l)
21045         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
21046 }
21047
21048 test_808() {
21049         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
21050                 skip "Need MDS version at least 2.11.55"
21051
21052         # Registration step
21053         changelog_register || error "changelog_register failed"
21054
21055         touch $DIR/$tfile || error "touch $tfile failed"
21056         check_som_nologged
21057
21058         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
21059                 error "write $tfile failed"
21060         check_som_nologged
21061
21062         $TRUNCATE $DIR/$tfile 1234
21063         check_som_nologged
21064
21065         $TRUNCATE $DIR/$tfile 1048576
21066         check_som_nologged
21067
21068         # Deregistration step
21069         changelog_deregister || error "changelog_deregister failed"
21070 }
21071 run_test 808 "Check trusted.som xattr not logged in Changelogs"
21072
21073 check_som_nodata()
21074 {
21075         $LFS getsom $1
21076         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
21077 }
21078
21079 test_809() {
21080         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21081                 skip "Need MDS version at least 2.11.56"
21082
21083         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
21084                 error "failed to create DoM-only file $DIR/$tfile"
21085         touch $DIR/$tfile || error "touch $tfile failed"
21086         check_som_nodata $DIR/$tfile
21087
21088         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
21089                 error "write $tfile failed"
21090         check_som_nodata $DIR/$tfile
21091
21092         $TRUNCATE $DIR/$tfile 1234
21093         check_som_nodata $DIR/$tfile
21094
21095         $TRUNCATE $DIR/$tfile 4097
21096         check_som_nodata $DIR/$file
21097 }
21098 run_test 809 "Verify no SOM xattr store for DoM-only files"
21099
21100 test_810() {
21101         local ORIG
21102         local CSUM
21103
21104         # t10 seem to dislike partial pages
21105         lctl set_param osc.*.checksum_type=adler
21106         lctl set_param fail_loc=0x411
21107         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
21108         ORIG=$(md5sum $DIR/$tfile)
21109         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
21110         CSUM=$(md5sum $DIR/$tfile)
21111         set_checksum_type adler
21112         if [ "$ORIG" != "$CSUM" ]; then
21113                 error "$ORIG != $CSUM"
21114         fi
21115 }
21116 run_test 810 "partial page writes on ZFS (LU-11663)"
21117
21118 test_811() {
21119         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
21120                 skip "Need MDS version at least 2.11.56"
21121
21122         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
21123         do_facet mds1 $LCTL set_param fail_loc=0x165
21124         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
21125
21126         stop mds1
21127         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21128
21129         sleep 5
21130         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
21131                 error "MDD orphan cleanup thread not quit"
21132 }
21133 run_test 811 "orphan name stub can be cleaned up in startup"
21134
21135 test_812() {
21136         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
21137                 skip "OST < 2.12.51 doesn't support this fail_loc"
21138         [ "$SHARED_KEY" = true ] &&
21139                 skip "OSC connections never go IDLE with Shared-Keys enabled"
21140
21141         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21142         # ensure ost1 is connected
21143         stat $DIR/$tfile >/dev/null || error "can't stat"
21144         wait_osc_import_state client ost1 FULL
21145         # no locks, no reqs to let the connection idle
21146         cancel_lru_locks osc
21147
21148         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
21149 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
21150         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
21151         wait_osc_import_state client ost1 CONNECTING
21152         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
21153
21154         stat $DIR/$tfile >/dev/null || error "can't stat file"
21155 }
21156 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
21157
21158 test_813() {
21159         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
21160         [ -z "$file_heat_sav" ] && skip "no file heat support"
21161
21162         local readsample
21163         local writesample
21164         local readbyte
21165         local writebyte
21166         local readsample1
21167         local writesample1
21168         local readbyte1
21169         local writebyte1
21170
21171         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
21172         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
21173
21174         $LCTL set_param -n llite.*.file_heat=1
21175         echo "Turn on file heat"
21176         echo "Period second: $period_second, Decay percentage: $decay_pct"
21177
21178         echo "QQQQ" > $DIR/$tfile
21179         echo "QQQQ" > $DIR/$tfile
21180         echo "QQQQ" > $DIR/$tfile
21181         cat $DIR/$tfile > /dev/null
21182         cat $DIR/$tfile > /dev/null
21183         cat $DIR/$tfile > /dev/null
21184         cat $DIR/$tfile > /dev/null
21185
21186         local out=$($LFS heat_get $DIR/$tfile)
21187
21188         $LFS heat_get $DIR/$tfile
21189         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21190         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21191         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21192         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21193
21194         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
21195         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
21196         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
21197         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
21198
21199         sleep $((period_second + 3))
21200         echo "Sleep $((period_second + 3)) seconds..."
21201         # The recursion formula to calculate the heat of the file f is as
21202         # follow:
21203         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
21204         # Where Hi is the heat value in the period between time points i*I and
21205         # (i+1)*I; Ci is the access count in the period; the symbol P refers
21206         # to the weight of Ci.
21207         out=$($LFS heat_get $DIR/$tfile)
21208         $LFS heat_get $DIR/$tfile
21209         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21210         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21211         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21212         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21213
21214         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
21215                 error "read sample ($readsample) is wrong"
21216         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
21217                 error "write sample ($writesample) is wrong"
21218         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
21219                 error "read bytes ($readbyte) is wrong"
21220         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
21221                 error "write bytes ($writebyte) is wrong"
21222
21223         echo "QQQQ" > $DIR/$tfile
21224         echo "QQQQ" > $DIR/$tfile
21225         echo "QQQQ" > $DIR/$tfile
21226         cat $DIR/$tfile > /dev/null
21227         cat $DIR/$tfile > /dev/null
21228         cat $DIR/$tfile > /dev/null
21229         cat $DIR/$tfile > /dev/null
21230
21231         sleep $((period_second + 3))
21232         echo "Sleep $((period_second + 3)) seconds..."
21233
21234         out=$($LFS heat_get $DIR/$tfile)
21235         $LFS heat_get $DIR/$tfile
21236         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21237         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21238         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21239         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21240
21241         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
21242                 4 * $decay_pct) / 100") -eq 1 ] ||
21243                 error "read sample ($readsample1) is wrong"
21244         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
21245                 3 * $decay_pct) / 100") -eq 1 ] ||
21246                 error "write sample ($writesample1) is wrong"
21247         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
21248                 20 * $decay_pct) / 100") -eq 1 ] ||
21249                 error "read bytes ($readbyte1) is wrong"
21250         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
21251                 15 * $decay_pct) / 100") -eq 1 ] ||
21252                 error "write bytes ($writebyte1) is wrong"
21253
21254         echo "Turn off file heat for the file $DIR/$tfile"
21255         $LFS heat_set -o $DIR/$tfile
21256
21257         echo "QQQQ" > $DIR/$tfile
21258         echo "QQQQ" > $DIR/$tfile
21259         echo "QQQQ" > $DIR/$tfile
21260         cat $DIR/$tfile > /dev/null
21261         cat $DIR/$tfile > /dev/null
21262         cat $DIR/$tfile > /dev/null
21263         cat $DIR/$tfile > /dev/null
21264
21265         out=$($LFS heat_get $DIR/$tfile)
21266         $LFS heat_get $DIR/$tfile
21267         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21268         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21269         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21270         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21271
21272         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
21273         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
21274         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
21275         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
21276
21277         echo "Trun on file heat for the file $DIR/$tfile"
21278         $LFS heat_set -O $DIR/$tfile
21279
21280         echo "QQQQ" > $DIR/$tfile
21281         echo "QQQQ" > $DIR/$tfile
21282         echo "QQQQ" > $DIR/$tfile
21283         cat $DIR/$tfile > /dev/null
21284         cat $DIR/$tfile > /dev/null
21285         cat $DIR/$tfile > /dev/null
21286         cat $DIR/$tfile > /dev/null
21287
21288         out=$($LFS heat_get $DIR/$tfile)
21289         $LFS heat_get $DIR/$tfile
21290         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21291         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21292         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21293         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21294
21295         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
21296         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
21297         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
21298         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
21299
21300         $LFS heat_set -c $DIR/$tfile
21301         $LCTL set_param -n llite.*.file_heat=0
21302         echo "Turn off file heat support for the Lustre filesystem"
21303
21304         echo "QQQQ" > $DIR/$tfile
21305         echo "QQQQ" > $DIR/$tfile
21306         echo "QQQQ" > $DIR/$tfile
21307         cat $DIR/$tfile > /dev/null
21308         cat $DIR/$tfile > /dev/null
21309         cat $DIR/$tfile > /dev/null
21310         cat $DIR/$tfile > /dev/null
21311
21312         out=$($LFS heat_get $DIR/$tfile)
21313         $LFS heat_get $DIR/$tfile
21314         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21315         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21316         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21317         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21318
21319         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
21320         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
21321         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
21322         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
21323
21324         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
21325         rm -f $DIR/$tfile
21326 }
21327 run_test 813 "File heat verfication"
21328
21329 test_814()
21330 {
21331         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
21332         echo -n y >> $DIR/$tfile
21333         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
21334         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
21335 }
21336 run_test 814 "sparse cp works as expected (LU-12361)"
21337
21338 test_815()
21339 {
21340         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
21341         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
21342 }
21343 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
21344
21345 test_816() {
21346         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21347         # ensure ost1 is connected
21348         stat $DIR/$tfile >/dev/null || error "can't stat"
21349         wait_osc_import_state client ost1 FULL
21350         # no locks, no reqs to let the connection idle
21351         cancel_lru_locks osc
21352         lru_resize_disable osc
21353         local before
21354         local now
21355         before=$($LCTL get_param -n \
21356                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
21357
21358         wait_osc_import_state client ost1 IDLE
21359         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
21360         now=$($LCTL get_param -n \
21361               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
21362         [ $before == $now ] || error "lru_size changed $before != $now"
21363 }
21364 run_test 816 "do not reset lru_resize on idle reconnect"
21365
21366 #
21367 # tests that do cleanup/setup should be run at the end
21368 #
21369
21370 test_900() {
21371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21372         local ls
21373
21374         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
21375         $LCTL set_param fail_loc=0x903
21376
21377         cancel_lru_locks MGC
21378
21379         FAIL_ON_ERROR=true cleanup
21380         FAIL_ON_ERROR=true setup
21381 }
21382 run_test 900 "umount should not race with any mgc requeue thread"
21383
21384 complete $SECONDS
21385 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
21386 check_and_cleanup_lustre
21387 if [ "$I_MOUNTED" != "yes" ]; then
21388         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
21389 fi
21390 exit_status